Module omnipy.modules.general.models
Overview
View Source
from typing import Generic, Hashable, TypeAlias, TypeVar
from omnipy.data.model import Model
from omnipy.modules.general.typedefs import FrozenDict
from omnipy.util.helpers import is_iterable
class NotIterableExceptStrOrBytesModel(Model[object | None]):
"""
Model describing any object that is not iterable, except for `str` and `bytes` types.
As strings and bytes are iterable (over the characters/bytes) but also generally useful and
often considered singular (or scalar) types, they are specifically allowed by this model.
Examples:
>>> from omnipy import NotIterableExceptStrOrBytesModel, print_exception
>>>
>>> NotIterableExceptStrOrBytesModel(1234)
NotIterableExceptStrOrBytesModel(1234)
>>> NotIterableExceptStrOrBytesModel('1234')
NotIterableExceptStrOrBytesModel(1234)
>>> with print_exception:
... NotIterableExceptStrOrBytesModel((1, 2, 3, 4))
ValidationError: 1 validation error for NotIterableExceptStrOrBytesModel
Note:
JsonScalarModel is a strict submodel of NotIterableExceptStrOrBytesModel in that all objects
allowed by JsonScalarModel are also allowed by NotIterableExceptStrOrBytesModel.
"""
@classmethod
def _parse_data(cls, data: object) -> object:
assert isinstance(data, str) or isinstance(data, bytes) or not is_iterable(data), \
f'Data of type {type(data)} is iterable'
return data
# TODO: Follow pydantic topic https://github.com/pydantic/pydantic/issues/6868 on MappingProxyType.
# Used way too much energy to implement (and test) recursive frozen models, only to discover
# that pydantic actually does not support MappingProxyType, which was hugely surprising.
# Add tests on the immutability part once there is support for this.
# Note: see comments in omnipy.modules.json.models for more information on the basic organisation of
# nested models.
#
# Private models
#
# Basic building block models
_KeyT = TypeVar('_KeyT', bound=str | Hashable)
_ValT = TypeVar('_ValT', bound=NotIterableExceptStrOrBytesModel | object)
_FrozenBaseT = TypeVar('_FrozenBaseT')
# class _FrozenScalarM(NotIterableExceptStrOrBytesModel):
# ...
class _FrozenScalarM(Model[_ValT], Generic[_ValT]):
_parse_data = NotIterableExceptStrOrBytesModel._parse_data
class _FrozenTupleBaseM(Model[tuple[_FrozenBaseT, ...]], Generic[_FrozenBaseT]):
...
class _FrozenDictBaseM(Model[FrozenDict[_KeyT, _FrozenBaseT]], Generic[_KeyT, _FrozenBaseT]):
...
class _FrozenTupleM(_FrozenTupleBaseM['_FrozenAnyUnion'], Generic[_ValT]):
...
#
# class _FrozenDictM(_FrozenDictBaseM[_KeyT, '_FrozenAnyUnion'], Generic[_KeyT, _ValT]):
# ...
class _FrozenDictM(_FrozenDictBaseM[str | Hashable, '_FrozenAnyUnion'], Generic[_KeyT, _ValT]):
...
class _FrozenNoDictsM(_FrozenTupleBaseM['_FrozenNoDictsUnion'], Generic[_ValT]):
...
# class _FrozenNoTuplesM(_FrozenDictBaseM['_KeyT', '_FrozenNoTuplesUnion'], Generic[_KeyT, _ValT]):
# ...
class _FrozenNoTuplesM(_FrozenDictBaseM[str | Hashable, '_FrozenNoTuplesUnion'],
Generic[_KeyT, _ValT]):
...
# TypeAliases
_FrozenAnyUnion: TypeAlias = \
_FrozenScalarM[_ValT] | _FrozenTupleM[_ValT] | _FrozenDictM[_KeyT, _ValT]
_FrozenNoDictsUnion: TypeAlias = _FrozenScalarM[_ValT] | _FrozenNoDictsM[_ValT]
_FrozenNoTuplesUnion: TypeAlias = _FrozenScalarM[_ValT] | _FrozenNoTuplesM[_KeyT, _ValT]
# Basic models needs to update their forward_refs with type aliases declared above
_FrozenTupleM.update_forward_refs()
_FrozenDictM.update_forward_refs()
_FrozenNoDictsM.update_forward_refs()
_FrozenNoTuplesM.update_forward_refs()
#
# Exportable models
#
# General
class NestedFrozenDictsOrTuplesModel(Model[_FrozenAnyUnion], Generic[_KeyT, _ValT]):
"""
Recursive model for nested immutable containers (FrozenDict and tuples). Not functional.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work.
Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
"""
class NestedFrozenTuplesModel(Model[_FrozenNoDictsM[_ValT]], Generic[_ValT]):
"""
Recursive model for nested tuples.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work.
Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
"""
class NestedFrozenDictsModel(Model[_FrozenNoTuplesM[_KeyT, _ValT]], Generic[_KeyT, _ValT]):
"""
Recursive model for nested FrozenDicts.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work.
Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
"""
Classes
NestedFrozenDictsModel
class NestedFrozenDictsModel(
value: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
*,
__root__: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
**data: Any
)
Recursive model for nested FrozenDicts.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work. Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
View Source
class NestedFrozenDictsModel(Model[_FrozenNoTuplesM[_KeyT, _ValT]], Generic[_KeyT, _ValT]):
"""
Recursive model for nested FrozenDicts.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work.
Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
"""
Class variables
Static methods
to_json_schema
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
@classmethod
def to_json_schema(cls, pretty=False) -> str:
schema = cls.schema()
if pretty:
return cls._pretty_print_json(schema)
else:
return json.dumps(schema)
validate
Hack to allow overwriting of iter method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
Model |
View Source
@classmethod
def validate(cls: Type['Model'], value: Any) -> 'Model':
"""
Hack to allow overwriting of __iter__ method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
"""
if isinstance(value, Model):
with AttribHolder(value, '__iter__', GenericModel.__iter__, on_class=True):
return super().validate(value)
else:
return super().validate(value)
Instance variables
Methods
delitem
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
eq
Return self==value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
object |
Returns:
Type | Description |
---|---|
bool |
View Source
def __eq__(self, other: object) -> bool:
return isinstance(other, Model) \
and self.__class__ == other.__class__ \
and self.contents == other.contents \
and self.to_data() == other.to_data() # last is probably unnecessary, but just in case
getattr
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
Returns:
Type | Description |
---|---|
Any |
View Source
def __getattr__(self, attr: str) -> Any:
ret = self._getattr_from_contents(attr)
if callable(ret):
ret = add_callback_after_call(ret, self.validate_contents)
return ret
iter
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
setattr
Implement setattr(self, name, value).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
||
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def __setattr__(self, attr: str, value: Any) -> None:
if attr in self.__dict__ and attr not in [ROOT_KEY]:
super().__setattr__(attr, value)
else:
if attr in ['contents']:
contents_prop = getattr(self.__class__, attr)
contents_prop.__set__(self, value)
else:
raise RuntimeError('Model does not allow setting of extra attributes')
setitem
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
from_data
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_data(self, value: Any) -> None:
self.contents = value
from_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
json_contents |
str |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_json(self, json_contents: str) -> None:
new_model = self.parse_raw(json_contents, proto=pydantic_protocol.json)
self._set_contents_without_validation(new_model)
inner_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def inner_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=False, with_args=with_args)
is_nested_type
Returns:
Type | Description |
---|---|
bool |
View Source
def is_nested_type(self) -> bool:
return not self.inner_type(with_args=True) == self.outer_type(with_args=True)
outer_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def outer_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=True, with_args=with_args)
to_data
Returns:
Type | Description |
---|---|
Any |
View Source
def to_data(self) -> Any:
return self.dict()[ROOT_KEY]
to_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
def to_json(self, pretty=False) -> str:
json_content = self.json()
if pretty:
return self._pretty_print_json(json.loads(json_content))
else:
return json_content
validate_contents
View Source
def validate_contents(self):
self.contents = self.contents
NestedFrozenDictsOrTuplesModel
class NestedFrozenDictsOrTuplesModel(
value: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
*,
__root__: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
**data: Any
)
Recursive model for nested immutable containers (FrozenDict and tuples). Not functional.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work. Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
View Source
class NestedFrozenDictsOrTuplesModel(Model[_FrozenAnyUnion], Generic[_KeyT, _ValT]):
"""
Recursive model for nested immutable containers (FrozenDict and tuples). Not functional.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work.
Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
"""
Class variables
Static methods
to_json_schema
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
@classmethod
def to_json_schema(cls, pretty=False) -> str:
schema = cls.schema()
if pretty:
return cls._pretty_print_json(schema)
else:
return json.dumps(schema)
validate
Hack to allow overwriting of iter method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
Model |
View Source
@classmethod
def validate(cls: Type['Model'], value: Any) -> 'Model':
"""
Hack to allow overwriting of __iter__ method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
"""
if isinstance(value, Model):
with AttribHolder(value, '__iter__', GenericModel.__iter__, on_class=True):
return super().validate(value)
else:
return super().validate(value)
Instance variables
Methods
delitem
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
eq
Return self==value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
object |
Returns:
Type | Description |
---|---|
bool |
View Source
def __eq__(self, other: object) -> bool:
return isinstance(other, Model) \
and self.__class__ == other.__class__ \
and self.contents == other.contents \
and self.to_data() == other.to_data() # last is probably unnecessary, but just in case
getattr
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
Returns:
Type | Description |
---|---|
Any |
View Source
def __getattr__(self, attr: str) -> Any:
ret = self._getattr_from_contents(attr)
if callable(ret):
ret = add_callback_after_call(ret, self.validate_contents)
return ret
iter
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
setattr
Implement setattr(self, name, value).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
||
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def __setattr__(self, attr: str, value: Any) -> None:
if attr in self.__dict__ and attr not in [ROOT_KEY]:
super().__setattr__(attr, value)
else:
if attr in ['contents']:
contents_prop = getattr(self.__class__, attr)
contents_prop.__set__(self, value)
else:
raise RuntimeError('Model does not allow setting of extra attributes')
setitem
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
from_data
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_data(self, value: Any) -> None:
self.contents = value
from_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
json_contents |
str |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_json(self, json_contents: str) -> None:
new_model = self.parse_raw(json_contents, proto=pydantic_protocol.json)
self._set_contents_without_validation(new_model)
inner_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def inner_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=False, with_args=with_args)
is_nested_type
Returns:
Type | Description |
---|---|
bool |
View Source
def is_nested_type(self) -> bool:
return not self.inner_type(with_args=True) == self.outer_type(with_args=True)
outer_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def outer_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=True, with_args=with_args)
to_data
Returns:
Type | Description |
---|---|
Any |
View Source
def to_data(self) -> Any:
return self.dict()[ROOT_KEY]
to_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
def to_json(self, pretty=False) -> str:
json_content = self.json()
if pretty:
return self._pretty_print_json(json.loads(json_content))
else:
return json_content
validate_contents
View Source
def validate_contents(self):
self.contents = self.contents
NestedFrozenTuplesModel
class NestedFrozenTuplesModel(
value: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
*,
__root__: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
**data: Any
)
Recursive model for nested tuples.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work. Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
View Source
class NestedFrozenTuplesModel(Model[_FrozenNoDictsM[_ValT]], Generic[_ValT]):
"""
Recursive model for nested tuples.
Awaiting support for MappingProxyType in pydantic for the immutability to actually work.
Also use as generic types awaits Python 3.13. Way ahead of the crowd here!
"""
Class variables
Static methods
to_json_schema
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
@classmethod
def to_json_schema(cls, pretty=False) -> str:
schema = cls.schema()
if pretty:
return cls._pretty_print_json(schema)
else:
return json.dumps(schema)
validate
Hack to allow overwriting of iter method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
Model |
View Source
@classmethod
def validate(cls: Type['Model'], value: Any) -> 'Model':
"""
Hack to allow overwriting of __iter__ method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
"""
if isinstance(value, Model):
with AttribHolder(value, '__iter__', GenericModel.__iter__, on_class=True):
return super().validate(value)
else:
return super().validate(value)
Instance variables
Methods
eq
Return self==value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
object |
Returns:
Type | Description |
---|---|
bool |
View Source
def __eq__(self, other: object) -> bool:
return isinstance(other, Model) \
and self.__class__ == other.__class__ \
and self.contents == other.contents \
and self.to_data() == other.to_data() # last is probably unnecessary, but just in case
getattr
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
Returns:
Type | Description |
---|---|
Any |
View Source
def __getattr__(self, attr: str) -> Any:
ret = self._getattr_from_contents(attr)
if callable(ret):
ret = add_callback_after_call(ret, self.validate_contents)
return ret
iter
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
object |
||
kwargs |
object |
Returns:
Type | Description |
---|---|
object |
View Source
def _method(cls_or_self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(cls_or_self, *self.args, *args, **keywords)
setattr
Implement setattr(self, name, value).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
||
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def __setattr__(self, attr: str, value: Any) -> None:
if attr in self.__dict__ and attr not in [ROOT_KEY]:
super().__setattr__(attr, value)
else:
if attr in ['contents']:
contents_prop = getattr(self.__class__, attr)
contents_prop.__set__(self, value)
else:
raise RuntimeError('Model does not allow setting of extra attributes')
from_data
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_data(self, value: Any) -> None:
self.contents = value
from_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
json_contents |
str |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_json(self, json_contents: str) -> None:
new_model = self.parse_raw(json_contents, proto=pydantic_protocol.json)
self._set_contents_without_validation(new_model)
inner_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def inner_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=False, with_args=with_args)
is_nested_type
Returns:
Type | Description |
---|---|
bool |
View Source
def is_nested_type(self) -> bool:
return not self.inner_type(with_args=True) == self.outer_type(with_args=True)
outer_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def outer_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=True, with_args=with_args)
to_data
Returns:
Type | Description |
---|---|
Any |
View Source
def to_data(self) -> Any:
return self.dict()[ROOT_KEY]
to_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
def to_json(self, pretty=False) -> str:
json_content = self.json()
if pretty:
return self._pretty_print_json(json.loads(json_content))
else:
return json_content
validate_contents
View Source
def validate_contents(self):
self.contents = self.contents
NotIterableExceptStrOrBytesModel
class NotIterableExceptStrOrBytesModel(
value: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
*,
__root__: Union[Any, pydantic.fields.UndefinedType] = PydanticUndefined,
**data: Any
)
Model describing any object that is not iterable, except for str
and bytes
types.
As strings and bytes are iterable (over the characters/bytes) but also generally useful and often considered singular (or scalar) types, they are specifically allowed by this model.
View Source
class NotIterableExceptStrOrBytesModel(Model[object | None]):
"""
Model describing any object that is not iterable, except for `str` and `bytes` types.
As strings and bytes are iterable (over the characters/bytes) but also generally useful and
often considered singular (or scalar) types, they are specifically allowed by this model.
Examples:
>>> from omnipy import NotIterableExceptStrOrBytesModel, print_exception
>>>
>>> NotIterableExceptStrOrBytesModel(1234)
NotIterableExceptStrOrBytesModel(1234)
>>> NotIterableExceptStrOrBytesModel('1234')
NotIterableExceptStrOrBytesModel(1234)
>>> with print_exception:
... NotIterableExceptStrOrBytesModel((1, 2, 3, 4))
ValidationError: 1 validation error for NotIterableExceptStrOrBytesModel
Note:
JsonScalarModel is a strict submodel of NotIterableExceptStrOrBytesModel in that all objects
allowed by JsonScalarModel are also allowed by NotIterableExceptStrOrBytesModel.
"""
@classmethod
def _parse_data(cls, data: object) -> object:
assert isinstance(data, str) or isinstance(data, bytes) or not is_iterable(data), \
f'Data of type {type(data)} is iterable'
return data
Class variables
Static methods
to_json_schema
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
@classmethod
def to_json_schema(cls, pretty=False) -> str:
schema = cls.schema()
if pretty:
return cls._pretty_print_json(schema)
else:
return json.dumps(schema)
validate
Hack to allow overwriting of iter method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
Model |
View Source
@classmethod
def validate(cls: Type['Model'], value: Any) -> 'Model':
"""
Hack to allow overwriting of __iter__ method without compromising pydantic validation. Part
of the pydantic API and not the Omnipy API.
"""
if isinstance(value, Model):
with AttribHolder(value, '__iter__', GenericModel.__iter__, on_class=True):
return super().validate(value)
else:
return super().validate(value)
Instance variables
Methods
eq
Return self==value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
object |
Returns:
Type | Description |
---|---|
bool |
View Source
def __eq__(self, other: object) -> bool:
return isinstance(other, Model) \
and self.__class__ == other.__class__ \
and self.contents == other.contents \
and self.to_data() == other.to_data() # last is probably unnecessary, but just in case
getattr
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
Returns:
Type | Description |
---|---|
Any |
View Source
def __getattr__(self, attr: str) -> Any:
ret = self._getattr_from_contents(attr)
if callable(ret):
ret = add_callback_after_call(ret, self.validate_contents)
return ret
setattr
Implement setattr(self, name, value).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
attr |
str |
||
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def __setattr__(self, attr: str, value: Any) -> None:
if attr in self.__dict__ and attr not in [ROOT_KEY]:
super().__setattr__(attr, value)
else:
if attr in ['contents']:
contents_prop = getattr(self.__class__, attr)
contents_prop.__set__(self, value)
else:
raise RuntimeError('Model does not allow setting of extra attributes')
from_data
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_data(self, value: Any) -> None:
self.contents = value
from_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
json_contents |
str |
Returns:
Type | Description |
---|---|
NoneType |
View Source
def from_json(self, json_contents: str) -> None:
new_model = self.parse_raw(json_contents, proto=pydantic_protocol.json)
self._set_contents_without_validation(new_model)
inner_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def inner_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=False, with_args=with_args)
is_nested_type
Returns:
Type | Description |
---|---|
bool |
View Source
def is_nested_type(self) -> bool:
return not self.inner_type(with_args=True) == self.outer_type(with_args=True)
outer_type
Parameters:
Name | Type | Description | Default |
---|---|---|---|
with_args |
bool |
Returns:
Type | Description |
---|---|
type |
None |
View Source
def outer_type(self, with_args: bool = False) -> type | None:
return self.__class__._get_root_type(outer=True, with_args=with_args)
to_data
Returns:
Type | Description |
---|---|
Any |
View Source
def to_data(self) -> Any:
return self.dict()[ROOT_KEY]
to_json
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pretty |
Returns:
Type | Description |
---|---|
str |
View Source
def to_json(self, pretty=False) -> str:
json_content = self.json()
if pretty:
return self._pretty_print_json(json.loads(json_content))
else:
return json_content
validate_contents
View Source
def validate_contents(self):
self.contents = self.contents