diff --git a/docs/api.rst b/docs/api.rst index b5009907..1b0da45a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -171,18 +171,6 @@ implementation that Flask is using. .. autoclass:: SessionMixin :members: -.. autodata:: session_json_serializer - - This object provides dumping and loading methods similar to simplejson - but it also tags certain builtin Python objects that commonly appear in - sessions. Currently the following extended values are supported in - the JSON it dumps: - - - :class:`~markupsafe.Markup` objects - - :class:`~uuid.UUID` objects - - :class:`~datetime.datetime` objects - - :class:`tuple`\s - .. admonition:: Notice The ``PERMANENT_SESSION_LIFETIME`` config key can also be an integer @@ -354,6 +342,21 @@ you are using Flask 0.10 which implies that: .. autoclass:: JSONDecoder :members: +Tagged JSON +~~~~~~~~~~~ + +A compact representation for lossless serialization of non-standard JSON types. +:class:`~flask.sessions.SecureCookieSessionInterface` uses this to serialize +the session data, but it may be useful in other places. + +.. py:currentmodule:: flask.json.tag + +.. autoclass:: TaggedJSONSerializer + :members: + +.. autoclass:: JSONTag + :members: + Template Rendering ------------------ diff --git a/flask/json/tag.py b/flask/json/tag.py index 3cf32a0c..0ac583b5 100644 --- a/flask/json/tag.py +++ b/flask/json/tag.py @@ -13,36 +13,32 @@ class JSONTag(object): """Base class for defining type tags for :class:`TaggedJSONSerializer`.""" __slots__ = ('serializer',) + + #: The tag to mark the serialized object with. If ``None``, this tag is + #: only used as an intermediate step during tagging. key = None - """The tag to mark the serialized object with. If ``None``, this tag is - only used as an intermediate step during tagging.""" def __init__(self, serializer): """Create a tagger for the given serializer.""" - self.serializer = serializer def check(self, value): """Check if the given value should be tagged by this tag.""" - raise NotImplementedError def to_json(self, value): """Convert the Python object to an object that is a valid JSON type. The tag will be added later.""" - raise NotImplementedError def to_python(self, value): """Convert the JSON representation back to the correct type. The tag will already be removed.""" - raise NotImplementedError def tag(self, value): """Convert the value to a valid JSON type and add the tag structure around it.""" - return {self.key: self.to_json(value)} @@ -127,9 +123,9 @@ class TagBytes(JSONTag): class TagMarkup(JSONTag): - """Serialize anything matching the :class:`~markupsafe.Markup` API by + """Serialize anything matching the :class:`~flask.Markup` API by having a ``__html__`` method to the result of that method. Always - deserializes to an instance of :class:`~markupsafe.Markup`.""" + deserializes to an instance of :class:`~flask.Markup`.""" __slots__ = ('serializer',) key = ' m' @@ -175,15 +171,26 @@ class TagDateTime(JSONTag): class TaggedJSONSerializer(object): """Serializer that uses a tag system to compactly represent objects that are not JSON types. Passed as the intermediate serializer to - :class:`itsdangerous.Serializer`.""" + :class:`itsdangerous.Serializer`. + + The following extra types are supported: + + * :class:`dict` + * :class:`tuple` + * :class:`bytes` + * :class:`~flask.Markup` + * :class:`~uuid.UUID` + * :class:`~datetime.datetime` + """ __slots__ = ('tags', 'order') + + #: Tag classes to bind when creating the serializer. Other tags can be + #: added later using :meth:`~register`. default_tags = [ TagDict, PassDict, TagTuple, PassList, TagBytes, TagMarkup, TagUUID, TagDateTime, ] - """Tag classes to bind when creating the serializer. Other tags can be - added later using :meth:`~register`.""" def __init__(self): self.tags = {} @@ -206,7 +213,6 @@ class TaggedJSONSerializer(object): :raise KeyError: if the tag key is already registered and ``force`` is not true. """ - tag = tag_class(self) key = tag.key @@ -223,7 +229,6 @@ class TaggedJSONSerializer(object): def tag(self, value): """Convert a value to a tagged representation if necessary.""" - for tag in self.order: if tag.check(value): return tag.tag(value) @@ -232,7 +237,6 @@ class TaggedJSONSerializer(object): def untag(self, value): """Convert a tagged representation back to the original type.""" - if len(value) != 1: return value @@ -245,7 +249,6 @@ class TaggedJSONSerializer(object): def dumps(self, value): """Tag the value and dump it to a compact JSON string.""" - return dumps(self.tag(value), separators=(',', ':')) def loads(self, value):