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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
# -*- coding: utf-8 -*-c
"""demjson 1.3 compatibility module"""
from io import StringIO
import json
import sys
DEBUG = False
def decode(txt, strict=False, encoding=None, **kw):
"""Decodes a JSON-encoded string into a Python object.
If 'strict' is set to True, then only strictly-conforming JSON
output will be produced. Note that this means that some types
of values may not be convertable and will result in a
JSONEncodeError exception.
The input string can be either a python string or a python unicode
string. If it is already a unicode string, then it is assumed
that no character set decoding is required.
However, if you pass in a non-Unicode text string (i.e., a python
type 'str') then an attempt will be made to auto-detect and decode
the character encoding. This will be successful if the input was
encoded in any of UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE),
and of course plain ASCII works too.
Note though that if you know the character encoding, then you
should convert to a unicode string yourself, or pass it the name
of the 'encoding' to avoid the guessing made by the auto
detection, as with
python_object = demjson.decode( input_bytes, encoding='utf8' )
Optional keywords arguments are ignored.
"""
if not strict:
# Remove comments
io = StringIO()
escape = False
prev = None
expect_comment = False
in_comment = False
comment_multiline = False
in_quote = False
write = True
for c in txt:
if DEBUG:
sys.stdout.write(c)
write = True
if c == "\\":
if DEBUG:
sys.stdout.write("<ESCAPE>")
escape = True
elif escape:
if DEBUG:
sys.stdout.write("</ESCAPE>")
escape = False
else:
if not in_quote:
if c == "/":
if expect_comment:
if DEBUG:
sys.stdout.write("<COMMENT>")
in_comment = True
comment_multiline = False
expect_comment = False
elif in_comment and prev == "*":
if DEBUG:
sys.stdout.write("</MULTILINECOMMENT>")
in_comment = False
comment_multiline = False
write = False
elif not in_comment:
if DEBUG:
sys.stdout.write("<EXPECT_COMMENT>")
expect_comment = True
elif c == "*":
if expect_comment:
if DEBUG:
sys.stdout.write("<MULTILINECOMMENT>")
in_comment = True
comment_multiline = True
expect_comment = False
elif expect_comment:
if DEBUG:
sys.stdout.write("</EXPECT_COMMENT>")
expect_comment = False
if c == "\n":
if in_comment and not comment_multiline:
if DEBUG:
sys.stdout.write("</COMMENT>")
in_comment = False
write = False
elif c == '"' and not in_comment:
if in_quote:
if DEBUG:
sys.stdout.write("</QUOTE>")
in_quote = False
else:
if DEBUG:
sys.stdout.write("<QUOTE>")
in_quote = True
if write and not expect_comment and not in_comment:
io.write(c)
prev = c
txt = io.getvalue()
if DEBUG:
sys.stdout.write("\n")
print("JSON:", txt)
return json.loads(txt, encoding=encoding, strict=strict)
def encode(obj, strict=False, compactly=True, escape_unicode=False, encoding=None):
"""Encodes a Python object into a JSON-encoded string.
'strict' is ignored.
If 'compactly' is set to True, then the resulting string will
have all extraneous white space removed; if False then the
string will be "pretty printed" with whitespace and indentation
added to make it more readable.
If 'escape_unicode' is set to True, then all non-ASCII characters
will be represented as a unicode escape sequence; if False then
the actual real unicode character will be inserted.
If no encoding is specified (encoding=None) then the output will
either be a Python string (if entirely ASCII) or a Python unicode
string type.
However if an encoding name is given then the returned value will
be a python string which is the byte sequence encoding the JSON
value. As the default/recommended encoding for JSON is UTF-8,
you should almost always pass in encoding='utf8'.
"""
if compactly:
indent = None
separators = (",", ":")
else:
indent = 2
separators = (",", ": ")
ensure_ascii = escape_unicode or encoding is not None
return json.dumps(
obj,
ensure_ascii=ensure_ascii,
indent=indent,
separators=separators,
encoding=encoding or "utf-8",
)
|