Spade
Mini Shell
�
�t0^c@s�dZddlZddlZddlZddlmZmZyddlmZm Z Wn'e
k
r�ddlmZm Z nXejej
�defd��Y�ZdS(sJOSE
interfaces.i����N(terrorstutil(tSequencetMappingtJSONDeSerializablecBskeZdZejd��Zd�Zejd��Z e
d��Zd�Zd�Z
e
d��ZRS(s�Interface for (de)serializable JSON objects.
Please recall, that standard Python library implements
:class:`json.JSONEncoder` and :class:`json.JSONDecoder` that perform
translations based on respective :ref:`conversion tables
<conversion-table>` that look pretty much like the one below (for
complete tables see relevant Python documentation):
.. _conversion-table:
====== ======
JSON Python
====== ======
object dict
... ...
====== ======
While the above **conversion table** is about translation of JSON
documents to/from the basic Python types only,
:class:`JSONDeSerializable` introduces the following two concepts:
serialization
Turning an arbitrary Python object into Python object that can
be encoded into a JSON document. **Full serialization** produces
a Python object composed of only basic types as required by the
:ref:`conversion table <conversion-table>`. **Partial
serialization** (accomplished by :meth:`to_partial_json`)
produces a Python object that might also be built from other
:class:`JSONDeSerializable` objects.
deserialization
Turning a decoded Python object (necessarily one of the basic
types as required by the :ref:`conversion table
<conversion-table>`) into an arbitrary Python object.
Serialization produces **serialized object** ("partially
serialized
object" or "fully serialized object" for partial and
full
serialization respectively) and deserialization produces
**deserialized object**, both usually denoted in the source code as
``jobj``.
Wording in the official Python documentation might be confusing
after reading the above, but in the light of those definitions, one
can view :meth:`json.JSONDecoder.decode` as decoder and
deserializer of basic types, :meth:`json.JSONEncoder.default` as
serializer of basic types, :meth:`json.JSONEncoder.encode` as
serializer and encoder of basic types.
One could extend :mod:`json` to support arbitrary object
(de)serialization either by:
- overriding :meth:`json.JSONDecoder.decode` and
:meth:`json.JSONEncoder.default` in subclasses
- or passing ``object_hook`` argument (or ``object_hook_pairs``)
to :func:`json.load`/:func:`json.loads` or ``default`` argument
for :func:`json.dump`/:func:`json.dumps`.
Interestingly, ``default`` is required to perform only partial
serialization, as :func:`json.dumps` applies ``default``
recursively. This is the idea behind making :meth:`to_partial_json`
produce only partial serialization, while providing custom
:meth:`json_dumps` that dumps with ``default`` set to
:meth:`json_dump_default`.
To make further documentation a bit more concrete, please, consider
the following imaginatory implementation example::
class Foo(JSONDeSerializable):
def to_partial_json(self):
return 'foo'
@classmethod
def from_json(cls, jobj):
return Foo()
class Bar(JSONDeSerializable):
def to_partial_json(self):
return [Foo(), Foo()]
@classmethod
def from_json(cls, jobj):
return Bar()
cCs
t��dS(s�Partially serialize.
Following the example, **partial serialization** means the
following::
assert isinstance(Bar().to_partial_json()[0], Foo)
assert isinstance(Bar().to_partial_json()[1], Foo)
# in particular...
assert Bar().to_partial_json() != ['foo',
'foo']
:raises josepy.errors.SerializationError:
in case of any serialization error.
:returns: Partially serializable object.
N(tNotImplementedError(tself((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pytto_partial_jsonkscs�fd���|�S(sDFully
serialize.
Again, following the example from before, **full serialization**
means the following::
assert Bar().to_json() == ['foo', 'foo']
:raises josepy.errors.SerializationError:
in case of any serialization error.
:returns: Fully serialized object.
cs�t|t�r�|j��St|tj�r5|St|t�rag|D]}�|�^qKSt|t�r�t�fd�|D��St|t�r�t �fd�tj
|�D��S|SdS(Nc3s|]}�|�VqdS(N((t.0tsubobj(t
_serialize(s5/usr/lib/python2.7/site-packages/josepy/interfaces.pys <genexpr>�sc3s-|]#\}}�|��|�fVqdS(N((Rtkeytvalue(R
(s5/usr/lib/python2.7/site-packages/josepy/interfaces.pys <genexpr>�s(t
isinstanceRRtsixtstring_typestlistRttupleRtdictt iteritems(tobjR (R
(s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyR
�s((R((R
s5/usr/lib/python2.7/site-packages/josepy/interfaces.pytto_json~s
cCs|�S(s�Deserialize
a decoded JSON document.
:param jobj: Python object, composed of only other basic data
types, as decoded from JSON document. Not necessarily
:class:`dict` (as decoded from "JSON object"
document).
:raises josepy.errors.DeserializationError:
if decoding was unsuccessful, e.g. in case of unparseable
X509 certificate, or wrong padding in JOSE base64 encoded
string, etc.
((tclstjobj((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyt from_json�scCsEytj|�}Wn"tk
r7}tj|��nX|j|�S(s&Deserialize from JSON document
string.(tjsontloadst
ValueErrorRtDeserializationErrorR(Rtjson_stringRterror((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyt
json_loads�s
cKstj|d|j|�S(ssDump to JSON string using proper
serializer.
:returns: JSON document string.
:rtype: str
tdefault(Rtdumpstjson_dump_default(Rtkwargs((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyt
json_dumps�scCs|jdtdddd�S(sNDump the object to pretty
JSON document string.
:rtype: str
t sort_keystindentit
separatorst,s: (R(s:
(R$tTrue(R((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pytjson_dumps_pretty�scCs3t|t�r|j�Stt|�d��dS(s�Serialize
Python object.
This function is meant to be passed as ``default`` to
:func:`json.dump` or :func:`json.dumps`. They call
``default(python_object)`` only for non-basic Python types, so
this function necessarily raises :class:`TypeError` if
``python_object`` is not an instance of
:class:`IJSONSerializable`.
Please read the class docstring for more information.
s is not JSON
serializableN(R
RRt TypeErrortrepr(Rt
python_object((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyR"�s
(t__name__t
__module__t__doc__tabctabstractmethodRRRtabstractclassmethodRtclassmethodRR$R*R"(((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyRsW
(R0R1RRtjosepyRRtcollections.abcRRtImportErrortcollectionst
add_metaclasstABCMetatobjectR(((s5/usr/lib/python2.7/site-packages/josepy/interfaces.pyt<module>s