Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def to_preserialization_data(cls, python_value, *, default_to_skip=None):
if python_value is None:
return cls.DEFAULT
try:
return cls.TYPE(python_value)
except ValueError as exc:
try:
data = cls.TYPE(float(python_value))
except ValueError:
raise exc from None
else:
log.warn(f'Precision lost in conversion to int: {python_value}')
return data
class String(Converter, str):
"""Converter for `str` literals."""
TYPE = str
DEFAULT = ""
def to_python_value(cls, deserialized_data, *, target_object=None):
if isinstance(deserialized_data, str):
value = deserialized_data.lower() not in cls._FALSY
else:
value = cls.TYPE(deserialized_data)
return value
class Float(Converter, float):
"""Converter for `float` literals."""
TYPE = float
DEFAULT = 0.0
class Integer(Converter, int):
"""Converter for `int` literals."""
TYPE = int
DEFAULT = 0
@classmethod
def to_preserialization_data(cls, python_value, *, default_to_skip=None):
if python_value is None:
return cls.DEFAULT
try:
return cls.TYPE(python_value)
except ValueError as exc:
try:
data = cls.TYPE(float(python_value))
except ValueError:
raise exc from None
value.clear()
value.update(data)
return value
@classmethod
def to_preserialization_data(cls, python_value, *, default_to_skip=None):
data = dict(python_value)
if data == default_to_skip:
data.clear()
return data
class Dataclass(Converter):
"""Base converter for dataclasses."""
DATACLASS: Callable = None # type: ignore
CONVERTERS: Dict = None # type: ignore
@classmethod
def subclass(cls, dataclass, converters: Dict[str, type]):
name = f'{dataclass.__name__}Converter'
bases = (cls,)
attributes = {'DATACLASS': dataclass, 'CONVERTERS': converters}
return type(name, bases, attributes)
@classmethod
def to_python_value(cls, deserialized_data, *, target_object):
if isinstance(deserialized_data, dict):
data = deserialized_data.copy()
return converter
raise TypeError(f'Unsupported container type: {cls.__origin__}')
if isinstance(cls, str):
log.debug(f'Searching for class matching {cls!r} annotation')
for cls2 in Converter.__subclasses__():
if cls2.__name__ == cls:
register(cls, cls2)
log.debug(f'Registered {cls2} as new converter')
return cls2
if not isclass(cls):
raise TypeError(f'Annotation is not a type: {cls!r}')
if issubclass(cls, Converter):
log.debug(f'Mapped {cls!r} to existing converter (itself)')
return cls
raise TypeError(f'Could not map type: {cls}')
elif cls.__origin__ == Union:
converter = map_type(cls.__args__[0])
assert len(cls.__args__) == 2
assert cls.__args__[1] == type(None)
converter = converter.as_optional()
if converter:
log.debug(f'Mapped {cls!r} to new converter: {converter}')
return converter
raise TypeError(f'Unsupported container type: {cls.__origin__}')
if isinstance(cls, str):
log.debug(f'Searching for class matching {cls!r} annotation')
for cls2 in Converter.__subclasses__():
if cls2.__name__ == cls:
register(cls, cls2)
log.debug(f'Registered {cls2} as new converter')
return cls2
if not isclass(cls):
raise TypeError(f'Annotation is not a type: {cls!r}')
if issubclass(cls, Converter):
log.debug(f'Mapped {cls!r} to existing converter (itself)')
return cls
raise TypeError(f'Could not map type: {cls}')
sorted(convert(item, default_to_skip=None) for item in python_value)
)
else:
for item in python_value:
data.append(convert(item, default_to_skip=None))
else:
data.append(convert(python_value, default_to_skip=None))
if data == default_to_skip:
data.clear()
return data or [None]
class Dictionary(Converter):
"""Base converter for raw dictionaries."""
@classmethod
def subclass(cls, key: type, value: type):
name = f'{key.__name__}{value.__name__}Dict'
bases = (cls,)
return type(name, bases, {})
@classmethod
def to_python_value(cls, deserialized_data, *, target_object):
if isinstance(deserialized_data, dict):
data = deserialized_data.copy()
else:
data = {}
if target_object is None or target_object is Missing:
"""Converter for `bool` literals."""
TYPE = bool
DEFAULT = False
_FALSY = {'false', 'f', 'no', 'n', 'disabled', 'off', '0'}
@classmethod
def to_python_value(cls, deserialized_data, *, target_object=None):
if isinstance(deserialized_data, str):
value = deserialized_data.lower() not in cls._FALSY
else:
value = cls.TYPE(deserialized_data)
return value
class Float(Converter, float):
"""Converter for `float` literals."""
TYPE = float
DEFAULT = 0.0
class Integer(Converter, int):
"""Converter for `int` literals."""
TYPE = int
DEFAULT = 0
@classmethod
def to_preserialization_data(cls, python_value, *, default_to_skip=None):
if python_value is None:
return cls.DEFAULT
# pylint: disable=unused-argument,not-callable
from ._bases import Converter
class Enumeration(Converter):
ENUM: type = NotImplemented
@classmethod
def of_type(cls, enum: type):
name = f'{enum.__name__}Converter'
bases = (cls,)
attributes = {'ENUM': enum}
return type(name, bases, attributes)
@classmethod
def to_python_value(cls, deserialized_data, *, target_object=None):
return cls.ENUM(deserialized_data)
@classmethod
def to_preserialization_data(cls, python_value, *, default_to_skip=None):
from collections.abc import Iterable
from contextlib import suppress
from typing import Callable, Dict
import log
from ..utils import Missing, get_default_field_value
from ._bases import Converter
class List(Converter):
"""Base converter for homogeneous lists of another converter."""
CONVERTER: Converter = None # type: ignore
@classmethod
def subclass(cls, converter: type):
name = f'{converter.__name__}List'
bases = (cls,)
attributes = {'CONVERTER': converter}
return type(name, bases, attributes)
@classmethod
def to_python_value(cls, deserialized_data, *, target_object):
if target_object is None or target_object is Missing:
value = []
else:
# pylint: disable=unused-argument
import log
from ._bases import Converter
class Boolean(Converter, int):
"""Converter for `bool` literals."""
TYPE = bool
DEFAULT = False
_FALSY = {'false', 'f', 'no', 'n', 'disabled', 'off', '0'}
@classmethod
def to_python_value(cls, deserialized_data, *, target_object=None):
if isinstance(deserialized_data, str):
value = deserialized_data.lower() not in cls._FALSY
else:
value = cls.TYPE(deserialized_data)
return value
class Float(Converter, float):