chef 17.0.242-universal-mingw32 → 17.1.35-universal-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -12
  3. data/Rakefile +2 -2
  4. data/chef.gemspec +9 -20
  5. data/lib/chef/chef_fs/file_pattern.rb +2 -2
  6. data/lib/chef/compliance/default_attributes.rb +1 -1
  7. data/lib/chef/compliance/reporter/automate.rb +1 -1
  8. data/lib/chef/compliance/runner.rb +2 -2
  9. data/lib/chef/cookbook/cookbook_version_loader.rb +3 -3
  10. data/lib/chef/cookbook/gem_installer.rb +5 -1
  11. data/lib/chef/dsl/declare_resource.rb +5 -10
  12. data/lib/chef/formatters/doc.rb +2 -1
  13. data/lib/chef/node.rb +1 -1
  14. data/lib/chef/provider/directory.rb +6 -6
  15. data/lib/chef/provider/link.rb +1 -1
  16. data/lib/chef/provider/package/dnf/dnf_helper.py +11 -10
  17. data/lib/chef/provider/package/dnf/python_helper.rb +9 -8
  18. data/lib/chef/provider/package/yum.rb +1 -4
  19. data/lib/chef/provider/package/yum/python_helper.rb +15 -10
  20. data/lib/chef/provider/package/yum/yum_helper.py +46 -62
  21. data/lib/chef/provider/registry_key.rb +1 -1
  22. data/lib/chef/provider/service/systemd.rb +1 -1
  23. data/lib/chef/provider/systemd_unit.rb +1 -1
  24. data/lib/chef/provider/template/content.rb +1 -1
  25. data/lib/chef/provider/windows_script.rb +1 -1
  26. data/lib/chef/resource.rb +6 -7
  27. data/lib/chef/resource/execute.rb +2 -2
  28. data/lib/chef/resource/inspec_waiver_file_entry.rb +155 -0
  29. data/lib/chef/resource/lwrp_base.rb +17 -2
  30. data/lib/chef/resource/remote_file.rb +2 -2
  31. data/lib/chef/resource/windows_env.rb +1 -1
  32. data/lib/chef/resource/windows_font.rb +1 -1
  33. data/lib/chef/resource/windows_pagefile.rb +2 -2
  34. data/lib/chef/resource/windows_path.rb +2 -2
  35. data/lib/chef/resource/windows_security_policy.rb +5 -2
  36. data/lib/chef/resource/windows_task.rb +1 -1
  37. data/lib/chef/resource_builder.rb +8 -2
  38. data/lib/chef/resources.rb +1 -0
  39. data/lib/chef/run_lock.rb +1 -1
  40. data/lib/chef/runner.rb +1 -1
  41. data/lib/chef/shell/ext.rb +3 -3
  42. data/lib/chef/version.rb +1 -1
  43. data/lib/chef/win32/api.rb +9 -2
  44. data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
  45. data/spec/data/knife-site-subcommands/plugins/knife/example_subcommand.rb +0 -0
  46. data/spec/data/knife_subcommand/test_explicit_category.rb +7 -0
  47. data/spec/data/knife_subcommand/test_name_mapping.rb +4 -0
  48. data/spec/data/knife_subcommand/test_yourself.rb +21 -0
  49. data/spec/functional/resource/dnf_package_spec.rb +857 -537
  50. data/spec/functional/resource/group_spec.rb +1 -1
  51. data/spec/functional/resource/link_spec.rb +1 -1
  52. data/spec/functional/resource/remote_file_spec.rb +1 -1
  53. data/spec/functional/resource/windows_env_spec.rb +2 -2
  54. data/spec/functional/resource/yum_package_spec.rb +495 -428
  55. data/spec/integration/client/client_spec.rb +0 -20
  56. data/spec/integration/recipes/unified_mode_spec.rb +70 -0
  57. data/spec/spec_helper.rb +3 -0
  58. data/spec/support/chef_helpers.rb +1 -1
  59. data/spec/support/shared/functional/execute_resource.rb +1 -1
  60. data/spec/support/shared/functional/knife.rb +37 -0
  61. data/spec/support/shared/integration/knife_support.rb +192 -0
  62. data/spec/support/shared/unit/knife_shared.rb +39 -0
  63. data/spec/support/shared/unit/provider/file.rb +1 -1
  64. data/spec/unit/chef_fs/file_system/repository/directory_spec.rb +1 -1
  65. data/spec/unit/compliance/runner_spec.rb +1 -1
  66. data/spec/unit/provider/link_spec.rb +1 -1
  67. data/spec/unit/provider/package/dnf/python_helper_spec.rb +1 -0
  68. data/spec/unit/provider/package/yum/python_helper_spec.rb +1 -0
  69. data/spec/unit/provider/service/systemd_service_spec.rb +2 -2
  70. data/spec/unit/provider/systemd_unit_spec.rb +2 -2
  71. data/spec/unit/resource/inspec_waiver_file_entry_spec.rb +80 -0
  72. data/tasks/rspec.rb +4 -9
  73. metadata +16 -160
  74. data/lib/chef/provider/package/yum/simplejson/LICENSE.txt +0 -79
  75. data/lib/chef/provider/package/yum/simplejson/__init__.py +0 -318
  76. data/lib/chef/provider/package/yum/simplejson/__init__.pyc +0 -0
  77. data/lib/chef/provider/package/yum/simplejson/decoder.py +0 -354
  78. data/lib/chef/provider/package/yum/simplejson/decoder.pyc +0 -0
  79. data/lib/chef/provider/package/yum/simplejson/encoder.py +0 -440
  80. data/lib/chef/provider/package/yum/simplejson/encoder.pyc +0 -0
  81. data/lib/chef/provider/package/yum/simplejson/scanner.py +0 -65
  82. data/lib/chef/provider/package/yum/simplejson/scanner.pyc +0 -0
  83. 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)
@@ -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