Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
You may ask additional arguments between ``cls`` and ``kwargs``.
:param func: the serializer function.
:param cls: the type or sequence of types this serializer can handle.
:param high_prio: determines the order in which is looked for the callable.
:param fork_inst: if given, it uses this fork of ``JsonSerializable``.
:return: None.
"""
if isinstance(cls, Sequence):
for cls_ in cls:
set_serializer(func, cls_, high_prio, fork_inst)
elif cls:
index = 0 if high_prio else len(fork_inst._classes_serializers)
fork_inst._classes_serializers.insert(index, cls)
cls_name = get_class_name(cls, fork_inst=fork_inst,
fully_qualified=True)
fork_inst._serializers[cls_name.lower()] = func
else:
fork_inst._serializers['nonetype'] = func
strip_class_variables=strip_class_variables,
strip_attr=strip_attr,
**kwargs)
_store_cls_info(dumped_elem, attr, kwargs)
except RecursionDetectedError:
fork_inst._warn('Recursive structure detected in attribute "{}" '
'of object of type "{}", ignoring the attribute.'
.format(attr_name, get_class_name(cls)))
except SerializationError as err:
if strict:
raise
else:
fork_inst._warn('Failed to dump attribute "{}" of object of '
'type "{}". Reason: {}. Ignoring the '
'attribute.'
.format(attr, get_class_name(cls), err.message))
break
_add_dumped_elem(result, attr_name, dumped_elem,
strip_nulls, key_transformer)
return result
def _get_lizer_by_parents(cls: type,
lizers: Dict[str, callable],
classes_lizers: list,
fork_inst: type) -> callable:
result = None
parents = get_parents(cls, classes_lizers)
if parents:
pname = get_class_name(parents[0], str.lower, fork_inst=fork_inst,
fully_qualified=True)
result = lizers[pname]
return result
def _store_cls_info(result: object, attr: str, original_obj: dict, **kwargs):
if isinstance(result, dict) and kwargs.get('_store_cls'):
cls = get_type(original_obj[attr])
if cls.__module__ == 'typing':
cls_name = repr(cls)
else:
cls_name = get_class_name(cls, fully_qualified=True,
fork_inst=kwargs['fork_inst'])
result['-cls'] = cls_name
def _check_and_get_cls_and_meta_hints(
json_obj: object,
cls: type,
fork_inst: type,
inferred_cls: bool) -> Tuple[type, Optional[dict]]:
# Check if json_obj is of a valid type and return the cls.
if type(json_obj) not in VALID_TYPES:
invalid_type = get_class_name(type(json_obj), fork_inst=fork_inst,
fully_qualified=True)
valid_types = [get_class_name(typ, fork_inst=fork_inst,
fully_qualified=True)
for typ in VALID_TYPES]
msg = ('Invalid type: "{}", only arguments of the following types are '
'allowed: {}'.format(invalid_type, ", ".join(valid_types)))
raise DeserializationError(msg, json_obj, cls)
if json_obj is None:
raise DeserializationError('Cannot load None with strict=True',
json_obj, cls)
cls_from_meta, meta = get_cls_and_meta(json_obj, fork_inst)
meta_hints = meta.get('classes', {}) if meta else {}
return determine_precedence(
cls, cls_from_meta, type(json_obj), inferred_cls), meta_hints
def _check_and_get_cls_and_meta_hints(
json_obj: object,
cls: type,
fork_inst: type,
inferred_cls: bool) -> Tuple[type, Optional[dict]]:
# Check if json_obj is of a valid type and return the cls.
if type(json_obj) not in VALID_TYPES:
invalid_type = get_class_name(type(json_obj), fully_qualified=True)
valid_types = [get_class_name(typ, fully_qualified=True)
for typ in VALID_TYPES]
msg = ('Invalid type: "{}", only arguments of the following types are '
'allowed: {}'.format(invalid_type, ", ".join(valid_types)))
raise DeserializationError(msg, json_obj, cls)
cls_from_meta, meta = get_cls_and_meta(json_obj, fork_inst)
meta_hints = meta.get('classes', {}) if meta else {}
return determine_precedence(
cls, cls_from_meta, type(json_obj), inferred_cls), meta_hints
You can also provide ``cls`` to specify that ``obj`` needs to be serialized
as if it was of type ``cls`` (meaning to only take into account attributes
from ``cls``). The type ``cls`` must have a ``__slots__`` defined. Any type
will do, but in most cases you may want ``cls`` to be a base class of
``obj``.
:param obj: a Python instance of any sort.
:param cls: if given, ``obj`` will be dumped as if it is of type ``type``.
:param fork_inst: if given, it uses this fork of ``JsonSerializable``.
:param kwargs: the keyword args are passed on to the serializer function.
:return: the serialized obj as a JSON type.
"""
if cls and not hasattr(cls, '__slots__'):
raise SerializationError('Invalid type: "{}". Only types that have a '
'__slots__ defined are allowed when '
'providing "cls".'
.format(get_class_name(cls, fork_inst=fork_inst,
fully_qualified=True)))
cls_ = cls or obj.__class__
serializer = _get_serializer(cls_, fork_inst)
kwargs_ = {
'fork_inst': fork_inst,
**kwargs
}
announce_class(cls_, fork_inst=fork_inst)
try:
return serializer(obj, cls=cls, **kwargs_)
except Exception as err:
raise SerializationError(str(err))
fork_inst: type = StateHolder) -> None:
"""
Set a validator function for the given ``cls``. The function should accept
an instance of the type it should validate and must return ``False`` or
raise any exception in case of a validation failure.
:param func: the function that takes an instance of type ``cls`` and
returns a bool (``True`` if the validation was successful).
:param cls: the type or types that ``func`` is able to validate.
:param fork_inst: if given, it uses this fork of ``JsonSerializable``.
:return: None.
"""
if isinstance(cls, Sequence):
for cls_ in cls:
set_validator(func, cls=cls_, fork_inst=fork_inst)
else:
cls_name = get_class_name(cls, fully_qualified=True)
fork_inst._validators[cls_name.lower()] = func
fork_inst._classes_validators.append(cls)