File: demjson_compat.py

package info (click to toggle)
displaycal-py3 3.9.16-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 29,120 kB
  • sloc: python: 115,777; javascript: 11,540; xml: 598; sh: 257; makefile: 173
file content (159 lines) | stat: -rw-r--r-- 5,670 bytes parent folder | download | duplicates (2)
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",
    )