chef 17.0.242 → 17.1.35
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -12
- data/Rakefile +2 -2
- data/chef.gemspec +9 -20
- data/lib/chef/chef_fs/file_pattern.rb +2 -2
- data/lib/chef/compliance/default_attributes.rb +1 -1
- data/lib/chef/compliance/reporter/automate.rb +1 -1
- data/lib/chef/compliance/runner.rb +2 -2
- data/lib/chef/cookbook/cookbook_version_loader.rb +3 -3
- data/lib/chef/cookbook/gem_installer.rb +5 -1
- data/lib/chef/dsl/declare_resource.rb +5 -10
- data/lib/chef/formatters/doc.rb +2 -1
- data/lib/chef/node.rb +1 -1
- data/lib/chef/provider/directory.rb +6 -6
- data/lib/chef/provider/link.rb +1 -1
- data/lib/chef/provider/package/dnf/dnf_helper.py +11 -10
- data/lib/chef/provider/package/dnf/python_helper.rb +9 -8
- data/lib/chef/provider/package/yum.rb +1 -4
- data/lib/chef/provider/package/yum/python_helper.rb +15 -10
- data/lib/chef/provider/package/yum/yum_helper.py +46 -62
- data/lib/chef/provider/registry_key.rb +1 -1
- data/lib/chef/provider/service/systemd.rb +1 -1
- data/lib/chef/provider/systemd_unit.rb +1 -1
- data/lib/chef/provider/template/content.rb +1 -1
- data/lib/chef/provider/windows_script.rb +1 -1
- data/lib/chef/resource.rb +6 -7
- data/lib/chef/resource/execute.rb +2 -2
- data/lib/chef/resource/inspec_waiver_file_entry.rb +155 -0
- data/lib/chef/resource/lwrp_base.rb +17 -2
- data/lib/chef/resource/remote_file.rb +2 -2
- data/lib/chef/resource/windows_env.rb +1 -1
- data/lib/chef/resource/windows_font.rb +1 -1
- data/lib/chef/resource/windows_pagefile.rb +2 -2
- data/lib/chef/resource/windows_path.rb +2 -2
- data/lib/chef/resource/windows_security_policy.rb +5 -2
- data/lib/chef/resource/windows_task.rb +1 -1
- data/lib/chef/resource_builder.rb +8 -2
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/run_lock.rb +1 -1
- data/lib/chef/runner.rb +1 -1
- data/lib/chef/shell/ext.rb +3 -3
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api.rb +9 -2
- data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
- data/spec/data/knife-site-subcommands/plugins/knife/example_subcommand.rb +0 -0
- data/spec/data/knife_subcommand/test_explicit_category.rb +7 -0
- data/spec/data/knife_subcommand/test_name_mapping.rb +4 -0
- data/spec/data/knife_subcommand/test_yourself.rb +21 -0
- data/spec/functional/resource/dnf_package_spec.rb +857 -537
- data/spec/functional/resource/group_spec.rb +1 -1
- data/spec/functional/resource/link_spec.rb +1 -1
- data/spec/functional/resource/remote_file_spec.rb +1 -1
- data/spec/functional/resource/windows_env_spec.rb +2 -2
- data/spec/functional/resource/yum_package_spec.rb +495 -428
- data/spec/integration/client/client_spec.rb +0 -20
- data/spec/integration/recipes/unified_mode_spec.rb +70 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/chef_helpers.rb +1 -1
- data/spec/support/shared/functional/execute_resource.rb +1 -1
- data/spec/support/shared/functional/knife.rb +37 -0
- data/spec/support/shared/integration/knife_support.rb +192 -0
- data/spec/support/shared/unit/knife_shared.rb +39 -0
- data/spec/support/shared/unit/provider/file.rb +1 -1
- data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +1 -1
- data/spec/unit/compliance/runner_spec.rb +1 -1
- data/spec/unit/provider/link_spec.rb +1 -1
- data/spec/unit/provider/package/dnf/python_helper_spec.rb +1 -0
- data/spec/unit/provider/package/yum/python_helper_spec.rb +1 -0
- data/spec/unit/provider/service/systemd_service_spec.rb +2 -2
- data/spec/unit/provider/systemd_unit_spec.rb +2 -2
- data/spec/unit/resource/inspec_waiver_file_entry_spec.rb +80 -0
- data/tasks/rspec.rb +4 -9
- metadata +16 -160
- data/lib/chef/provider/package/yum/simplejson/LICENSE.txt +0 -79
- data/lib/chef/provider/package/yum/simplejson/__init__.py +0 -318
- data/lib/chef/provider/package/yum/simplejson/__init__.pyc +0 -0
- data/lib/chef/provider/package/yum/simplejson/decoder.py +0 -354
- data/lib/chef/provider/package/yum/simplejson/decoder.pyc +0 -0
- data/lib/chef/provider/package/yum/simplejson/encoder.py +0 -440
- data/lib/chef/provider/package/yum/simplejson/encoder.pyc +0 -0
- data/lib/chef/provider/package/yum/simplejson/scanner.py +0 -65
- data/lib/chef/provider/package/yum/simplejson/scanner.pyc +0 -0
- data/lib/chef/provider/package/yum/simplejson/tool.py +0 -37
@@ -1,318 +0,0 @@
|
|
1
|
-
r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
|
2
|
-
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
|
3
|
-
interchange format.
|
4
|
-
|
5
|
-
:mod:`simplejson` exposes an API familiar to users of the standard library
|
6
|
-
:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained
|
7
|
-
version of the :mod:`json` library contained in Python 2.6, but maintains
|
8
|
-
compatibility with Python 2.4 and Python 2.5 and (currently) has
|
9
|
-
significant performance advantages, even without using the optional C
|
10
|
-
extension for speedups.
|
11
|
-
|
12
|
-
Encoding basic Python object hierarchies::
|
13
|
-
|
14
|
-
>>> import simplejson as json
|
15
|
-
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
|
16
|
-
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
|
17
|
-
>>> print json.dumps("\"foo\bar")
|
18
|
-
"\"foo\bar"
|
19
|
-
>>> print json.dumps(u'\u1234')
|
20
|
-
"\u1234"
|
21
|
-
>>> print json.dumps('\\')
|
22
|
-
"\\"
|
23
|
-
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
|
24
|
-
{"a": 0, "b": 0, "c": 0}
|
25
|
-
>>> from StringIO import StringIO
|
26
|
-
>>> io = StringIO()
|
27
|
-
>>> json.dump(['streaming API'], io)
|
28
|
-
>>> io.getvalue()
|
29
|
-
'["streaming API"]'
|
30
|
-
|
31
|
-
Compact encoding::
|
32
|
-
|
33
|
-
>>> import simplejson as json
|
34
|
-
>>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
|
35
|
-
'[1,2,3,{"4":5,"6":7}]'
|
36
|
-
|
37
|
-
Pretty printing::
|
38
|
-
|
39
|
-
>>> import simplejson as json
|
40
|
-
>>> s = json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
|
41
|
-
>>> print '\n'.join([l.rstrip() for l in s.splitlines()])
|
42
|
-
{
|
43
|
-
"4": 5,
|
44
|
-
"6": 7
|
45
|
-
}
|
46
|
-
|
47
|
-
Decoding JSON::
|
48
|
-
|
49
|
-
>>> import simplejson as json
|
50
|
-
>>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
|
51
|
-
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
|
52
|
-
True
|
53
|
-
>>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
|
54
|
-
True
|
55
|
-
>>> from StringIO import StringIO
|
56
|
-
>>> io = StringIO('["streaming API"]')
|
57
|
-
>>> json.load(io)[0] == 'streaming API'
|
58
|
-
True
|
59
|
-
|
60
|
-
Specializing JSON object decoding::
|
61
|
-
|
62
|
-
>>> import simplejson as json
|
63
|
-
>>> def as_complex(dct):
|
64
|
-
... if '__complex__' in dct:
|
65
|
-
... return complex(dct['real'], dct['imag'])
|
66
|
-
... return dct
|
67
|
-
...
|
68
|
-
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
|
69
|
-
... object_hook=as_complex)
|
70
|
-
(1+2j)
|
71
|
-
>>> import decimal
|
72
|
-
>>> json.loads('1.1', parse_float=decimal.Decimal) == decimal.Decimal('1.1')
|
73
|
-
True
|
74
|
-
|
75
|
-
Specializing JSON object encoding::
|
76
|
-
|
77
|
-
>>> import simplejson as json
|
78
|
-
>>> def encode_complex(obj):
|
79
|
-
... if isinstance(obj, complex):
|
80
|
-
... return [obj.real, obj.imag]
|
81
|
-
... raise TypeError(repr(o) + " is not JSON serializable")
|
82
|
-
...
|
83
|
-
>>> json.dumps(2 + 1j, default=encode_complex)
|
84
|
-
'[2.0, 1.0]'
|
85
|
-
>>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
|
86
|
-
'[2.0, 1.0]'
|
87
|
-
>>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
|
88
|
-
'[2.0, 1.0]'
|
89
|
-
|
90
|
-
|
91
|
-
Using simplejson.tool from the shell to validate and pretty-print::
|
92
|
-
|
93
|
-
$ echo '{"json":"obj"}' | python -m simplejson.tool
|
94
|
-
{
|
95
|
-
"json": "obj"
|
96
|
-
}
|
97
|
-
$ echo '{ 1.2:3.4}' | python -m simplejson.tool
|
98
|
-
Expecting property name: line 1 column 2 (char 2)
|
99
|
-
"""
|
100
|
-
__version__ = '2.0.9'
|
101
|
-
__all__ = [
|
102
|
-
'dump', 'dumps', 'load', 'loads',
|
103
|
-
'JSONDecoder', 'JSONEncoder',
|
104
|
-
]
|
105
|
-
|
106
|
-
__author__ = 'Bob Ippolito <bob@redivi.com>'
|
107
|
-
|
108
|
-
from decoder import JSONDecoder
|
109
|
-
from encoder import JSONEncoder
|
110
|
-
|
111
|
-
_default_encoder = JSONEncoder(
|
112
|
-
skipkeys=False,
|
113
|
-
ensure_ascii=True,
|
114
|
-
check_circular=True,
|
115
|
-
allow_nan=True,
|
116
|
-
indent=None,
|
117
|
-
separators=None,
|
118
|
-
encoding='utf-8',
|
119
|
-
default=None,
|
120
|
-
)
|
121
|
-
|
122
|
-
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
|
123
|
-
allow_nan=True, cls=None, indent=None, separators=None,
|
124
|
-
encoding='utf-8', default=None, **kw):
|
125
|
-
"""Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
|
126
|
-
``.write()``-supporting file-like object).
|
127
|
-
|
128
|
-
If ``skipkeys`` is true then ``dict`` keys that are not basic types
|
129
|
-
(``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
|
130
|
-
will be skipped instead of raising a ``TypeError``.
|
131
|
-
|
132
|
-
If ``ensure_ascii`` is false, then the some chunks written to ``fp``
|
133
|
-
may be ``unicode`` instances, subject to normal Python ``str`` to
|
134
|
-
``unicode`` coercion rules. Unless ``fp.write()`` explicitly
|
135
|
-
understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
|
136
|
-
to cause an error.
|
137
|
-
|
138
|
-
If ``check_circular`` is false, then the circular reference check
|
139
|
-
for container types will be skipped and a circular reference will
|
140
|
-
result in an ``OverflowError`` (or worse).
|
141
|
-
|
142
|
-
If ``allow_nan`` is false, then it will be a ``ValueError`` to
|
143
|
-
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
|
144
|
-
in strict compliance of the JSON specification, instead of using the
|
145
|
-
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
|
146
|
-
|
147
|
-
If ``indent`` is a non-negative integer, then JSON array elements and object
|
148
|
-
members will be pretty-printed with that indent level. An indent level
|
149
|
-
of 0 will only insert newlines. ``None`` is the most compact representation.
|
150
|
-
|
151
|
-
If ``separators`` is an ``(item_separator, dict_separator)`` tuple
|
152
|
-
then it will be used instead of the default ``(', ', ': ')`` separators.
|
153
|
-
``(',', ':')`` is the most compact JSON representation.
|
154
|
-
|
155
|
-
``encoding`` is the character encoding for str instances, default is UTF-8.
|
156
|
-
|
157
|
-
``default(obj)`` is a function that should return a serializable version
|
158
|
-
of obj or raise TypeError. The default simply raises TypeError.
|
159
|
-
|
160
|
-
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
|
161
|
-
``.default()`` method to serialize additional types), specify it with
|
162
|
-
the ``cls`` kwarg.
|
163
|
-
|
164
|
-
"""
|
165
|
-
# cached encoder
|
166
|
-
if (not skipkeys and ensure_ascii and
|
167
|
-
check_circular and allow_nan and
|
168
|
-
cls is None and indent is None and separators is None and
|
169
|
-
encoding == 'utf-8' and default is None and not kw):
|
170
|
-
iterable = _default_encoder.iterencode(obj)
|
171
|
-
else:
|
172
|
-
if cls is None:
|
173
|
-
cls = JSONEncoder
|
174
|
-
iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
|
175
|
-
check_circular=check_circular, allow_nan=allow_nan, indent=indent,
|
176
|
-
separators=separators, encoding=encoding,
|
177
|
-
default=default, **kw).iterencode(obj)
|
178
|
-
# could accelerate with writelines in some versions of Python, at
|
179
|
-
# a debuggability cost
|
180
|
-
for chunk in iterable:
|
181
|
-
fp.write(chunk)
|
182
|
-
|
183
|
-
|
184
|
-
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
|
185
|
-
allow_nan=True, cls=None, indent=None, separators=None,
|
186
|
-
encoding='utf-8', default=None, **kw):
|
187
|
-
"""Serialize ``obj`` to a JSON formatted ``str``.
|
188
|
-
|
189
|
-
If ``skipkeys`` is false then ``dict`` keys that are not basic types
|
190
|
-
(``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
|
191
|
-
will be skipped instead of raising a ``TypeError``.
|
192
|
-
|
193
|
-
If ``ensure_ascii`` is false, then the return value will be a
|
194
|
-
``unicode`` instance subject to normal Python ``str`` to ``unicode``
|
195
|
-
coercion rules instead of being escaped to an ASCII ``str``.
|
196
|
-
|
197
|
-
If ``check_circular`` is false, then the circular reference check
|
198
|
-
for container types will be skipped and a circular reference will
|
199
|
-
result in an ``OverflowError`` (or worse).
|
200
|
-
|
201
|
-
If ``allow_nan`` is false, then it will be a ``ValueError`` to
|
202
|
-
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
|
203
|
-
strict compliance of the JSON specification, instead of using the
|
204
|
-
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
|
205
|
-
|
206
|
-
If ``indent`` is a non-negative integer, then JSON array elements and
|
207
|
-
object members will be pretty-printed with that indent level. An indent
|
208
|
-
level of 0 will only insert newlines. ``None`` is the most compact
|
209
|
-
representation.
|
210
|
-
|
211
|
-
If ``separators`` is an ``(item_separator, dict_separator)`` tuple
|
212
|
-
then it will be used instead of the default ``(', ', ': ')`` separators.
|
213
|
-
``(',', ':')`` is the most compact JSON representation.
|
214
|
-
|
215
|
-
``encoding`` is the character encoding for str instances, default is UTF-8.
|
216
|
-
|
217
|
-
``default(obj)`` is a function that should return a serializable version
|
218
|
-
of obj or raise TypeError. The default simply raises TypeError.
|
219
|
-
|
220
|
-
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
|
221
|
-
``.default()`` method to serialize additional types), specify it with
|
222
|
-
the ``cls`` kwarg.
|
223
|
-
|
224
|
-
"""
|
225
|
-
# cached encoder
|
226
|
-
if (not skipkeys and ensure_ascii and
|
227
|
-
check_circular and allow_nan and
|
228
|
-
cls is None and indent is None and separators is None and
|
229
|
-
encoding == 'utf-8' and default is None and not kw):
|
230
|
-
return _default_encoder.encode(obj)
|
231
|
-
if cls is None:
|
232
|
-
cls = JSONEncoder
|
233
|
-
return cls(
|
234
|
-
skipkeys=skipkeys, ensure_ascii=ensure_ascii,
|
235
|
-
check_circular=check_circular, allow_nan=allow_nan, indent=indent,
|
236
|
-
separators=separators, encoding=encoding, default=default,
|
237
|
-
**kw).encode(obj)
|
238
|
-
|
239
|
-
|
240
|
-
_default_decoder = JSONDecoder(encoding=None, object_hook=None)
|
241
|
-
|
242
|
-
|
243
|
-
def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
|
244
|
-
parse_int=None, parse_constant=None, **kw):
|
245
|
-
"""Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
|
246
|
-
a JSON document) to a Python object.
|
247
|
-
|
248
|
-
If the contents of ``fp`` is encoded with an ASCII based encoding other
|
249
|
-
than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must
|
250
|
-
be specified. Encodings that are not ASCII based (such as UCS-2) are
|
251
|
-
not allowed, and should be wrapped with
|
252
|
-
``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode``
|
253
|
-
object and passed to ``loads()``
|
254
|
-
|
255
|
-
``object_hook`` is an optional function that will be called with the
|
256
|
-
result of any object literal decode (a ``dict``). The return value of
|
257
|
-
``object_hook`` will be used instead of the ``dict``. This feature
|
258
|
-
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
|
259
|
-
|
260
|
-
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
|
261
|
-
kwarg.
|
262
|
-
|
263
|
-
"""
|
264
|
-
return loads(fp.read(),
|
265
|
-
encoding=encoding, cls=cls, object_hook=object_hook,
|
266
|
-
parse_float=parse_float, parse_int=parse_int,
|
267
|
-
parse_constant=parse_constant, **kw)
|
268
|
-
|
269
|
-
|
270
|
-
def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
|
271
|
-
parse_int=None, parse_constant=None, **kw):
|
272
|
-
"""Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
|
273
|
-
document) to a Python object.
|
274
|
-
|
275
|
-
If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
|
276
|
-
other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
|
277
|
-
must be specified. Encodings that are not ASCII based (such as UCS-2)
|
278
|
-
are not allowed and should be decoded to ``unicode`` first.
|
279
|
-
|
280
|
-
``object_hook`` is an optional function that will be called with the
|
281
|
-
result of any object literal decode (a ``dict``). The return value of
|
282
|
-
``object_hook`` will be used instead of the ``dict``. This feature
|
283
|
-
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
|
284
|
-
|
285
|
-
``parse_float``, if specified, will be called with the string
|
286
|
-
of every JSON float to be decoded. By default this is equivalent to
|
287
|
-
float(num_str). This can be used to use another datatype or parser
|
288
|
-
for JSON floats (e.g. decimal.Decimal).
|
289
|
-
|
290
|
-
``parse_int``, if specified, will be called with the string
|
291
|
-
of every JSON int to be decoded. By default this is equivalent to
|
292
|
-
int(num_str). This can be used to use another datatype or parser
|
293
|
-
for JSON integers (e.g. float).
|
294
|
-
|
295
|
-
``parse_constant``, if specified, will be called with one of the
|
296
|
-
following strings: -Infinity, Infinity, NaN, null, true, false.
|
297
|
-
This can be used to raise an exception if invalid JSON numbers
|
298
|
-
are encountered.
|
299
|
-
|
300
|
-
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
|
301
|
-
kwarg.
|
302
|
-
|
303
|
-
"""
|
304
|
-
if (cls is None and encoding is None and object_hook is None and
|
305
|
-
parse_int is None and parse_float is None and
|
306
|
-
parse_constant is None and not kw):
|
307
|
-
return _default_decoder.decode(s)
|
308
|
-
if cls is None:
|
309
|
-
cls = JSONDecoder
|
310
|
-
if object_hook is not None:
|
311
|
-
kw['object_hook'] = object_hook
|
312
|
-
if parse_float is not None:
|
313
|
-
kw['parse_float'] = parse_float
|
314
|
-
if parse_int is not None:
|
315
|
-
kw['parse_int'] = parse_int
|
316
|
-
if parse_constant is not None:
|
317
|
-
kw['parse_constant'] = parse_constant
|
318
|
-
return cls(encoding=encoding, **kw).decode(s)
|
Binary file
|
@@ -1,354 +0,0 @@
|
|
1
|
-
"""Implementation of JSONDecoder
|
2
|
-
"""
|
3
|
-
import re
|
4
|
-
import sys
|
5
|
-
import struct
|
6
|
-
|
7
|
-
from simplejson.scanner import make_scanner
|
8
|
-
try:
|
9
|
-
from simplejson._speedups import scanstring as c_scanstring
|
10
|
-
except ImportError:
|
11
|
-
c_scanstring = None
|
12
|
-
|
13
|
-
__all__ = ['JSONDecoder']
|
14
|
-
|
15
|
-
FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
|
16
|
-
|
17
|
-
def _floatconstants():
|
18
|
-
_BYTES = '7FF80000000000007FF0000000000000'.decode('hex')
|
19
|
-
if sys.byteorder != 'big':
|
20
|
-
_BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1]
|
21
|
-
nan, inf = struct.unpack('dd', _BYTES)
|
22
|
-
return nan, inf, -inf
|
23
|
-
|
24
|
-
NaN, PosInf, NegInf = _floatconstants()
|
25
|
-
|
26
|
-
|
27
|
-
def linecol(doc, pos):
|
28
|
-
lineno = doc.count('\n', 0, pos) + 1
|
29
|
-
if lineno == 1:
|
30
|
-
colno = pos
|
31
|
-
else:
|
32
|
-
colno = pos - doc.rindex('\n', 0, pos)
|
33
|
-
return lineno, colno
|
34
|
-
|
35
|
-
|
36
|
-
def errmsg(msg, doc, pos, end=None):
|
37
|
-
# Note that this function is called from _speedups
|
38
|
-
lineno, colno = linecol(doc, pos)
|
39
|
-
if end is None:
|
40
|
-
#fmt = '{0}: line {1} column {2} (char {3})'
|
41
|
-
#return fmt.format(msg, lineno, colno, pos)
|
42
|
-
fmt = '%s: line %d column %d (char %d)'
|
43
|
-
return fmt % (msg, lineno, colno, pos)
|
44
|
-
endlineno, endcolno = linecol(doc, end)
|
45
|
-
#fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
|
46
|
-
#return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
|
47
|
-
fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'
|
48
|
-
return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)
|
49
|
-
|
50
|
-
|
51
|
-
_CONSTANTS = {
|
52
|
-
'-Infinity': NegInf,
|
53
|
-
'Infinity': PosInf,
|
54
|
-
'NaN': NaN,
|
55
|
-
}
|
56
|
-
|
57
|
-
STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
|
58
|
-
BACKSLASH = {
|
59
|
-
'"': u'"', '\\': u'\\', '/': u'/',
|
60
|
-
'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',
|
61
|
-
}
|
62
|
-
|
63
|
-
DEFAULT_ENCODING = "utf-8"
|
64
|
-
|
65
|
-
def py_scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match):
|
66
|
-
"""Scan the string s for a JSON string. End is the index of the
|
67
|
-
character in s after the quote that started the JSON string.
|
68
|
-
Unescapes all valid JSON string escape sequences and raises ValueError
|
69
|
-
on attempt to decode an invalid string. If strict is False then literal
|
70
|
-
control characters are allowed in the string.
|
71
|
-
|
72
|
-
Returns a tuple of the decoded string and the index of the character in s
|
73
|
-
after the end quote."""
|
74
|
-
if encoding is None:
|
75
|
-
encoding = DEFAULT_ENCODING
|
76
|
-
chunks = []
|
77
|
-
_append = chunks.append
|
78
|
-
begin = end - 1
|
79
|
-
while 1:
|
80
|
-
chunk = _m(s, end)
|
81
|
-
if chunk is None:
|
82
|
-
raise ValueError(
|
83
|
-
errmsg("Unterminated string starting at", s, begin))
|
84
|
-
end = chunk.end()
|
85
|
-
content, terminator = chunk.groups()
|
86
|
-
# Content is contains zero or more unescaped string characters
|
87
|
-
if content:
|
88
|
-
if not isinstance(content, unicode):
|
89
|
-
content = unicode(content, encoding)
|
90
|
-
_append(content)
|
91
|
-
# Terminator is the end of string, a literal control character,
|
92
|
-
# or a backslash denoting that an escape sequence follows
|
93
|
-
if terminator == '"':
|
94
|
-
break
|
95
|
-
elif terminator != '\\':
|
96
|
-
if strict:
|
97
|
-
msg = "Invalid control character %r at" % (terminator,)
|
98
|
-
#msg = "Invalid control character {0!r} at".format(terminator)
|
99
|
-
raise ValueError(errmsg(msg, s, end))
|
100
|
-
else:
|
101
|
-
_append(terminator)
|
102
|
-
continue
|
103
|
-
try:
|
104
|
-
esc = s[end]
|
105
|
-
except IndexError:
|
106
|
-
raise ValueError(
|
107
|
-
errmsg("Unterminated string starting at", s, begin))
|
108
|
-
# If not a unicode escape sequence, must be in the lookup table
|
109
|
-
if esc != 'u':
|
110
|
-
try:
|
111
|
-
char = _b[esc]
|
112
|
-
except KeyError:
|
113
|
-
msg = "Invalid \\escape: " + repr(esc)
|
114
|
-
raise ValueError(errmsg(msg, s, end))
|
115
|
-
end += 1
|
116
|
-
else:
|
117
|
-
# Unicode escape sequence
|
118
|
-
esc = s[end + 1:end + 5]
|
119
|
-
next_end = end + 5
|
120
|
-
if len(esc) != 4:
|
121
|
-
msg = "Invalid \\uXXXX escape"
|
122
|
-
raise ValueError(errmsg(msg, s, end))
|
123
|
-
uni = int(esc, 16)
|
124
|
-
# Check for surrogate pair on UCS-4 systems
|
125
|
-
if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535:
|
126
|
-
msg = "Invalid \\uXXXX\\uXXXX surrogate pair"
|
127
|
-
if not s[end + 5:end + 7] == '\\u':
|
128
|
-
raise ValueError(errmsg(msg, s, end))
|
129
|
-
esc2 = s[end + 7:end + 11]
|
130
|
-
if len(esc2) != 4:
|
131
|
-
raise ValueError(errmsg(msg, s, end))
|
132
|
-
uni2 = int(esc2, 16)
|
133
|
-
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
|
134
|
-
next_end += 6
|
135
|
-
char = unichr(uni)
|
136
|
-
end = next_end
|
137
|
-
# Append the unescaped character
|
138
|
-
_append(char)
|
139
|
-
return u''.join(chunks), end
|
140
|
-
|
141
|
-
|
142
|
-
# Use speedup if available
|
143
|
-
scanstring = c_scanstring or py_scanstring
|
144
|
-
|
145
|
-
WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
|
146
|
-
WHITESPACE_STR = ' \t\n\r'
|
147
|
-
|
148
|
-
def JSONObject((s, end), encoding, strict, scan_once, object_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
|
149
|
-
pairs = {}
|
150
|
-
# Use a slice to prevent IndexError from being raised, the following
|
151
|
-
# check will raise a more specific ValueError if the string is empty
|
152
|
-
nextchar = s[end:end + 1]
|
153
|
-
# Normally we expect nextchar == '"'
|
154
|
-
if nextchar != '"':
|
155
|
-
if nextchar in _ws:
|
156
|
-
end = _w(s, end).end()
|
157
|
-
nextchar = s[end:end + 1]
|
158
|
-
# Trivial empty object
|
159
|
-
if nextchar == '}':
|
160
|
-
return pairs, end + 1
|
161
|
-
elif nextchar != '"':
|
162
|
-
raise ValueError(errmsg("Expecting property name", s, end))
|
163
|
-
end += 1
|
164
|
-
while True:
|
165
|
-
key, end = scanstring(s, end, encoding, strict)
|
166
|
-
|
167
|
-
# To skip some function call overhead we optimize the fast paths where
|
168
|
-
# the JSON key separator is ": " or just ":".
|
169
|
-
if s[end:end + 1] != ':':
|
170
|
-
end = _w(s, end).end()
|
171
|
-
if s[end:end + 1] != ':':
|
172
|
-
raise ValueError(errmsg("Expecting : delimiter", s, end))
|
173
|
-
|
174
|
-
end += 1
|
175
|
-
|
176
|
-
try:
|
177
|
-
if s[end] in _ws:
|
178
|
-
end += 1
|
179
|
-
if s[end] in _ws:
|
180
|
-
end = _w(s, end + 1).end()
|
181
|
-
except IndexError:
|
182
|
-
pass
|
183
|
-
|
184
|
-
try:
|
185
|
-
value, end = scan_once(s, end)
|
186
|
-
except StopIteration:
|
187
|
-
raise ValueError(errmsg("Expecting object", s, end))
|
188
|
-
pairs[key] = value
|
189
|
-
|
190
|
-
try:
|
191
|
-
nextchar = s[end]
|
192
|
-
if nextchar in _ws:
|
193
|
-
end = _w(s, end + 1).end()
|
194
|
-
nextchar = s[end]
|
195
|
-
except IndexError:
|
196
|
-
nextchar = ''
|
197
|
-
end += 1
|
198
|
-
|
199
|
-
if nextchar == '}':
|
200
|
-
break
|
201
|
-
elif nextchar != ',':
|
202
|
-
raise ValueError(errmsg("Expecting , delimiter", s, end - 1))
|
203
|
-
|
204
|
-
try:
|
205
|
-
nextchar = s[end]
|
206
|
-
if nextchar in _ws:
|
207
|
-
end += 1
|
208
|
-
nextchar = s[end]
|
209
|
-
if nextchar in _ws:
|
210
|
-
end = _w(s, end + 1).end()
|
211
|
-
nextchar = s[end]
|
212
|
-
except IndexError:
|
213
|
-
nextchar = ''
|
214
|
-
|
215
|
-
end += 1
|
216
|
-
if nextchar != '"':
|
217
|
-
raise ValueError(errmsg("Expecting property name", s, end - 1))
|
218
|
-
|
219
|
-
if object_hook is not None:
|
220
|
-
pairs = object_hook(pairs)
|
221
|
-
return pairs, end
|
222
|
-
|
223
|
-
def JSONArray((s, end), scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
|
224
|
-
values = []
|
225
|
-
nextchar = s[end:end + 1]
|
226
|
-
if nextchar in _ws:
|
227
|
-
end = _w(s, end + 1).end()
|
228
|
-
nextchar = s[end:end + 1]
|
229
|
-
# Look-ahead for trivial empty array
|
230
|
-
if nextchar == ']':
|
231
|
-
return values, end + 1
|
232
|
-
_append = values.append
|
233
|
-
while True:
|
234
|
-
try:
|
235
|
-
value, end = scan_once(s, end)
|
236
|
-
except StopIteration:
|
237
|
-
raise ValueError(errmsg("Expecting object", s, end))
|
238
|
-
_append(value)
|
239
|
-
nextchar = s[end:end + 1]
|
240
|
-
if nextchar in _ws:
|
241
|
-
end = _w(s, end + 1).end()
|
242
|
-
nextchar = s[end:end + 1]
|
243
|
-
end += 1
|
244
|
-
if nextchar == ']':
|
245
|
-
break
|
246
|
-
elif nextchar != ',':
|
247
|
-
raise ValueError(errmsg("Expecting , delimiter", s, end))
|
248
|
-
|
249
|
-
try:
|
250
|
-
if s[end] in _ws:
|
251
|
-
end += 1
|
252
|
-
if s[end] in _ws:
|
253
|
-
end = _w(s, end + 1).end()
|
254
|
-
except IndexError:
|
255
|
-
pass
|
256
|
-
|
257
|
-
return values, end
|
258
|
-
|
259
|
-
class JSONDecoder(object):
|
260
|
-
"""Simple JSON <http://json.org> decoder
|
261
|
-
|
262
|
-
Performs the following translations in decoding by default:
|
263
|
-
|
264
|
-
+---------------+-------------------+
|
265
|
-
| JSON | Python |
|
266
|
-
+===============+===================+
|
267
|
-
| object | dict |
|
268
|
-
+---------------+-------------------+
|
269
|
-
| array | list |
|
270
|
-
+---------------+-------------------+
|
271
|
-
| string | unicode |
|
272
|
-
+---------------+-------------------+
|
273
|
-
| number (int) | int, long |
|
274
|
-
+---------------+-------------------+
|
275
|
-
| number (real) | float |
|
276
|
-
+---------------+-------------------+
|
277
|
-
| true | True |
|
278
|
-
+---------------+-------------------+
|
279
|
-
| false | False |
|
280
|
-
+---------------+-------------------+
|
281
|
-
| null | None |
|
282
|
-
+---------------+-------------------+
|
283
|
-
|
284
|
-
It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as
|
285
|
-
their corresponding ``float`` values, which is outside the JSON spec.
|
286
|
-
|
287
|
-
"""
|
288
|
-
|
289
|
-
def __init__(self, encoding=None, object_hook=None, parse_float=None,
|
290
|
-
parse_int=None, parse_constant=None, strict=True):
|
291
|
-
"""``encoding`` determines the encoding used to interpret any ``str``
|
292
|
-
objects decoded by this instance (utf-8 by default). It has no
|
293
|
-
effect when decoding ``unicode`` objects.
|
294
|
-
|
295
|
-
Note that currently only encodings that are a superset of ASCII work,
|
296
|
-
strings of other encodings should be passed in as ``unicode``.
|
297
|
-
|
298
|
-
``object_hook``, if specified, will be called with the result
|
299
|
-
of every JSON object decoded and its return value will be used in
|
300
|
-
place of the given ``dict``. This can be used to provide custom
|
301
|
-
deserializations (e.g. to support JSON-RPC class hinting).
|
302
|
-
|
303
|
-
``parse_float``, if specified, will be called with the string
|
304
|
-
of every JSON float to be decoded. By default this is equivalent to
|
305
|
-
float(num_str). This can be used to use another datatype or parser
|
306
|
-
for JSON floats (e.g. decimal.Decimal).
|
307
|
-
|
308
|
-
``parse_int``, if specified, will be called with the string
|
309
|
-
of every JSON int to be decoded. By default this is equivalent to
|
310
|
-
int(num_str). This can be used to use another datatype or parser
|
311
|
-
for JSON integers (e.g. float).
|
312
|
-
|
313
|
-
``parse_constant``, if specified, will be called with one of the
|
314
|
-
following strings: -Infinity, Infinity, NaN.
|
315
|
-
This can be used to raise an exception if invalid JSON numbers
|
316
|
-
are encountered.
|
317
|
-
|
318
|
-
"""
|
319
|
-
self.encoding = encoding
|
320
|
-
self.object_hook = object_hook
|
321
|
-
self.parse_float = parse_float or float
|
322
|
-
self.parse_int = parse_int or int
|
323
|
-
self.parse_constant = parse_constant or _CONSTANTS.__getitem__
|
324
|
-
self.strict = strict
|
325
|
-
self.parse_object = JSONObject
|
326
|
-
self.parse_array = JSONArray
|
327
|
-
self.parse_string = scanstring
|
328
|
-
self.scan_once = make_scanner(self)
|
329
|
-
|
330
|
-
def decode(self, s, _w=WHITESPACE.match):
|
331
|
-
"""Return the Python representation of ``s`` (a ``str`` or ``unicode``
|
332
|
-
instance containing a JSON document)
|
333
|
-
|
334
|
-
"""
|
335
|
-
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
|
336
|
-
end = _w(s, end).end()
|
337
|
-
if end != len(s):
|
338
|
-
raise ValueError(errmsg("Extra data", s, end, len(s)))
|
339
|
-
return obj
|
340
|
-
|
341
|
-
def raw_decode(self, s, idx=0):
|
342
|
-
"""Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning
|
343
|
-
with a JSON document) and return a 2-tuple of the Python
|
344
|
-
representation and the index in ``s`` where the document ended.
|
345
|
-
|
346
|
-
This can be used to decode a JSON document from a string that may
|
347
|
-
have extraneous data at the end.
|
348
|
-
|
349
|
-
"""
|
350
|
-
try:
|
351
|
-
obj, end = self.scan_once(s, idx)
|
352
|
-
except StopIteration:
|
353
|
-
raise ValueError("No JSON object could be decoded")
|
354
|
-
return obj, end
|