Skip to content

Commit

Permalink
refactor: remove all unused DataView collections
Browse files Browse the repository at this point in the history
Signed-off-by: Oz Tiram <oz.tiram@gmail.com>
  • Loading branch information
oz123 committed Apr 19, 2024
1 parent a766fe1 commit c886af7
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 174 deletions.
2 changes: 1 addition & 1 deletion src/plette/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from .base import (
DataModel, DataModelCollection, DataModelMapping, DataModelSequence,
validate, DataValidationError,
DataValidationError,
)

from .hashes import Hash
Expand Down
172 changes: 3 additions & 169 deletions src/plette/models/base.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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)

Expand All @@ -293,4 +128,3 @@ def values(self):

def items(self):
return [(k, self[k]) for k in self._data]

4 changes: 2 additions & 2 deletions src/plette/models/hashes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base import DataModel
from .base import DataValidationError
from .base import DataModel, DataValidationError


class Hash(DataModel):
"""A hash.
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit c886af7

Please sign in to comment.