parasite.object

Brief

Reference for the object submodule of the parasite package. This submodule contains the parasite.object.Object class, which is a generic container for a dictionary Python object.

Usage

from parasite import p

schema = p.obj({
   "name": p.string(),
   "age": p.number().integer().min(0),
}).strict()

schema.parse({
   "name": "John",
   "age": 30,
})  # -> {"name": "John", "age": 30 }
...

Member Reference

class parasite.object.K

Template type for the key in a dictionary.

alias of TypeVar(‘K’)

class parasite.object.Object(items: dict[Any, ParasiteType] | None = None)[source]

parasite type for creating and parsing dictionary based schemas. Will return a python dict[Any, Any] with the parsed values on success.

Note

Please use p.obj(...) instead of instantiating this class directly. p can be imported with:

from parasite import p

schema = p.obj({...})
...

Note

Calling the constructor with a dictionary of keys and their respective schemas will create a new schema. This is equivalent to calling add_item() for each key and schema. If no or an empty dictionary is passed, the schema will accept any kind of dictionary.

Inheritance:

Inheritance diagram of parasite.object.Object

Parameters:

items (dict[K, ParasiteType]) – The schema of subitems of the dictionary. Default: {}.

Example usage:

You can create a dictionary schema by passing a dictionary of keys and their respective schemas. The following example shows how to create a schema for a dictionary with a the keys “name”,”age”:

from parasite import p

schema = p.obj({
    "name": p.string(),
    "age": p.number().integer().optional(),
})
schema2 = p.obj()

The resulting schemas will parse the following objects:

>>> schema.parse({ "name": "John" })
{ "name": "John" }
>>> schema.parse({ })
ValidationError: key "name" not found, but is required

>>> schema2.parse({ })
{ }
>>> schema2.parse({ "name": "John" })
{ "name": "John" }
optional() Object[source]

Makes the value optional, when parsing with _find_and_parse(). Has no effect on parse(). Inverse of required().

Warning

This function has no effect if the value is parsed as a standalone value.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schemas:

from parasite import p

schema = p.obj({ "sub": p.obj().optional() })
schema2 = p.obj({ "sub": p.obj() })

The resulting schemas will parse the following objects:

>>> schema.parse({ "sub": { } })
{ "sub": { } }
>>> schema.parse({ })
{ }

>>> schema2.parse({ "sub": { } })
{ "sub": { } }
>>> schema2.parse({ })
ValidationError: key "sub" not found, but is required
required() Object[source]

Makes the value required, when parsing with _find_and_parse(). Has no effect on parse(). Inverse of optional(). Default behavior.

Note

This function is default behavior for the class and therefore only has an effect if the function optional() may have been called before.

Warning

This function has no effect if the value is parsed as a standalone value.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schemas:

from parasite import p

schema = p.obj({ "sub": p.obj().optional().required() })
schema2 = p.obj({ "sub": p.obj() })

The resulting schemas will parse the following objects:

>>> schema.parse({ "sub": { } })
{ "sub": { } }
>>> schema.parse({ })
ValidationError: key "sub" not found, but is required

>>> schema2.parse({ "sub": { } })
{ "sub": { } }
>>> schema2.parse({ })
ValidationError: key "sub" not found, but is required
nullable() Object[source]

Makes the value nullable, when parsing with _find_and_parse(). Has no effect on parse(). Inverse of not_nullable().

Warning

This function has no effect if the value is parsed as a standalone value.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schemas:

from parasite import p

schema = p.obj({ "sub": p.obj().nullable() })
schema2 = p.obj({ "sub": p.obj() })

The resulting schemas will parse the following objects:

>>> schema.parse({ "sub": { } })
{ "sub": { } }
>>> schema.parse({ "sub": None })
{ "sub": None }

>>> schema2.parse({ "sub": { } })
{ "sub": { } }
>>> schema2.parse({ "sub": None })
ValidationError: key "sub" is not nullable, but is None
not_nullable() Object[source]

Makes the value not-nullable, when parsing with _find_and_parse(). Has no effect on parse(). Inverse of nullable(). Default behavior.

Note

This function is default behavior for the class and therefore only has an effect if the function nullable() may have been called before.

Warning

This function has no effect if the value is parsed as a standalone value.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schemas:

from parasite import p

schema = p.obj({ "sub": p.obj().nullable().not_nullable() })
schema2 = p.obj({ "sub": p.obj() })

The resulting schemas will parse the following objects:

>>> schema.parse({ "sub": { } })
{ "sub": { } }
>>> schema.parse({ "sub": None })
ValidationError: key "sub" is not nullable, but is None

>>> schema2.parse({ "sub": { } })
{ "sub": { } }
>>> schema2.parse({ "sub": None })
ValidationError: key "sub" is not nullable, but is None
strict() Object[source]

Set the dictionary to be strict. This function ensures that only the keys in the schema are allowed in the dictionary. If this function is used strip() has no effect.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schemas:

from parasite import p

schema = p.obj({ "name": p.string() }).strict()
schema2 = p.obj({ "name": p.string() })

The resulting schemas will parse the following objects:

>>> schema.parse({ "name": "John" })
{ "name": "John" }
>>> schema.parse({ "name": "John", "age": 20 })
ValidationError: object has the key "age", but is not allowed to

>>> schema2.parse({ "name": "John" })
{ "name": "John" }
>>> schema2.parse({ "name": "John", "age": 20 })
{ "name": "John", "age": 20 }
strip() Object[source]

Set the dictionary to be stripped. This will remove all keys that are not in the schema. In constrast to strict() this function does not raise an error if a key is not in the schema.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schemas:

from parasite import p

schema = p.obj({ "name": p.string() }).strip()
schema2 = p.obj({ "name": p.string() })

The resulting schemas will parse the following objects:

>>> schema.parse({ "name": "John" })
{ "name": "John" }
>>> schema.parse({ "name": "John", "age": 20 })
{ "name": "John" }

>>> schema2.parse({ "name": "John" })
{ "name": "John" }
>>> schema2.parse({ "name": "John", "age": 20 })
{ "name": "John", "age": 20 }
extend(other: Object) Object[source]

Extend the dictionary with another dictionary. This will overwrite all values of the current dictionary with the values of the other dictionary if the key exists in both dictionaries. If you want to merge the dictionaries, use merge().

Parameters:

other (Object) – The dictionary to extend with.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following two schemas:

from parasite import p

schema = p.obj({ "name": p.string(), "age": p.string() })
schema2 = p.obj({ "age": p.number().integer() })

If we extend the two schemas, the resulting schema will be:

# -> schema.extend(schema2)

p.obj({
    "name": p.string(),
    "age": p.number().integer(),
})

The resulting schema will parse the following objects:

>>> schema.parse({ "name": "John", "age": 20 })
{ "name": "John", "age": 20 }

>>> schema.parse({ "name": "John", "age": "20" })
ValidationError: key "age" has to be an integer, but is 20
merge(other: Object) Object[source]

Merge the dictionary with another dictionary. This tries to merge the values of the current dictionary with the values of the other dictionary. If the key exists in both dictionaries the value of the current dictionary will not be overwritten, but the values will be merged. This results in the following behavior:

  • If both values are objects, they will be merged (merge()) into a single dictionary.

  • If both values are variants, they will be merged into a single variant.

  • If one value is a variant and the other is not, the value will be added to the variant.

  • If both values are something else, they will be merged into a new variant.

Parameters:

other (Object) – The dictionary to merge with.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following two schemas:

from parasite import p

schema = p.obj({ "name": p.string(), "age": p.string() })
schema2 = p.obj({ "age": p.number().integer() })

If we merge the two schemas, the resulting schema will be:

# -> schema.merge(schema2)

p.obj({
    "name": p.string(),
    "age": p.variant([
        p.string(),
        p.number().integer(),
    ])
})

The resulting schema will parse the following objects:

>>> schema.parse({ "name": "John", "age": 20 })
{ "name": "John", "age": 20 }

>>> schema.parse({ "name": "John", "age": "20" })
{ "name": "John", "age": "20" }
pick(keys: list) Object[source]

Pick only the keys from the object. This will create a new Object with only the keys found in the list. If a key is not found in the object, it will raise a KeyError. If you want to ignore keys that are not found, use pick_safe().

Parameters:

keys (list[K]) – The keys to pick.

Returns:

New instance of the class with only the picked keys.

Return type:

Object

Raises:

KeyError – If a key is not found in the object.

Example usage:

Lets assume we have the following schema:

from parasite import p

schema = p.obj({
    "name": p.string(),
    "age": p.number().integer(),
    "city": p.string(),
}).strict()

If we pick the keys “name” and “age”, the resulting schema will be:

# -> schema = schema.pick(["name", "age"])

p.obj({
    "name": p.string(),
    "age": p.number().integer(),
}).strict()

The resulting schema will parse the following objects:

>>> schema.parse({ "name": "John", "age": 20 })
{ "name": "John", "age": 20 }

>>> schema.parse({ "name": "John", "age": 20, "city": "New York" })
ValidationError: object has the key "city", but is not allowed to
pick_safe(keys: list) Object[source]

Pick only the keys from the object. This will create a new Object with only the keys found in the list. If a key is not found in the object, it will be ignored. If you want to raise an error if a key is not found, use pick().

Parameters:

keys (list[K]) – The keys to pick.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schema:

from parasite import p

schema = p.obj({
    "name": p.string(),
    "age": p.number().integer(),
    "city": p.string(),
}).strict()

If we pick the keys “name” and “age”, the resulting schema will be:

# -> schema = schema.pick_safe(["name", "age"])

p.obj({
    "name": p.string(),
    "age": p.number().integer(),
}).strict()

The resulting schema will parse the following objects:

>>> schema.parse({ "name": "John", "age": 20 })
{ "name": "John", "age": 20 }

>>> schema.parse({ "name": "John", "age": 20, "city": "New York" })
{ "name": "John", "age": 20 }
omit(keys: list) Object[source]

Omit the keys from the object. This will create a new Object with all keys except the ones found in the list.

Parameters:

keys (list[K]) – The keys to omit.

Returns:

New instance of the class with the omitted keys.

Return type:

Object

Example usage:

Lets assume we have the following schema:

from parasite import p

schema = p.obj({
    "name": p.string(),
    "age": p.number().integer(),
    "city": p.string(),
}).strict()

If we omit the keys “name” and “age”, the resulting schema will be:

# -> schema = schema.omit(["name", "age"])

p.obj({
    "city": p.string(),
}).strict()

The resulting schema will parse the following objects:

>>> schema.parse({ "name": "John", "age": 20, "city": "New York" })
ValidationError: object has the key "name", but is not allowed to

>>> schema.parse({ "city": "New York" })
{ "city": "New York" }
add_item(key: Any, item: ParasiteType) Object[source]

Add an item to the object. This will also overwrite the item if it already exists.

Parameters:
  • key (K) – The key of the item.

  • item (ParasiteType) – The item to add.

Returns:

The updated instance of the class.

Return type:

Object

Example usage:

Lets assume we have the following schema:

from parasite import p

schema = p.obj({
    "name": p.string(),
    "age": p.number().integer(),
}).strict()

If we add the key “city” with a string schema, the resulting schema will be:

# -> schema.add_item("city", p.string())

p.obj({
    "name": p.string(),
    "age": p.number().integer(),
    "city": p.string(),
}).strict()

The resulting schema will parse the following objects:

>>> schema.parse({ "name": "John", "age": 20, "city": "New York" })
{ "name": "John", "age": 20, "city": "New York" }

>>> schema.parse({ "name": "John", "age": 20 })
ValidationError: key "city" not found, but is required
parse(obj: Any) dict[Any, Any][source]

Default method for parsing a value. This method should be overridden by subclasses.

Throws:

ValidationError: if the value could not be parsed or was invalid

Parameters:

obj (Any) – value to parse

Returns:

parsed destination value

Return type:

T

parse_safe(obj: Any) Result[T, ValidationError]

Converts the result of parse() into a rusttypes.result.Result type. Should be used when safe parsing is required.

Note

Will only catch parasite.errors.ValidationError exceptions!!!

Parameters:

obj (Any) – value to parse

Returns:

parsed destination value or an error

Return type:

Result[T, ValidationError]