Source code for pytypewriter.exchange

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Created by pat on 9/21/19
"""
.. currentmodule:: pytypewriter.exchange
.. moduleauthor:: Pat Daburu <pat@daburu.net>

Document exchange... data exchange... it all starts here!
"""
from abc import ABC, abstractmethod
from typing import Any, Mapping
from .types import pycls, pyfqn, InvalidTypeException


[docs]class Exportable(ABC): """ Objects that can be exported as and loaded from simple data types should extend `Exportable` to make their intentions clear and their methods consistent. """
[docs] @abstractmethod def export(self) -> Mapping[str, Any]: """ Export the instance as a mapping of simple types. :return: the mapping """
[docs] @classmethod @abstractmethod def load(cls, data: Mapping[str, Any]) -> Any: """ Create an instance from a mapping. :param data: the data :return: the instance """
[docs]def export(exportable: Exportable) -> Mapping[str, Any]: """ Export an :py:class:`Exportable` including meta-data. :param exportable: the exportable :return: the mapping .. note:: This function will add a ``__type__`` key containing the fully-qualified type name. .. seealso:: * :py:func:`load` * :py:func:`pyfqn <pytypewriter.types.pyfqn>` """ exported = exportable.export() # Add meta-information to the exported data. exported['__type__'] = pyfqn(exportable) return exported
[docs]def load(data: Mapping[str, Any]) -> Any: """ :param data: a mapping that represents the type :return: the type instance .. note:: The mapping must contain a ``__type__`` key that contains the fully-qualified type name. .. seealso:: * :py:func:`export` * :py:func:`pycls <pytypewriter.types.pycls>` """ # Try to get the python class. try: cls = pycls(data['__type__']) except KeyError: # If there is no type information, we can't continue. raise InvalidTypeException( "The data is missing the '__type__' key." ) # Remove meta-information from the data. _data = { k: v for k, v in data.items() if k not in ('__type__',) } # Let the class take if from here. return cls.load(_data)