ยปCore Development>Code coverage>Lib/json/encoder.py

Python code coverage for Lib/json/encoder.py

#countcontent
1n/a"""Implementation of JSONEncoder
2n/a"""
3n/aimport re
4n/a
5n/atry:
6n/a from _json import encode_basestring_ascii as c_encode_basestring_ascii
7n/aexcept ImportError:
8n/a c_encode_basestring_ascii = None
9n/atry:
10n/a from _json import encode_basestring as c_encode_basestring
11n/aexcept ImportError:
12n/a c_encode_basestring = None
13n/atry:
14n/a from _json import make_encoder as c_make_encoder
15n/aexcept ImportError:
16n/a c_make_encoder = None
17n/a
18n/aESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
19n/aESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
20n/aHAS_UTF8 = re.compile(b'[\x80-\xff]')
21n/aESCAPE_DCT = {
22n/a '\\': '\\\\',
23n/a '"': '\\"',
24n/a '\b': '\\b',
25n/a '\f': '\\f',
26n/a '\n': '\\n',
27n/a '\r': '\\r',
28n/a '\t': '\\t',
29n/a}
30n/afor i in range(0x20):
31n/a ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
32n/a #ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
33n/a
34n/aINFINITY = float('inf')
35n/a
36n/adef py_encode_basestring(s):
37n/a """Return a JSON representation of a Python string
38n/a
39n/a """
40n/a def replace(match):
41n/a return ESCAPE_DCT[match.group(0)]
42n/a return '"' + ESCAPE.sub(replace, s) + '"'
43n/a
44n/a
45n/aencode_basestring = (c_encode_basestring or py_encode_basestring)
46n/a
47n/a
48n/adef py_encode_basestring_ascii(s):
49n/a """Return an ASCII-only JSON representation of a Python string
50n/a
51n/a """
52n/a def replace(match):
53n/a s = match.group(0)
54n/a try:
55n/a return ESCAPE_DCT[s]
56n/a except KeyError:
57n/a n = ord(s)
58n/a if n < 0x10000:
59n/a return '\\u{0:04x}'.format(n)
60n/a #return '\\u%04x' % (n,)
61n/a else:
62n/a # surrogate pair
63n/a n -= 0x10000
64n/a s1 = 0xd800 | ((n >> 10) & 0x3ff)
65n/a s2 = 0xdc00 | (n & 0x3ff)
66n/a return '\\u{0:04x}\\u{1:04x}'.format(s1, s2)
67n/a return '"' + ESCAPE_ASCII.sub(replace, s) + '"'
68n/a
69n/a
70n/aencode_basestring_ascii = (
71n/a c_encode_basestring_ascii or py_encode_basestring_ascii)
72n/a
73n/aclass JSONEncoder(object):
74n/a """Extensible JSON <http://json.org> encoder for Python data structures.
75n/a
76n/a Supports the following objects and types by default:
77n/a
78n/a +-------------------+---------------+
79n/a | Python | JSON |
80n/a +===================+===============+
81n/a | dict | object |
82n/a +-------------------+---------------+
83n/a | list, tuple | array |
84n/a +-------------------+---------------+
85n/a | str | string |
86n/a +-------------------+---------------+
87n/a | int, float | number |
88n/a +-------------------+---------------+
89n/a | True | true |
90n/a +-------------------+---------------+
91n/a | False | false |
92n/a +-------------------+---------------+
93n/a | None | null |
94n/a +-------------------+---------------+
95n/a
96n/a To extend this to recognize other objects, subclass and implement a
97n/a ``.default()`` method with another method that returns a serializable
98n/a object for ``o`` if possible, otherwise it should call the superclass
99n/a implementation (to raise ``TypeError``).
100n/a
101n/a """
102n/a item_separator = ', '
103n/a key_separator = ': '
104n/a def __init__(self, *, skipkeys=False, ensure_ascii=True,
105n/a check_circular=True, allow_nan=True, sort_keys=False,
106n/a indent=None, separators=None, default=None):
107n/a """Constructor for JSONEncoder, with sensible defaults.
108n/a
109n/a If skipkeys is false, then it is a TypeError to attempt
110n/a encoding of keys that are not str, int, float or None. If
111n/a skipkeys is True, such items are simply skipped.
112n/a
113n/a If ensure_ascii is true, the output is guaranteed to be str
114n/a objects with all incoming non-ASCII characters escaped. If
115n/a ensure_ascii is false, the output can contain non-ASCII characters.
116n/a
117n/a If check_circular is true, then lists, dicts, and custom encoded
118n/a objects will be checked for circular references during encoding to
119n/a prevent an infinite recursion (which would cause an OverflowError).
120n/a Otherwise, no such check takes place.
121n/a
122n/a If allow_nan is true, then NaN, Infinity, and -Infinity will be
123n/a encoded as such. This behavior is not JSON specification compliant,
124n/a but is consistent with most JavaScript based encoders and decoders.
125n/a Otherwise, it will be a ValueError to encode such floats.
126n/a
127n/a If sort_keys is true, then the output of dictionaries will be
128n/a sorted by key; this is useful for regression tests to ensure
129n/a that JSON serializations can be compared on a day-to-day basis.
130n/a
131n/a If indent is a non-negative integer, then JSON array
132n/a elements and object members will be pretty-printed with that
133n/a indent level. An indent level of 0 will only insert newlines.
134n/a None is the most compact representation.
135n/a
136n/a If specified, separators should be an (item_separator, key_separator)
137n/a tuple. The default is (', ', ': ') if *indent* is ``None`` and
138n/a (',', ': ') otherwise. To get the most compact JSON representation,
139n/a you should specify (',', ':') to eliminate whitespace.
140n/a
141n/a If specified, default is a function that gets called for objects
142n/a that can't otherwise be serialized. It should return a JSON encodable
143n/a version of the object or raise a ``TypeError``.
144n/a
145n/a """
146n/a
147n/a self.skipkeys = skipkeys
148n/a self.ensure_ascii = ensure_ascii
149n/a self.check_circular = check_circular
150n/a self.allow_nan = allow_nan
151n/a self.sort_keys = sort_keys
152n/a self.indent = indent
153n/a if separators is not None:
154n/a self.item_separator, self.key_separator = separators
155n/a elif indent is not None:
156n/a self.item_separator = ','
157n/a if default is not None:
158n/a self.default = default
159n/a
160n/a def default(self, o):
161n/a """Implement this method in a subclass such that it returns
162n/a a serializable object for ``o``, or calls the base implementation
163n/a (to raise a ``TypeError``).
164n/a
165n/a For example, to support arbitrary iterators, you could
166n/a implement default like this::
167n/a
168n/a def default(self, o):
169n/a try:
170n/a iterable = iter(o)
171n/a except TypeError:
172n/a pass
173n/a else:
174n/a return list(iterable)
175n/a # Let the base class default method raise the TypeError
176n/a return JSONEncoder.default(self, o)
177n/a
178n/a """
179n/a raise TypeError("Object of type '%s' is not JSON serializable" %
180n/a o.__class__.__name__)
181n/a
182n/a def encode(self, o):
183n/a """Return a JSON string representation of a Python data structure.
184n/a
185n/a >>> from json.encoder import JSONEncoder
186n/a >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
187n/a '{"foo": ["bar", "baz"]}'
188n/a
189n/a """
190n/a # This is for extremely simple cases and benchmarks.
191n/a if isinstance(o, str):
192n/a if self.ensure_ascii:
193n/a return encode_basestring_ascii(o)
194n/a else:
195n/a return encode_basestring(o)
196n/a # This doesn't pass the iterator directly to ''.join() because the
197n/a # exceptions aren't as detailed. The list call should be roughly
198n/a # equivalent to the PySequence_Fast that ''.join() would do.
199n/a chunks = self.iterencode(o, _one_shot=True)
200n/a if not isinstance(chunks, (list, tuple)):
201n/a chunks = list(chunks)
202n/a return ''.join(chunks)
203n/a
204n/a def iterencode(self, o, _one_shot=False):
205n/a """Encode the given object and yield each string
206n/a representation as available.
207n/a
208n/a For example::
209n/a
210n/a for chunk in JSONEncoder().iterencode(bigobject):
211n/a mysocket.write(chunk)
212n/a
213n/a """
214n/a if self.check_circular:
215n/a markers = {}
216n/a else:
217n/a markers = None
218n/a if self.ensure_ascii:
219n/a _encoder = encode_basestring_ascii
220n/a else:
221n/a _encoder = encode_basestring
222n/a
223n/a def floatstr(o, allow_nan=self.allow_nan,
224n/a _repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY):
225n/a # Check for specials. Note that this type of test is processor
226n/a # and/or platform-specific, so do tests which don't depend on the
227n/a # internals.
228n/a
229n/a if o != o:
230n/a text = 'NaN'
231n/a elif o == _inf:
232n/a text = 'Infinity'
233n/a elif o == _neginf:
234n/a text = '-Infinity'
235n/a else:
236n/a return _repr(o)
237n/a
238n/a if not allow_nan:
239n/a raise ValueError(
240n/a "Out of range float values are not JSON compliant: " +
241n/a repr(o))
242n/a
243n/a return text
244n/a
245n/a
246n/a if (_one_shot and c_make_encoder is not None
247n/a and self.indent is None):
248n/a _iterencode = c_make_encoder(
249n/a markers, self.default, _encoder, self.indent,
250n/a self.key_separator, self.item_separator, self.sort_keys,
251n/a self.skipkeys, self.allow_nan)
252n/a else:
253n/a _iterencode = _make_iterencode(
254n/a markers, self.default, _encoder, self.indent, floatstr,
255n/a self.key_separator, self.item_separator, self.sort_keys,
256n/a self.skipkeys, _one_shot)
257n/a return _iterencode(o, 0)
258n/a
259n/adef _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
260n/a _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
261n/a ## HACK: hand-optimized bytecode; turn globals into locals
262n/a ValueError=ValueError,
263n/a dict=dict,
264n/a float=float,
265n/a id=id,
266n/a int=int,
267n/a isinstance=isinstance,
268n/a list=list,
269n/a str=str,
270n/a tuple=tuple,
271n/a _intstr=int.__str__,
272n/a ):
273n/a
274n/a if _indent is not None and not isinstance(_indent, str):
275n/a _indent = ' ' * _indent
276n/a
277n/a def _iterencode_list(lst, _current_indent_level):
278n/a if not lst:
279n/a yield '[]'
280n/a return
281n/a if markers is not None:
282n/a markerid = id(lst)
283n/a if markerid in markers:
284n/a raise ValueError("Circular reference detected")
285n/a markers[markerid] = lst
286n/a buf = '['
287n/a if _indent is not None:
288n/a _current_indent_level += 1
289n/a newline_indent = '\n' + _indent * _current_indent_level
290n/a separator = _item_separator + newline_indent
291n/a buf += newline_indent
292n/a else:
293n/a newline_indent = None
294n/a separator = _item_separator
295n/a first = True
296n/a for value in lst:
297n/a if first:
298n/a first = False
299n/a else:
300n/a buf = separator
301n/a if isinstance(value, str):
302n/a yield buf + _encoder(value)
303n/a elif value is None:
304n/a yield buf + 'null'
305n/a elif value is True:
306n/a yield buf + 'true'
307n/a elif value is False:
308n/a yield buf + 'false'
309n/a elif isinstance(value, int):
310n/a # Subclasses of int/float may override __str__, but we still
311n/a # want to encode them as integers/floats in JSON. One example
312n/a # within the standard library is IntEnum.
313n/a yield buf + _intstr(value)
314n/a elif isinstance(value, float):
315n/a # see comment above for int
316n/a yield buf + _floatstr(value)
317n/a else:
318n/a yield buf
319n/a if isinstance(value, (list, tuple)):
320n/a chunks = _iterencode_list(value, _current_indent_level)
321n/a elif isinstance(value, dict):
322n/a chunks = _iterencode_dict(value, _current_indent_level)
323n/a else:
324n/a chunks = _iterencode(value, _current_indent_level)
325n/a yield from chunks
326n/a if newline_indent is not None:
327n/a _current_indent_level -= 1
328n/a yield '\n' + _indent * _current_indent_level
329n/a yield ']'
330n/a if markers is not None:
331n/a del markers[markerid]
332n/a
333n/a def _iterencode_dict(dct, _current_indent_level):
334n/a if not dct:
335n/a yield '{}'
336n/a return
337n/a if markers is not None:
338n/a markerid = id(dct)
339n/a if markerid in markers:
340n/a raise ValueError("Circular reference detected")
341n/a markers[markerid] = dct
342n/a yield '{'
343n/a if _indent is not None:
344n/a _current_indent_level += 1
345n/a newline_indent = '\n' + _indent * _current_indent_level
346n/a item_separator = _item_separator + newline_indent
347n/a yield newline_indent
348n/a else:
349n/a newline_indent = None
350n/a item_separator = _item_separator
351n/a first = True
352n/a if _sort_keys:
353n/a items = sorted(dct.items(), key=lambda kv: kv[0])
354n/a else:
355n/a items = dct.items()
356n/a for key, value in items:
357n/a if isinstance(key, str):
358n/a pass
359n/a # JavaScript is weakly typed for these, so it makes sense to
360n/a # also allow them. Many encoders seem to do something like this.
361n/a elif isinstance(key, float):
362n/a # see comment for int/float in _make_iterencode
363n/a key = _floatstr(key)
364n/a elif key is True:
365n/a key = 'true'
366n/a elif key is False:
367n/a key = 'false'
368n/a elif key is None:
369n/a key = 'null'
370n/a elif isinstance(key, int):
371n/a # see comment for int/float in _make_iterencode
372n/a key = _intstr(key)
373n/a elif _skipkeys:
374n/a continue
375n/a else:
376n/a raise TypeError("key " + repr(key) + " is not a string")
377n/a if first:
378n/a first = False
379n/a else:
380n/a yield item_separator
381n/a yield _encoder(key)
382n/a yield _key_separator
383n/a if isinstance(value, str):
384n/a yield _encoder(value)
385n/a elif value is None:
386n/a yield 'null'
387n/a elif value is True:
388n/a yield 'true'
389n/a elif value is False:
390n/a yield 'false'
391n/a elif isinstance(value, int):
392n/a # see comment for int/float in _make_iterencode
393n/a yield _intstr(value)
394n/a elif isinstance(value, float):
395n/a # see comment for int/float in _make_iterencode
396n/a yield _floatstr(value)
397n/a else:
398n/a if isinstance(value, (list, tuple)):
399n/a chunks = _iterencode_list(value, _current_indent_level)
400n/a elif isinstance(value, dict):
401n/a chunks = _iterencode_dict(value, _current_indent_level)
402n/a else:
403n/a chunks = _iterencode(value, _current_indent_level)
404n/a yield from chunks
405n/a if newline_indent is not None:
406n/a _current_indent_level -= 1
407n/a yield '\n' + _indent * _current_indent_level
408n/a yield '}'
409n/a if markers is not None:
410n/a del markers[markerid]
411n/a
412n/a def _iterencode(o, _current_indent_level):
413n/a if isinstance(o, str):
414n/a yield _encoder(o)
415n/a elif o is None:
416n/a yield 'null'
417n/a elif o is True:
418n/a yield 'true'
419n/a elif o is False:
420n/a yield 'false'
421n/a elif isinstance(o, int):
422n/a # see comment for int/float in _make_iterencode
423n/a yield _intstr(o)
424n/a elif isinstance(o, float):
425n/a # see comment for int/float in _make_iterencode
426n/a yield _floatstr(o)
427n/a elif isinstance(o, (list, tuple)):
428n/a yield from _iterencode_list(o, _current_indent_level)
429n/a elif isinstance(o, dict):
430n/a yield from _iterencode_dict(o, _current_indent_level)
431n/a else:
432n/a if markers is not None:
433n/a markerid = id(o)
434n/a if markerid in markers:
435n/a raise ValueError("Circular reference detected")
436n/a markers[markerid] = o
437n/a o = _default(o)
438n/a yield from _iterencode(o, _current_indent_level)
439n/a if markers is not None:
440n/a del markers[markerid]
441n/a return _iterencode