From c886af70bd3d3b7d2c067a77b86909cfa8231ff9 Mon Sep 17 00:00:00 2001 From: Oz Tiram Date: Fri, 19 Apr 2024 10:00:15 +0200 Subject: [PATCH] refactor: remove all unused DataView collections Signed-off-by: Oz Tiram --- src/plette/models/__init__.py | 2 +- src/plette/models/base.py | 172 +---------------------------- src/plette/models/hashes.py | 4 +- tests/integration/test_examples.py | 4 +- 4 files changed, 8 insertions(+), 174 deletions(-) diff --git a/src/plette/models/__init__.py b/src/plette/models/__init__.py index 90cb739..babe1f9 100644 --- a/src/plette/models/__init__.py +++ b/src/plette/models/__init__.py @@ -7,7 +7,7 @@ from .base import ( DataModel, DataModelCollection, DataModelMapping, DataModelSequence, - validate, DataValidationError, + DataValidationError, ) from .hashes import Hash diff --git a/src/plette/models/base.py b/src/plette/models/base.py index 152c77d..c3d6937 100644 --- a/src/plette/models/base.py +++ b/src/plette/models/base.py @@ -1,168 +1,3 @@ -try: - import cerberus -except ImportError: - cerberus = None - - -class ValidationError(ValueError): - def __init__(self, value, validator): - super(ValidationError, self).__init__(value) - self.validator = validator - self.value = value - - def __str__(self): - return '{}\n{}'.format( - self.value, - '\n'.join( - '{}: {}'.format(k, e) - for k, errors in self.validator.errors.items() - for e in errors - ) - ) - - -VALIDATORS = {} - - -def validate(cls, data): - if not cerberus: # Skip validation if Cerberus is not available. - return - schema = cls.__SCHEMA__ - key = id(schema) - try: - v = VALIDATORS[key] - except KeyError: - v = VALIDATORS[key] = cerberus.Validator(schema, allow_unknown=True) - if v.validate(data, normalize=False): - return - raise ValidationError(data, v) - - -class DataView(object): - """A "view" to a data. - - Validates the input mapping on creation. A subclass is expected to - provide a `__SCHEMA__` class attribute specifying a validator schema. - """ - - def __init__(self, data): - self.validate(data) - self._data = data - - def __repr__(self): - return "{0}({1!r})".format(type(self).__name__, self._data) - - def __eq__(self, other): - if not isinstance(other, type(self)): - raise TypeError( - "cannot compare {0!r} with {1!r}".format( - type(self).__name__, type(other).__name__ - ) - ) - return self._data == other._data - - def __getitem__(self, key): - return self._data[key] - - def __setitem__(self, key, value): - self._data[key] = value - - def __delitem__(self, key): - del self._data[key] - - def get(self, key, default=None): - try: - return self[key] - except KeyError: - return default - - @classmethod - def validate(cls, data): - return validate(cls, data) - - -class DataViewCollection(DataView): - """A homogeneous collection of data views. - - Subclasses are expected to assign a class attribute `item_class` to specify - the type of items it contains. This class will be used to coerce return - values when accessed. The item class should conform to the `DataView` - protocol. - - You should not instantiate an instance from this class, but from one of its - subclasses instead. - """ - - item_class = None - - def __repr__(self): - return "{0}({1!r})".format(type(self).__name__, self._data) - - def __len__(self): - return len(self._data) - - def __getitem__(self, key): - return self.item_class(self._data[key]) - - def __setitem__(self, key, value): - if isinstance(value, DataView): - value = value._data - self._data[key] = value - - def __delitem__(self, key): - del self._data[key] - - -class DataViewMapping(DataViewCollection): - """A mapping of data views. - - The keys are primitive values, while values are instances of `item_class`. - """ - - @classmethod - def validate(cls, data): - for d in data.values(): - cls.item_class.validate(d) - - def __iter__(self): - return iter(self._data) - - def keys(self): - return self._data.keys() - - def values(self): - return [self[k] for k in self._data] - - def items(self): - return [(k, self[k]) for k in self._data] - - - -class DataViewSequence(DataViewCollection): - """A sequence of data views. - - Each entry is an instance of `item_class`. - """ - - @classmethod - def validate(cls, data): - for d in data: - cls.item_class.validate(d) - - def __iter__(self): - return (self.item_class(d) for d in self._data) - - def __getitem__(self, key): - if isinstance(key, slice): - return type(self)(self._data[key]) - return super(DataViewSequence, self).__getitem__(key) - - def append(self, value): - if isinstance(value, DataView): - value = value._data - self._data.append(value) - - class DataValidationError(ValueError): pass @@ -219,7 +54,7 @@ class DataModelCollection(DataModel): Subclasses are expected to assign a class attribute `item_class` to specify the type of items it contains. This class will be used to coerce return - values when accessed. The item class should conform to the `DataView` + values when accessed. The item class should conform to the `DataModel` protocol. You should not instantiate an instance from this class, but from one of its @@ -238,7 +73,7 @@ def __getitem__(self, key): return self.item_class(self._data[key]) def __setitem__(self, key, value): - if isinstance(value, DataView): + if isinstance(value, DataModel): value = value._data self._data[key] = value @@ -266,7 +101,7 @@ def __getitem__(self, key): return super().__getitem__(key) def append(self, value): - if isinstance(value, DataView): + if isinstance(value, DataModel): value = value._data self._data.append(value) @@ -293,4 +128,3 @@ def values(self): def items(self): return [(k, self[k]) for k in self._data] - diff --git a/src/plette/models/hashes.py b/src/plette/models/hashes.py index ddf1f61..75c4c2c 100644 --- a/src/plette/models/hashes.py +++ b/src/plette/models/hashes.py @@ -1,5 +1,5 @@ -from .base import DataModel -from .base import DataValidationError +from .base import DataModel, DataValidationError + class Hash(DataModel): """A hash. diff --git a/tests/integration/test_examples.py b/tests/integration/test_examples.py index f3d8a4a..61338d2 100644 --- a/tests/integration/test_examples.py +++ b/tests/integration/test_examples.py @@ -5,13 +5,13 @@ import plette from plette import Pipfile -from plette.models.base import ValidationError +from plette.models.base import DataValidationError invalid_files = glob.glob("examples/*invalid*") valid_files = glob.glob("examples/*ok*") @pytest.mark.parametrize("fname", invalid_files) def test_invalid_files(fname): - with pytest.raises((ValueError, plette.models.base.ValidationError, ValidationError)) as excinfo: + with pytest.raises((ValueError, DataValidationError)) as excinfo: with open(fname) as f: pipfile = Pipfile.load(f)