Skip to content
Snippets Groups Projects
Commit c05a9182 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

v2.2.15

parent 96f99ae5
No related branches found
No related tags found
No related merge requests found
# v2.2.15
* _TBA_
* added `DictObject.is_valid_schema`
# v2.2.14
......
# coding=UTF-8
__version__ = '2.2.15a1'
__version__ = '2.2.15'
import typing as tp
from satella.configuration.schema import Descriptor, descriptor_from_dict
from satella.exceptions import ConfigurationValidationError
__all__ = ['DictObject', 'apply_dict_object']
class DictObject(dict):
"""
A dictionary wrapper that can be accessed by attributes. Eg:
>>> a = DictObject({'test': 5})
>>> self.assertEqual(a.test, 5)
"""
def __getattr__(self, item: str) -> tp.Any:
try:
return self[item]
......@@ -19,6 +27,27 @@ class DictObject(dict):
except KeyError as e:
raise AttributeError(repr(e))
def is_valid_schema(self, schema: tp.Union[Descriptor, dict]) -> bool:
"""
Check if this dictionary conforms to particular schema.
Schema is either a Descriptor, or a JSON-based schema. See satella.configuration.schema for details.
:param schema: schema to verify against
:return: whether is conformant
"""
if isinstance(schema, Descriptor):
descriptor = schema
else:
descriptor = descriptor_from_dict(schema)
try:
descriptor(self)
except ConfigurationValidationError:
return False
else:
return True
def apply_dict_object(v: tp.Any) -> tp.Union[DictObject, tp.Any]:
"""
......
......@@ -294,19 +294,21 @@ def _get_descriptor_for(key: str, value: tp.Any) -> Descriptor:
key, False, None)
else:
args = ()
type = value['type']
if type == 'list':
type_ = value['type']
if type_ == 'list':
of = _get_descriptor_for('', value.get('of', ''))
args = (of,)
elif type == 'union':
elif type_ == 'union':
args = [_get_descriptor_for('', x) for x in value.get('of', [])]
optional, default = False, None
if 'default' in value:
optional = True
default = value['default']
optional = value.get('optional', optional)
descriptor = BASE_LOOKUP_TABLE[type](*args)
descriptor = BASE_LOOKUP_TABLE[type_](*args)
return create_key(descriptor, key, optional, default)
elif isinstance(value, type):
return _get_descriptor_for(key, value.__qualname__)
else:
raise ConfigurationSchemaError('invalid schema, unrecognized config object %s' % (value,))
......@@ -350,6 +352,9 @@ def descriptor_from_dict(dct: dict) -> Descriptor:
"b": "str"
}
}
although you can pass "int", "float" and "str" without enclosing quotes, that will work too
:return: a Descriptor-based schema
"""
fields = []
......
......@@ -10,6 +10,10 @@ from satella.coding.structures import TimeBasedHeap, Heap, typednamedtuple, \
class TestTimeBasedHeap(unittest.TestCase):
def test_dict_object(self):
self.assertTrue(DictObject({'a': 5, 'b': 'test'}).is_valid_schema({'a': int, 'b': str}))
self.assertFalse(DictObject({'a': 5, 'b': 'test'}).is_valid_schema({'a': int, 'b': int}))
def test_omni(self):
class Omni(OmniHashableMixin):
_HASH_FIELDS_TO_USE = ['a']
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment