From 3a4d3a568a82adc9ee40b4cbf57bdcd739adc235 Mon Sep 17 00:00:00 2001 From: Matt Trentini Date: Mon, 2 May 2022 13:50:52 +1000 Subject: [PATCH] Remove json library (it's a built-in) --- python-stdlib/json/json/__init__.py | 416 ------------------------- python-stdlib/json/json/decoder.py | 381 ----------------------- python-stdlib/json/json/encoder.py | 461 ---------------------------- python-stdlib/json/json/scanner.py | 77 ----- python-stdlib/json/json/tool.py | 40 --- python-stdlib/json/setup.py | 18 -- python-stdlib/json/test_json.py | 13 - 7 files changed, 1406 deletions(-) delete mode 100644 python-stdlib/json/json/__init__.py delete mode 100644 python-stdlib/json/json/decoder.py delete mode 100644 python-stdlib/json/json/encoder.py delete mode 100644 python-stdlib/json/json/scanner.py delete mode 100644 python-stdlib/json/json/tool.py delete mode 100644 python-stdlib/json/setup.py delete mode 100644 python-stdlib/json/test_json.py diff --git a/python-stdlib/json/json/__init__.py b/python-stdlib/json/json/__init__.py deleted file mode 100644 index eb9493edb..000000000 --- a/python-stdlib/json/json/__init__.py +++ /dev/null @@ -1,416 +0,0 @@ -r"""JSON (JavaScript Object Notation) is a subset of -JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data -interchange format. - -:mod:`json` exposes an API familiar to users of the standard library -:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained -version of the :mod:`json` library contained in Python 2.6, but maintains -compatibility with Python 2.4 and Python 2.5 and (currently) has -significant performance advantages, even without using the optional C -extension for speedups. - -Encoding basic Python object hierarchies:: - - >>> import json - >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) - '["foo", {"bar": ["baz", null, 1.0, 2]}]' - >>> print(json.dumps("\"foo\bar")) - "\"foo\bar" - >>> print(json.dumps('\u1234')) - "\u1234" - >>> print(json.dumps('\\')) - "\\" - >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) - {"a": 0, "b": 0, "c": 0} - >>> from io import StringIO - >>> io = StringIO() - >>> json.dump(['streaming API'], io) - >>> io.getvalue() - '["streaming API"]' - -Compact encoding:: - - >>> import json - >>> from collections import OrderedDict - >>> mydict = OrderedDict([('4', 5), ('6', 7)]) - >>> json.dumps([1,2,3,mydict], separators=(',', ':')) - '[1,2,3,{"4":5,"6":7}]' - -Pretty printing:: - - >>> import json - >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, - ... indent=4, separators=(',', ': '))) - { - "4": 5, - "6": 7 - } - -Decoding JSON:: - - >>> import json - >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] - >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj - True - >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' - True - >>> from io import StringIO - >>> io = StringIO('["streaming API"]') - >>> json.load(io)[0] == 'streaming API' - True - -Specializing JSON object decoding:: - - >>> import json - >>> def as_complex(dct): - ... if '__complex__' in dct: - ... return complex(dct['real'], dct['imag']) - ... return dct - ... - >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', - ... object_hook=as_complex) - (1+2j) - >>> from decimal import Decimal - >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') - True - -Specializing JSON object encoding:: - - >>> import json - >>> def encode_complex(obj): - ... if isinstance(obj, complex): - ... return [obj.real, obj.imag] - ... raise TypeError(repr(o) + " is not JSON serializable") - ... - >>> json.dumps(2 + 1j, default=encode_complex) - '[2.0, 1.0]' - >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) - '[2.0, 1.0]' - >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) - '[2.0, 1.0]' - - -Using json.tool from the shell to validate and pretty-print:: - - $ echo '{"json":"obj"}' | python -m json.tool - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -m json.tool - Expecting property name enclosed in double quotes: line 1 column 3 (char 2) -""" -__version__ = "2.0.9" -__all__ = [ - "dump", - "dumps", - "load", - "loads", - "JSONDecoder", - "JSONEncoder", -] - -__author__ = "Bob Ippolito " - -from .decoder import JSONDecoder -from .encoder import JSONEncoder - -_default_encoder = JSONEncoder( - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - indent=None, - separators=None, - default=None, -) - - -def dump( - obj, - fp, - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - cls=None, - indent=None, - separators=None, - default=None, - sort_keys=False, - **kw -): - """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a - ``.write()``-supporting file-like object). - - If ``skipkeys`` is true then ``dict`` keys that are not basic types - (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped - instead of raising a ``TypeError``. - - If ``ensure_ascii`` is false, then the strings written to ``fp`` can - contain non-ASCII characters if they appear in strings contained in - ``obj``. Otherwise, all such characters are escaped in JSON strings. - - If ``check_circular`` is false, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). - - If ``allow_nan`` is false, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) - in strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and - object members will be pretty-printed with that indent level. An indent - level of 0 will only insert newlines. ``None`` is the most compact - representation. Since the default item separator is ``', '``, the - output might include trailing whitespace when ``indent`` is specified. - You can use ``separators=(',', ': ')`` to avoid this. - - If ``separators`` is an ``(item_separator, dict_separator)`` tuple - then it will be used instead of the default ``(', ', ': ')`` separators. - ``(',', ':')`` is the most compact JSON representation. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - If *sort_keys* is ``True`` (default: ``False``), then the output of - dictionaries will be sorted by key. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. - - """ - # cached encoder - if ( - not skipkeys - and ensure_ascii - and check_circular - and allow_nan - and cls is None - and indent is None - and separators is None - and default is None - and not sort_keys - and not kw - ): - iterable = _default_encoder.iterencode(obj) - else: - if cls is None: - cls = JSONEncoder - iterable = cls( - skipkeys=skipkeys, - ensure_ascii=ensure_ascii, - check_circular=check_circular, - allow_nan=allow_nan, - indent=indent, - separators=separators, - default=default, - sort_keys=sort_keys, - **kw - ).iterencode(obj) - # could accelerate with writelines in some versions of Python, at - # a debuggability cost - for chunk in iterable: - fp.write(chunk) - - -def dumps( - obj, - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - cls=None, - indent=None, - separators=None, - default=None, - sort_keys=False, - **kw -): - """Serialize ``obj`` to a JSON formatted ``str``. - - If ``skipkeys`` is false then ``dict`` keys that are not basic types - (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped - instead of raising a ``TypeError``. - - If ``ensure_ascii`` is false, then the return value can contain non-ASCII - characters if they appear in strings contained in ``obj``. Otherwise, all - such characters are escaped in JSON strings. - - If ``check_circular`` is false, then the circular reference check - for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). - - If ``allow_nan`` is false, then it will be a ``ValueError`` to - serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in - strict compliance of the JSON specification, instead of using the - JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). - - If ``indent`` is a non-negative integer, then JSON array elements and - object members will be pretty-printed with that indent level. An indent - level of 0 will only insert newlines. ``None`` is the most compact - representation. Since the default item separator is ``', '``, the - output might include trailing whitespace when ``indent`` is specified. - You can use ``separators=(',', ': ')`` to avoid this. - - If ``separators`` is an ``(item_separator, dict_separator)`` tuple - then it will be used instead of the default ``(', ', ': ')`` separators. - ``(',', ':')`` is the most compact JSON representation. - - ``default(obj)`` is a function that should return a serializable version - of obj or raise TypeError. The default simply raises TypeError. - - If *sort_keys* is ``True`` (default: ``False``), then the output of - dictionaries will be sorted by key. - - To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the - ``.default()`` method to serialize additional types), specify it with - the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. - - """ - # cached encoder - if ( - not skipkeys - and ensure_ascii - and check_circular - and allow_nan - and cls is None - and indent is None - and separators is None - and default is None - and not sort_keys - and not kw - ): - return _default_encoder.encode(obj) - if cls is None: - cls = JSONEncoder - return cls( - skipkeys=skipkeys, - ensure_ascii=ensure_ascii, - check_circular=check_circular, - allow_nan=allow_nan, - indent=indent, - separators=separators, - default=default, - sort_keys=sort_keys, - **kw - ).encode(obj) - - -_default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) - - -def load( - fp, - cls=None, - object_hook=None, - parse_float=None, - parse_int=None, - parse_constant=None, - object_pairs_hook=None, - **kw -): - """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing - a JSON document) to a Python object. - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - ``object_pairs_hook`` is an optional function that will be called with the - result of any object literal decoded with an ordered list of pairs. The - return value of ``object_pairs_hook`` will be used instead of the ``dict``. - This feature can be used to implement custom decoders that rely on the - order that the key and value pairs are decoded (for example, - collections.OrderedDict will remember the order of insertion). If - ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg; otherwise ``JSONDecoder`` is used. - - """ - return loads( - fp.read(), - cls=cls, - object_hook=object_hook, - parse_float=parse_float, - parse_int=parse_int, - parse_constant=parse_constant, - object_pairs_hook=object_pairs_hook, - **kw - ) - - -def loads( - s, - encoding=None, - cls=None, - object_hook=None, - parse_float=None, - parse_int=None, - parse_constant=None, - object_pairs_hook=None, - **kw -): - """Deserialize ``s`` (a ``str`` instance containing a JSON - document) to a Python object. - - ``object_hook`` is an optional function that will be called with the - result of any object literal decode (a ``dict``). The return value of - ``object_hook`` will be used instead of the ``dict``. This feature - can be used to implement custom decoders (e.g. JSON-RPC class hinting). - - ``object_pairs_hook`` is an optional function that will be called with the - result of any object literal decoded with an ordered list of pairs. The - return value of ``object_pairs_hook`` will be used instead of the ``dict``. - This feature can be used to implement custom decoders that rely on the - order that the key and value pairs are decoded (for example, - collections.OrderedDict will remember the order of insertion). If - ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN, null, true, false. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` - kwarg; otherwise ``JSONDecoder`` is used. - - The ``encoding`` argument is ignored and deprecated. - - """ - if ( - cls is None - and object_hook is None - and parse_int is None - and parse_float is None - and parse_constant is None - and object_pairs_hook is None - and not kw - ): - return _default_decoder.decode(s) - if cls is None: - cls = JSONDecoder - if object_hook is not None: - kw["object_hook"] = object_hook - if object_pairs_hook is not None: - kw["object_pairs_hook"] = object_pairs_hook - if parse_float is not None: - kw["parse_float"] = parse_float - if parse_int is not None: - kw["parse_int"] = parse_int - if parse_constant is not None: - kw["parse_constant"] = parse_constant - return cls(**kw).decode(s) diff --git a/python-stdlib/json/json/decoder.py b/python-stdlib/json/json/decoder.py deleted file mode 100644 index a232d6dca..000000000 --- a/python-stdlib/json/json/decoder.py +++ /dev/null @@ -1,381 +0,0 @@ -"""Implementation of JSONDecoder -""" -import re -import sys - -from json import scanner - -try: - from _json import scanstring as c_scanstring -except ImportError: - c_scanstring = None - -__all__ = ["JSONDecoder"] - -FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL - -NaN, PosInf, NegInf = float("nan"), float("inf"), float("-inf") - - -def linecol(doc, pos): - if isinstance(doc, bytes): - newline = b"\n" - else: - newline = "\n" - lineno = doc.count(newline, 0, pos) + 1 - if lineno == 1: - colno = pos + 1 - else: - colno = pos - doc.rindex(newline, 0, pos) - return lineno, colno - - -def errmsg(msg, doc, pos, end=None): - # Note that this function is called from _json - lineno, colno = linecol(doc, pos) - if end is None: - fmt = "{0}: line {1} column {2} (char {3})" - return fmt.format(msg, lineno, colno, pos) - # fmt = '%s: line %d column %d (char %d)' - # return fmt % (msg, lineno, colno, pos) - endlineno, endcolno = linecol(doc, end) - fmt = "{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})" - return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end) - # fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' - # return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) - - -_CONSTANTS = { - "-Infinity": NegInf, - "Infinity": PosInf, - "NaN": NaN, -} - - -STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) -BACKSLASH = { - '"': '"', - "\\": "\\", - "/": "/", - "b": "\b", - "f": "\f", - "n": "\n", - "r": "\r", - "t": "\t", -} - - -def py_scanstring(s, end, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match): - """Scan the string s for a JSON string. End is the index of the - character in s after the quote that started the JSON string. - Unescapes all valid JSON string escape sequences and raises ValueError - on attempt to decode an invalid string. If strict is False then literal - control characters are allowed in the string. - - Returns a tuple of the decoded string and the index of the character in s - after the end quote.""" - chunks = [] - _append = chunks.append - begin = end - 1 - while 1: - chunk = _m(s, end) - if chunk is None: - raise ValueError(errmsg("Unterminated string starting at", s, begin)) - end = chunk.end() - content, terminator = chunk.groups() - # Content is contains zero or more unescaped string characters - if content: - _append(content) - # Terminator is the end of string, a literal control character, - # or a backslash denoting that an escape sequence follows - if terminator == '"': - break - elif terminator != "\\": - if strict: - # msg = "Invalid control character %r at" % (terminator,) - msg = "Invalid control character {0!r} at".format(terminator) - raise ValueError(errmsg(msg, s, end)) - else: - _append(terminator) - continue - try: - esc = s[end] - except IndexError: - raise ValueError(errmsg("Unterminated string starting at", s, begin)) - # If not a unicode escape sequence, must be in the lookup table - if esc != "u": - try: - char = _b[esc] - except KeyError: - msg = "Invalid \\escape: {0!r}".format(esc) - raise ValueError(errmsg(msg, s, end)) - end += 1 - else: - esc = s[end + 1 : end + 5] - next_end = end + 5 - if len(esc) != 4: - msg = "Invalid \\uXXXX escape" - raise ValueError(errmsg(msg, s, end)) - uni = int(esc, 16) - if 0xD800 <= uni <= 0xDBFF: - msg = "Invalid \\uXXXX\\uXXXX surrogate pair" - if not s[end + 5 : end + 7] == "\\u": - raise ValueError(errmsg(msg, s, end)) - esc2 = s[end + 7 : end + 11] - if len(esc2) != 4: - raise ValueError(errmsg(msg, s, end)) - uni2 = int(esc2, 16) - uni = 0x10000 + (((uni - 0xD800) << 10) | (uni2 - 0xDC00)) - next_end += 6 - char = chr(uni) - - end = next_end - _append(char) - return "".join(chunks), end - - -# Use speedup if available -scanstring = c_scanstring or py_scanstring - -WHITESPACE = re.compile(r"[ \t\n\r]*", FLAGS) -WHITESPACE_STR = " \t\n\r" - - -def JSONObject( - s_and_end, - strict, - scan_once, - object_hook, - object_pairs_hook, - memo=None, - _w=WHITESPACE.match, - _ws=WHITESPACE_STR, -): - s, end = s_and_end - pairs = [] - pairs_append = pairs.append - # Backwards compatibility - if memo is None: - memo = {} - memo_get = memo.setdefault - # Use a slice to prevent IndexError from being raised, the following - # check will raise a more specific ValueError if the string is empty - nextchar = s[end : end + 1] - # Normally we expect nextchar == '"' - if nextchar != '"': - if nextchar in _ws: - end = _w(s, end).end() - nextchar = s[end : end + 1] - # Trivial empty object - if nextchar == "}": - if object_pairs_hook is not None: - result = object_pairs_hook(pairs) - return result, end + 1 - pairs = {} - if object_hook is not None: - pairs = object_hook(pairs) - return pairs, end + 1 - elif nextchar != '"': - raise ValueError(errmsg("Expecting property name enclosed in double quotes", s, end)) - end += 1 - while True: - key, end = scanstring(s, end, strict) - key = memo_get(key, key) - # To skip some function call overhead we optimize the fast paths where - # the JSON key separator is ": " or just ":". - if s[end : end + 1] != ":": - end = _w(s, end).end() - if s[end : end + 1] != ":": - raise ValueError(errmsg("Expecting ':' delimiter", s, end)) - end += 1 - - try: - if s[end] in _ws: - end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() - except IndexError: - pass - - try: - value, end = scan_once(s, end) - except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) - pairs_append((key, value)) - try: - nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end] - except IndexError: - nextchar = "" - end += 1 - - if nextchar == "}": - break - elif nextchar != ",": - raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) - end = _w(s, end).end() - nextchar = s[end : end + 1] - end += 1 - if nextchar != '"': - raise ValueError( - errmsg("Expecting property name enclosed in double quotes", s, end - 1) - ) - if object_pairs_hook is not None: - result = object_pairs_hook(pairs) - return result, end - pairs = dict(pairs) - if object_hook is not None: - pairs = object_hook(pairs) - return pairs, end - - -def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): - s, end = s_and_end - values = [] - nextchar = s[end : end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end : end + 1] - # Look-ahead for trivial empty array - if nextchar == "]": - return values, end + 1 - _append = values.append - while True: - try: - value, end = scan_once(s, end) - except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) - _append(value) - nextchar = s[end : end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() - nextchar = s[end : end + 1] - end += 1 - if nextchar == "]": - break - elif nextchar != ",": - raise ValueError(errmsg("Expecting ',' delimiter", s, end)) - try: - if s[end] in _ws: - end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() - except IndexError: - pass - - return values, end - - -class JSONDecoder(object): - """Simple JSON decoder - - Performs the following translations in decoding by default: - - +---------------+-------------------+ - | JSON | Python | - +===============+===================+ - | object | dict | - +---------------+-------------------+ - | array | list | - +---------------+-------------------+ - | string | str | - +---------------+-------------------+ - | number (int) | int | - +---------------+-------------------+ - | number (real) | float | - +---------------+-------------------+ - | true | True | - +---------------+-------------------+ - | false | False | - +---------------+-------------------+ - | null | None | - +---------------+-------------------+ - - It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as - their corresponding ``float`` values, which is outside the JSON spec. - - """ - - def __init__( - self, - object_hook=None, - parse_float=None, - parse_int=None, - parse_constant=None, - strict=True, - object_pairs_hook=None, - ): - """``object_hook``, if specified, will be called with the result - of every JSON object decoded and its return value will be used in - place of the given ``dict``. This can be used to provide custom - deserializations (e.g. to support JSON-RPC class hinting). - - ``object_pairs_hook``, if specified will be called with the result of - every JSON object decoded with an ordered list of pairs. The return - value of ``object_pairs_hook`` will be used instead of the ``dict``. - This feature can be used to implement custom decoders that rely on the - order that the key and value pairs are decoded (for example, - collections.OrderedDict will remember the order of insertion). If - ``object_hook`` is also defined, the ``object_pairs_hook`` takes - priority. - - ``parse_float``, if specified, will be called with the string - of every JSON float to be decoded. By default this is equivalent to - float(num_str). This can be used to use another datatype or parser - for JSON floats (e.g. decimal.Decimal). - - ``parse_int``, if specified, will be called with the string - of every JSON int to be decoded. By default this is equivalent to - int(num_str). This can be used to use another datatype or parser - for JSON integers (e.g. float). - - ``parse_constant``, if specified, will be called with one of the - following strings: -Infinity, Infinity, NaN. - This can be used to raise an exception if invalid JSON numbers - are encountered. - - If ``strict`` is false (true is the default), then control - characters will be allowed inside strings. Control characters in - this context are those with character codes in the 0-31 range, - including ``'\\t'`` (tab), ``'\\n'``, ``'\\r'`` and ``'\\0'``. - - """ - self.object_hook = object_hook - self.parse_float = parse_float or float - self.parse_int = parse_int or int - self.parse_constant = parse_constant or _CONSTANTS.__getitem__ - self.strict = strict - self.object_pairs_hook = object_pairs_hook - self.parse_object = JSONObject - self.parse_array = JSONArray - self.parse_string = scanstring - self.memo = {} - self.scan_once = scanner.make_scanner(self) - - def decode(self, s, _w=WHITESPACE.match): - """Return the Python representation of ``s`` (a ``str`` instance - containing a JSON document). - - """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() - if end != len(s): - raise ValueError(errmsg("Extra data", s, end, len(s))) - return obj - - def raw_decode(self, s, idx=0): - """Decode a JSON document from ``s`` (a ``str`` beginning with - a JSON document) and return a 2-tuple of the Python - representation and the index in ``s`` where the document ended. - - This can be used to decode a JSON document from a string that may - have extraneous data at the end. - - """ - try: - obj, end = self.scan_once(s, idx) - except StopIteration: - raise ValueError("No JSON object could be decoded") - return obj, end diff --git a/python-stdlib/json/json/encoder.py b/python-stdlib/json/json/encoder.py deleted file mode 100644 index ba798a0b0..000000000 --- a/python-stdlib/json/json/encoder.py +++ /dev/null @@ -1,461 +0,0 @@ -"""Implementation of JSONEncoder -""" -import re - -try: - from _json import encode_basestring_ascii as c_encode_basestring_ascii -except ImportError: - c_encode_basestring_ascii = None -try: - from _json import make_encoder as c_make_encoder -except ImportError: - c_make_encoder = None - -ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') -ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') -HAS_UTF8 = re.compile(b"[\x80-\xff]") -ESCAPE_DCT = { - "\\": "\\\\", - '"': '\\"', - "\b": "\\b", - "\f": "\\f", - "\n": "\\n", - "\r": "\\r", - "\t": "\\t", -} -for i in range(0x20): - ESCAPE_DCT.setdefault(chr(i), "\\u{0:04x}".format(i)) - # ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) - -INFINITY = float("inf") -FLOAT_REPR = repr - - -def encode_basestring(s): - """Return a JSON representation of a Python string""" - - def replace(match): - return ESCAPE_DCT[match.group(0)] - - return '"' + ESCAPE.sub(replace, s) + '"' - - -def py_encode_basestring_ascii(s): - """Return an ASCII-only JSON representation of a Python string""" - - def replace(match): - s = match.group(0) - try: - return ESCAPE_DCT[s] - except KeyError: - n = ord(s) - if n < 0x10000: - return "\\u{0:04x}".format(n) - # return '\\u%04x' % (n,) - else: - # surrogate pair - n -= 0x10000 - s1 = 0xD800 | ((n >> 10) & 0x3FF) - s2 = 0xDC00 | (n & 0x3FF) - return "\\u{0:04x}\\u{1:04x}".format(s1, s2) - - return '"' + ESCAPE_ASCII.sub(replace, s) + '"' - - -encode_basestring_ascii = c_encode_basestring_ascii or py_encode_basestring_ascii - - -class JSONEncoder(object): - """Extensible JSON encoder for Python data structures. - - Supports the following objects and types by default: - - +-------------------+---------------+ - | Python | JSON | - +===================+===============+ - | dict | object | - +-------------------+---------------+ - | list, tuple | array | - +-------------------+---------------+ - | str | string | - +-------------------+---------------+ - | int, float | number | - +-------------------+---------------+ - | True | true | - +-------------------+---------------+ - | False | false | - +-------------------+---------------+ - | None | null | - +-------------------+---------------+ - - To extend this to recognize other objects, subclass and implement a - ``.default()`` method with another method that returns a serializable - object for ``o`` if possible, otherwise it should call the superclass - implementation (to raise ``TypeError``). - - """ - - item_separator = ", " - key_separator = ": " - - def __init__( - self, - skipkeys=False, - ensure_ascii=True, - check_circular=True, - allow_nan=True, - sort_keys=False, - indent=None, - separators=None, - default=None, - ): - """Constructor for JSONEncoder, with sensible defaults. - - If skipkeys is false, then it is a TypeError to attempt - encoding of keys that are not str, int, float or None. If - skipkeys is True, such items are simply skipped. - - If ensure_ascii is true, the output is guaranteed to be str - objects with all incoming non-ASCII characters escaped. If - ensure_ascii is false, the output can contain non-ASCII characters. - - If check_circular is true, then lists, dicts, and custom encoded - objects will be checked for circular references during encoding to - prevent an infinite recursion (which would cause an OverflowError). - Otherwise, no such check takes place. - - If allow_nan is true, then NaN, Infinity, and -Infinity will be - encoded as such. This behavior is not JSON specification compliant, - but is consistent with most JavaScript based encoders and decoders. - Otherwise, it will be a ValueError to encode such floats. - - If sort_keys is true, then the output of dictionaries will be - sorted by key; this is useful for regression tests to ensure - that JSON serializations can be compared on a day-to-day basis. - - If indent is a non-negative integer, then JSON array - elements and object members will be pretty-printed with that - indent level. An indent level of 0 will only insert newlines. - None is the most compact representation. Since the default - item separator is ', ', the output might include trailing - whitespace when indent is specified. You can use - separators=(',', ': ') to avoid this. - - If specified, separators should be a (item_separator, key_separator) - tuple. The default is (', ', ': '). To get the most compact JSON - representation you should specify (',', ':') to eliminate whitespace. - - If specified, default is a function that gets called for objects - that can't otherwise be serialized. It should return a JSON encodable - version of the object or raise a ``TypeError``. - - """ - - self.skipkeys = skipkeys - self.ensure_ascii = ensure_ascii - self.check_circular = check_circular - self.allow_nan = allow_nan - self.sort_keys = sort_keys - self.indent = indent - if separators is not None: - self.item_separator, self.key_separator = separators - if default is not None: - self.default = default - - def default(self, o): - """Implement this method in a subclass such that it returns - a serializable object for ``o``, or calls the base implementation - (to raise a ``TypeError``). - - For example, to support arbitrary iterators, you could - implement default like this:: - - def default(self, o): - try: - iterable = iter(o) - except TypeError: - pass - else: - return list(iterable) - # Let the base class default method raise the TypeError - return JSONEncoder.default(self, o) - - """ - raise TypeError(repr(o) + " is not JSON serializable") - - def encode(self, o): - """Return a JSON string representation of a Python data structure. - - >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) - '{"foo": ["bar", "baz"]}' - - """ - # This is for extremely simple cases and benchmarks. - if isinstance(o, str): - if self.ensure_ascii: - return encode_basestring_ascii(o) - else: - return encode_basestring(o) - # This doesn't pass the iterator directly to ''.join() because the - # exceptions aren't as detailed. The list call should be roughly - # equivalent to the PySequence_Fast that ''.join() would do. - chunks = self.iterencode(o, _one_shot=True) - if not isinstance(chunks, (list, tuple)): - chunks = list(chunks) - return "".join(chunks) - - def iterencode(self, o, _one_shot=False): - """Encode the given object and yield each string - representation as available. - - For example:: - - for chunk in JSONEncoder().iterencode(bigobject): - mysocket.write(chunk) - - """ - if self.check_circular: - markers = {} - else: - markers = None - if self.ensure_ascii: - _encoder = encode_basestring_ascii - else: - _encoder = encode_basestring - - def floatstr( - o, allow_nan=self.allow_nan, _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY - ): - # Check for specials. Note that this type of test is processor - # and/or platform-specific, so do tests which don't depend on the - # internals. - - if o != o: - text = "NaN" - elif o == _inf: - text = "Infinity" - elif o == _neginf: - text = "-Infinity" - else: - return _repr(o) - - if not allow_nan: - raise ValueError("Out of range float values are not JSON compliant: " + repr(o)) - - return text - - if _one_shot and c_make_encoder is not None and self.indent is None: - _iterencode = c_make_encoder( - markers, - self.default, - _encoder, - self.indent, - self.key_separator, - self.item_separator, - self.sort_keys, - self.skipkeys, - self.allow_nan, - ) - else: - _iterencode = _make_iterencode( - markers, - self.default, - _encoder, - self.indent, - floatstr, - self.key_separator, - self.item_separator, - self.sort_keys, - self.skipkeys, - _one_shot, - ) - return _iterencode(o, 0) - - -def _make_iterencode( - markers, - _default, - _encoder, - _indent, - _floatstr, - _key_separator, - _item_separator, - _sort_keys, - _skipkeys, - _one_shot, - ## HACK: hand-optimized bytecode; turn globals into locals - ValueError=ValueError, - dict=dict, - float=float, - id=id, - int=int, - isinstance=isinstance, - list=list, - str=str, - tuple=tuple, -): - - if _indent is not None and not isinstance(_indent, str): - _indent = " " * _indent - - def _iterencode_list(lst, _current_indent_level): - if not lst: - yield "[]" - return - if markers is not None: - markerid = id(lst) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = lst - buf = "[" - if _indent is not None: - _current_indent_level += 1 - newline_indent = "\n" + _indent * _current_indent_level - separator = _item_separator + newline_indent - buf += newline_indent - else: - newline_indent = None - separator = _item_separator - first = True - for value in lst: - if first: - first = False - else: - buf = separator - if isinstance(value, str): - yield buf + _encoder(value) - elif value is None: - yield buf + "null" - elif value is True: - yield buf + "true" - elif value is False: - yield buf + "false" - elif isinstance(value, int): - yield buf + str(value) - elif isinstance(value, float): - yield buf + _floatstr(value) - else: - yield buf - if isinstance(value, (list, tuple)): - chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): - chunks = _iterencode_dict(value, _current_indent_level) - else: - chunks = _iterencode(value, _current_indent_level) - for chunk in chunks: - yield chunk - if newline_indent is not None: - _current_indent_level -= 1 - yield "\n" + _indent * _current_indent_level - yield "]" - if markers is not None: - del markers[markerid] - - def _iterencode_dict(dct, _current_indent_level): - if not dct: - yield "{}" - return - if markers is not None: - markerid = id(dct) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = dct - yield "{" - if _indent is not None: - _current_indent_level += 1 - newline_indent = "\n" + _indent * _current_indent_level - item_separator = _item_separator + newline_indent - yield newline_indent - else: - newline_indent = None - item_separator = _item_separator - first = True - if _sort_keys: - items = sorted(dct.items(), key=lambda kv: kv[0]) - else: - items = dct.items() - for key, value in items: - if isinstance(key, str): - pass - # JavaScript is weakly typed for these, so it makes sense to - # also allow them. Many encoders seem to do something like this. - elif isinstance(key, float): - key = _floatstr(key) - elif key is True: - key = "true" - elif key is False: - key = "false" - elif key is None: - key = "null" - elif isinstance(key, int): - key = str(key) - elif _skipkeys: - continue - else: - raise TypeError("key " + repr(key) + " is not a string") - if first: - first = False - else: - yield item_separator - yield _encoder(key) - yield _key_separator - if isinstance(value, str): - yield _encoder(value) - elif value is None: - yield "null" - elif value is True: - yield "true" - elif value is False: - yield "false" - elif isinstance(value, int): - yield str(value) - elif isinstance(value, float): - yield _floatstr(value) - else: - if isinstance(value, (list, tuple)): - chunks = _iterencode_list(value, _current_indent_level) - elif isinstance(value, dict): - chunks = _iterencode_dict(value, _current_indent_level) - else: - chunks = _iterencode(value, _current_indent_level) - for chunk in chunks: - yield chunk - if newline_indent is not None: - _current_indent_level -= 1 - yield "\n" + _indent * _current_indent_level - yield "}" - if markers is not None: - del markers[markerid] - - def _iterencode(o, _current_indent_level): - if isinstance(o, str): - yield _encoder(o) - elif o is None: - yield "null" - elif o is True: - yield "true" - elif o is False: - yield "false" - elif isinstance(o, int): - yield str(o) - elif isinstance(o, float): - yield _floatstr(o) - elif isinstance(o, (list, tuple)): - for chunk in _iterencode_list(o, _current_indent_level): - yield chunk - elif isinstance(o, dict): - for chunk in _iterencode_dict(o, _current_indent_level): - yield chunk - else: - if markers is not None: - markerid = id(o) - if markerid in markers: - raise ValueError("Circular reference detected") - markers[markerid] = o - o = _default(o) - for chunk in _iterencode(o, _current_indent_level): - yield chunk - if markers is not None: - del markers[markerid] - - return _iterencode diff --git a/python-stdlib/json/json/scanner.py b/python-stdlib/json/json/scanner.py deleted file mode 100644 index 5ddf305b3..000000000 --- a/python-stdlib/json/json/scanner.py +++ /dev/null @@ -1,77 +0,0 @@ -"""JSON token scanner -""" -import re - -try: - from _json import make_scanner as c_make_scanner -except ImportError: - c_make_scanner = None - -__all__ = ["make_scanner"] - -NUMBER_RE = re.compile( - r"(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?", (re.VERBOSE | re.MULTILINE | re.DOTALL) -) - - -def py_make_scanner(context): - parse_object = context.parse_object - parse_array = context.parse_array - parse_string = context.parse_string - match_number = NUMBER_RE.match - strict = context.strict - parse_float = context.parse_float - parse_int = context.parse_int - parse_constant = context.parse_constant - object_hook = context.object_hook - object_pairs_hook = context.object_pairs_hook - memo = context.memo - - def _scan_once(string, idx): - try: - nextchar = string[idx] - except IndexError: - raise StopIteration - - if nextchar == '"': - return parse_string(string, idx + 1, strict) - elif nextchar == "{": - return parse_object( - (string, idx + 1), strict, _scan_once, object_hook, object_pairs_hook, memo - ) - elif nextchar == "[": - return parse_array((string, idx + 1), _scan_once) - elif nextchar == "n" and string[idx : idx + 4] == "null": - return None, idx + 4 - elif nextchar == "t" and string[idx : idx + 4] == "true": - return True, idx + 4 - elif nextchar == "f" and string[idx : idx + 5] == "false": - return False, idx + 5 - - m = match_number(string, idx) - if m is not None: - integer, frac, exp = m.groups() - if frac or exp: - res = parse_float(integer + (frac or "") + (exp or "")) - else: - res = parse_int(integer) - return res, m.end() - elif nextchar == "N" and string[idx : idx + 3] == "NaN": - return parse_constant("NaN"), idx + 3 - elif nextchar == "I" and string[idx : idx + 8] == "Infinity": - return parse_constant("Infinity"), idx + 8 - elif nextchar == "-" and string[idx : idx + 9] == "-Infinity": - return parse_constant("-Infinity"), idx + 9 - else: - raise StopIteration - - def scan_once(string, idx): - try: - return _scan_once(string, idx) - finally: - memo.clear() - - return _scan_once - - -make_scanner = c_make_scanner or py_make_scanner diff --git a/python-stdlib/json/json/tool.py b/python-stdlib/json/json/tool.py deleted file mode 100644 index f88278b33..000000000 --- a/python-stdlib/json/json/tool.py +++ /dev/null @@ -1,40 +0,0 @@ -r"""Command-line tool to validate and pretty-print JSON - -Usage:: - - $ echo '{"json":"obj"}' | python -m json.tool - { - "json": "obj" - } - $ echo '{ 1.2:3.4}' | python -m json.tool - Expecting property name enclosed in double quotes: line 1 column 3 (char 2) - -""" -import sys -import json - - -def main(): - if len(sys.argv) == 1: - infile = sys.stdin - outfile = sys.stdout - elif len(sys.argv) == 2: - infile = open(sys.argv[1], "r") - outfile = sys.stdout - elif len(sys.argv) == 3: - infile = open(sys.argv[1], "r") - outfile = open(sys.argv[2], "w") - else: - raise SystemExit(sys.argv[0] + " [infile [outfile]]") - with infile: - try: - obj = json.load(infile) - except ValueError as e: - raise SystemExit(e) - with outfile: - json.dump(obj, outfile, sort_keys=True, indent=4, separators=(",", ": ")) - outfile.write("\n") - - -if __name__ == "__main__": - main() diff --git a/python-stdlib/json/setup.py b/python-stdlib/json/setup.py deleted file mode 100644 index 67bd8fce0..000000000 --- a/python-stdlib/json/setup.py +++ /dev/null @@ -1,18 +0,0 @@ -# import sys -# Remove current dir from sys.path, otherwise distutils will peek up our -# copy module instead of system. -# sys.path.pop(0) -from setuptools import setup - -setup( - name="micropython-json", - version="0.1", - description="CPython json package ported to MicroPython", - url="https://github.com/micropython/micropython/issues/405", - author="CPython Developers", - maintainer="MicroPython Developers", - maintainer_email="micro-python@googlegroups.com", - license="Python", - install_requires=["micropython-re-pcre"], - packages=["json"], -) diff --git a/python-stdlib/json/test_json.py b/python-stdlib/json/test_json.py deleted file mode 100644 index 7d7ba2104..000000000 --- a/python-stdlib/json/test_json.py +++ /dev/null @@ -1,13 +0,0 @@ -import json - -inp = ["foo", {"bar": ("baz", None, 1, 2)}] -print(inp) - -s = json.dumps(inp) -print(s) - -outp = json.loads(s) -print(outp) - -# Doesn't work because JSON doesn't have tuples -# assert inp == outp