1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
U
ß=®d§"ã@s$dZddlmZddlZddlmZddlmZddlmZddl    m
Z
ddl m Z dd    l mZdd
l mZd d lmZd d lmZGdd„dƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGd d!„d!ƒZdS)"a
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. It
can be extended to support other types.
 
.. autoclass:: TaggedJSONSerializer
    :members:
 
.. autoclass:: JSONTag
    :members:
 
Let's see an example that adds support for
:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so
to handle this we will dump the items as a list of ``[key, value]``
pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to
identify the type. The session serializer processes dicts first, so
insert the new tag at the front of the order since ``OrderedDict`` must
be processed before ``dict``.
 
.. code-block:: python
 
    from flask.json.tag import JSONTag
 
    class TagOrderedDict(JSONTag):
        __slots__ = ('serializer',)
        key = ' od'
 
        def check(self, value):
            return isinstance(value, OrderedDict)
 
        def to_json(self, value):
            return [[k, self.serializer.tag(v)] for k, v in iteritems(value)]
 
        def to_python(self, value):
            return OrderedDict(value)
 
    app.session_interface.serializer.register(TagOrderedDict, index=0)
é)Ú annotationsN©Ú    b64decode)Ú    b64encode)Údatetime©ÚUUID©ÚMarkup©Ú    http_date©Ú
parse_dateé)Údumps)Úloadsc@sreZdZUdZdZdZded<dddœd    d
„Zd d d œdd„Zd d d œdd„Z    d d d œdd„Z
d d d œdd„Z dS)ÚJSONTagzDBase class for defining type tags for :class:`TaggedJSONSerializer`.©Ú
serializerNz
str | NoneÚkeyÚTaggedJSONSerializerÚNone)rÚreturncCs
||_dS)z)Create a tagger for the given serializer.Nr)Úselfr©rúEd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\flask/json/tag.pyÚ__init__DszJSONTag.__init__út.AnyÚbool©ÚvaluercCst‚dS)z6Check if the given value should be tagged by this tag.N©ÚNotImplementedError©rr rrrÚcheckHsz JSONTag.checkcCst‚dS)zfConvert the Python object to an object that is a valid JSON type.
        The tag will be added later.Nr!r#rrrÚto_jsonLszJSONTag.to_jsoncCst‚dS)zbConvert the JSON representation back to the correct type. The tag
        will already be removed.Nr!r#rrrÚ    to_pythonQszJSONTag.to_pythoncCs|j| |¡iS)zSConvert the value to a valid JSON type and add the tag structure
        around it.)rr%r#rrrÚtagVsz JSONTag.tag) Ú__name__Ú
__module__Ú __qualname__Ú__doc__Ú    __slots__rÚ__annotations__rr$r%r&r'rrrrr;s
 rc@sHeZdZdZdZdZdddœdd„Zdddœd    d
„Zdddœd d „Zd S)ÚTagDictz©Tag for 1-item dicts whose only key matches a registered tag.
 
    Internally, the dict key is suffixed with `__`, and the suffix is removed
    when deserializing.
    rz dirrrcCs*t|tƒo(t|ƒdko(tt|ƒƒ|jjkS)Né)Ú
isinstanceÚdictÚlenÚnextÚiterrÚtagsr#rrrr$fs
 
 
ÿýz TagDict.checkcCs&tt|ƒƒ}|›d|j ||¡iS)NÚ__)r3r4rr'©rr rrrrr%ms zTagDict.to_jsoncCs tt|ƒƒ}|dd…||iS)Néþÿÿÿ)r3r4r7rrrr&qs zTagDict.to_pythonN©    r(r)r*r+r,rr$r%r&rrrrr.\s r.c@s4eZdZdZdddœdd„Zdddœdd„ZeZd    S)
ÚPassDictrrrrcCs
t|tƒS©N)r0r1r#rrrr$yszPassDict.checkcs‡fdd„| ¡DƒS)Ncsi|]\}}|ˆj |¡“qSr©rr')Ú.0ÚkÚv©rrrÚ
<dictcomp>sz$PassDict.to_json.<locals>.<dictcomp>)Úitemsr#rr@rr%|szPassDict.to_jsonN©r(r)r*r,r$r%r'rrrrr:vsr:c@sDeZdZdZdZdddœdd„Zdddœdd    „Zdddœd
d „Zd S) ÚTagTuplerz trrrcCs
t|tƒSr;)r0Útupler#rrrr$ˆszTagTuple.checkcs‡fdd„|DƒS)Ncsg|]}ˆj |¡‘qSrr<©r=Úitemr@rrÚ
<listcomp>Œsz$TagTuple.to_json.<locals>.<listcomp>rr#rr@rr%‹szTagTuple.to_jsoncCst|ƒSr;)rEr#rrrr&ŽszTagTuple.to_pythonN©r(r)r*r,rr$r%r&rrrrrD„s
rDc@s4eZdZdZdddœdd„Zdddœdd„ZeZd    S)
ÚPassListrrrrcCs
t|tƒSr;)r0Úlistr#rrrr$•szPassList.checkcs‡fdd„|DƒS)Ncsg|]}ˆj |¡‘qSrr<rFr@rrrH™sz$PassList.to_json.<locals>.<listcomp>rr#rr@rr%˜szPassList.to_jsonNrCrrrrrJ’srJc@sDeZdZdZdZdddœdd„Zdddœdd    „Zdddœd
d „Zd S) ÚTagBytesrz brrrcCs
t|tƒSr;)r0Úbytesr#rrrr$¢szTagBytes.checkcCst|ƒ d¡S)NÚascii)rÚdecoder#rrrr%¥szTagBytes.to_jsoncCst|ƒSr;rr#rrrr&¨szTagBytes.to_pythonNrIrrrrrLžs
rLc@sHeZdZdZdZdZdddœdd„Zdddœd    d
„Zdddœd d „Zd S)Ú    TagMarkupzÈSerialize anything matching the :class:`~markupsafe.Markup` API by
    having a ``__html__`` method to the result of that method. Always
    deserializes to an instance of :class:`~markupsafe.Markup`.rz mrrrcCstt|ddƒƒS)NÚ__html__)ÚcallableÚgetattrr#rrrr$´szTagMarkup.checkcCs t| ¡ƒSr;)ÚstrrQr#rrrr%·szTagMarkup.to_jsoncCst|ƒSr;r    r#rrrr&ºszTagMarkup.to_pythonNr9rrrrrP¬s rPc@sDeZdZdZdZdddœdd„Zdddœdd    „Zdddœd
d „Zd S) ÚTagUUIDrz urrrcCs
t|tƒSr;)r0rr#rrrr$Âsz TagUUID.checkcCs|jSr;)Úhexr#rrrr%ÅszTagUUID.to_jsoncCst|ƒSr;rr#rrrr&ÈszTagUUID.to_pythonNrIrrrrrU¾s
rUc@sDeZdZdZdZdddœdd„Zdddœdd    „Zdddœd
d „Zd S) Ú TagDateTimerz drrrcCs
t|tƒSr;)r0rr#rrrr$ÐszTagDateTime.checkcCst|ƒSr;r r#rrrr%ÓszTagDateTime.to_jsoncCst|ƒSr;r r#rrrr&ÖszTagDateTime.to_pythonNrIrrrrrWÌs
rWc@sŒeZdZdZdZeeeee    e
e e gZ ddœdd„Zdd    d
d dd œd d„Zdddœdd„Zdddœdd„Zdddœdd„Zdddœdd„ZdS)ra|Serializer that uses a tag system to compactly represent objects that
    are not JSON types. Passed as the intermediate serializer to
    :class:`itsdangerous.Serializer`.
 
    The following extra types are supported:
 
    * :class:`dict`
    * :class:`tuple`
    * :class:`bytes`
    * :class:`~markupsafe.Markup`
    * :class:`~uuid.UUID`
    * :class:`~datetime.datetime`
    )r5Úorderr)rcCs&i|_g|_|jD]}| |¡qdSr;)r5rXÚ default_tagsÚregister)rÚclsrrrrøs
zTaggedJSONSerializer.__init__FNz type[JSONTag]rz
int | None)Ú    tag_classÚforceÚindexrcCsf||ƒ}|j}|dk    r>|s4||jkr4td|›dƒ‚||j|<|dkrT|j |¡n|j ||¡dS)aURegister a new tag with this serializer.
 
        :param tag_class: tag class to register. Will be instantiated with this
            serializer instance.
        :param force: overwrite an existing tag. If false (default), a
            :exc:`KeyError` is raised.
        :param index: index to insert the new tag in the tag order. Useful when
            the new tag is a special case of an existing tag. If ``None``
            (default), the tag is appended to the end of the order.
 
        :raise KeyError: if the tag key is already registered and ``force`` is
            not true.
        NzTag 'z' is already registered.)rr5ÚKeyErrorrXÚappendÚinsert)rr\r]r^r'rrrrrZÿs
zTaggedJSONSerializer.registerrzdict[str, t.Any]rcCs(|jD]}| |¡r| |¡Sq|S)z8Convert a value to a tagged representation if necessary.)rXr$r')rr r'rrrr' s
 
zTaggedJSONSerializer.tagcCs>t|ƒdkr|Stt|ƒƒ}||jkr*|S|j| ||¡S)z:Convert a tagged representation back to the original type.r/)r2r3r4r5r&r7rrrÚuntag(s   
zTaggedJSONSerializer.untagrTcCst| |¡ddS)z3Tag the value and dump it to a compact JSON string.)ú,ú:)Ú
separators)rr'r#rrrr4szTaggedJSONSerializer.dumpscCst||jdS)zALoad data from a JSON string and deserialized any tagged objects.)Ú object_hook)rrbr#rrrr8szTaggedJSONSerializer.loads)FN)r(r)r*r+r,r.r:rDrJrLrPrUrWrYrrZr'rbrrrrrrrÚs&ø 
ü! r)r+Ú
__future__rÚtypingÚtÚbase64rrrÚuuidrZ
markupsafer
Z werkzeug.httpr rÚjsonrrrr.r:rDrJrLrPrUrWrrrrrÚ<module>s**          !