pax_global_header00006660000000000000000000000064137277705160014531gustar00rootroot0000000000000052 comment=cfd9286b84bb696adc254c4fc9709deaf6cf0e79 hjson-py-3.0.2/000077500000000000000000000000001372777051600133025ustar00rootroot00000000000000hjson-py-3.0.2/.gitignore000066400000000000000000000001621372777051600152710ustar00rootroot00000000000000!__init__.py *.egg-info *.egg *.pyc *.so .DS_Store /MANIFEST /.coverage /coverage.xml /htmlcov /build /dist /docs hjson-py-3.0.2/.travis.yml000066400000000000000000000002251372777051600154120ustar00rootroot00000000000000language: python python: - "2.7" - "3.4" - "3.5" - "3.6" - "3.7" - "pypy" script: - python -m compileall -f . - python setup.py test hjson-py-3.0.2/LICENSE.txt000066400000000000000000000243361372777051600151350ustar00rootroot00000000000000hjson (based on simplejson) is dual-licensed software. It is available under the terms of the MIT license, or the Academic Free License version 2.1. The full text of each license agreement is included below. This code is also licensed to the Python Software Foundation (PSF) under a Contributor Agreement. MIT License =========== Copyright (c) 2006 Bob Ippolito Copyright (c) 2015 Christian Zangl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Academic Free License v. 2.1 ============================ Copyright (c) 2006 Bob Ippolito. All rights reserved. Copyright (c) 2015 Christian Zangl This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following notice immediately following the copyright notice for the Original Work: Licensed under the Academic Free License version 2.1 1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license to do the following: a) to reproduce the Original Work in copies; b) to prepare derivative works ("Derivative Works") based upon the Original Work; c) to distribute copies of the Original Work and Derivative Works to the public; d) to perform the Original Work publicly; and e) to display the Original Work publicly. 2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, to make, use, sell and offer for sale the Original Work and Derivative Works. 3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work, and by publishing the address of that information repository in a notice immediately following the copyright notice that applies to the Original Work. 4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior written permission of the Licensor. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor except as expressly stated herein. No patent license is granted to make, use, sell or offer to sell embodiments of any patent claims other than the licensed claims defined in Section 2. No right is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any Original Work that Licensor otherwise would have a right to license. 5) This section intentionally omitted. 6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. 7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately proceeding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to Original Work is granted hereunder except under this disclaimer. 8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to liability for death or personal injury resulting from Licensor's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. Nothing else but this License (or another written agreement between Licensor and You) grants You permission to create Derivative Works based upon the Original Work or to exercise any of the rights granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions. 10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. 11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of the U.S. Copyright Act, 17 U.S.C. ยง 101 et seq., the equivalent laws of other countries, and international treaty. This section shall survive the termination of this License. 12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. 13) Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. 14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission is hereby granted to copy and distribute this license without modification. This license may not be modified without the express written permission of its copyright owner. hjson-py-3.0.2/MANIFEST.in000066400000000000000000000001251372777051600150360ustar00rootroot00000000000000include *.py include *.txt include *.rst include bin/* include MANIFEST.in prune \#* hjson-py-3.0.2/README.md000066400000000000000000000032551372777051600145660ustar00rootroot00000000000000# hjson-py [![Build Status](https://img.shields.io/travis/hjson/hjson-py.svg?style=flat-square)](http://travis-ci.org/hjson/hjson-py) [![PyPI version](https://img.shields.io/pypi/v/hjson.svg?style=flat-square)](https://pypi.python.org/pypi/hjson) [Hjson](http://hjson.org), a user interface for JSON ![Hjson Intro](http://hjson.org/hjson1.gif) Hjson works with Python 2.5+ and Python 3.3+ The Python implementation of Hjson is based on [simplejson](https://github.com/simplejson/simplejson). For other platforms see [hjson.org](http://hjson.org). # Installation - `pip install hjson` - or download from https://pypi.python.org/pypi/hjson pip will also add the `hjson` tool to your `PATH` (try `echo '{a:1}'|hjson`). ## Commandline ``` Usage: hjson [options] hjson [options] hjson (-h | --help) hjson (-V | --version) Options: -h --help Show this screen. -j Output as formatted JSON. -c Output as JSON. -V --version Show version. ``` E.g. `echo '{"json":"obj"}' | hjson` # Usage ```python import hjson ``` ## Decoding Hjson ```python text = """{ foo: a bar: 1 }""" hjson.loads(text) ``` Result: ```python OrderedDict([('foo', 'a'), ('bar', 1)]) ``` ## Encoding Python object hierarchies ```python hjson.dumps({'foo': 'text', 'bar': (1, 2)}) ``` Result: ``` { foo: text bar: [ 1 2 ] } ``` ## Encoding as JSON Note that this is probably not as performant as the simplejson version. ```python hjson.dumpsJSON(['foo', {'bar': ('baz', None, 1.0, 2)}]) ``` Result: `'["foo", {"bar": ["baz", null, 1.0, 2]}]'` # API [hjson-py documentation](http://hjson.github.io/hjson-py/) # History [see history.md](history.md) hjson-py-3.0.2/README.rst000066400000000000000000000027241372777051600147760ustar00rootroot00000000000000hjson-py ======== `Hjson`_, a user interface for JSON Hjson works with Python 2.5+ and Python 3.3+ (based on `simplejson`_) Installation ============ - ``pip install hjson`` - or download from https://pypi.python.org/pypi/hjson Commandline ----------- :: Usage: hjson [options] hjson [options] hjson (-h | --help) hjson (-V | --version) Options: -h --help Show this screen. -j Output as formatted JSON. -c Output as JSON. -V --version Show version. E.g. ``echo '{"json":"obj"}' | hjson`` Usage ===== .. code-block:: python import hjson Decoding Hjson -------------- .. code-block:: python text = """{ foo: a bar: 1 }""" hjson.loads(text) Result: .. code-block:: python OrderedDict([('foo', 'a'), ('bar', 1)]) Encoding Python object hierarchies ---------------------------------- .. code-block:: python hjson.dumps({'foo': 'text', 'bar': (1, 2)}) Result: :: { foo: text bar: [ 1 2 ] } Encoding as JSON ---------------- Note that this is probably not as performant as the simplejson version. .. code-block:: python hjson.dumpsJSON(['foo', {'bar': ('baz', None, 1.0, 2)}]) Result: ``'["foo", {"bar": ["baz", null, 1.0, 2]}]'`` API === `hjson-py`_ .. _Hjson: http://hjson.org .. _simplejson: https://github.com/simplejson/simplejson .. _hjson-py: http://hjson.github.io/hjson-py/ hjson-py-3.0.2/bin/000077500000000000000000000000001372777051600140525ustar00rootroot00000000000000hjson-py-3.0.2/bin/hjson000077500000000000000000000000451372777051600151200ustar00rootroot00000000000000#!/bin/sh python -m hjson.tool "$@" hjson-py-3.0.2/bin/hjson.cmd000066400000000000000000000000301372777051600156510ustar00rootroot00000000000000@python -m hjson.tool %*hjson-py-3.0.2/docs/000077500000000000000000000000001372777051600142325ustar00rootroot00000000000000hjson-py-3.0.2/docs/index.html000066400000000000000000006047601372777051600162440ustar00rootroot00000000000000 hjson API documentation Top

hjson module

Hjson, the Human JSON. A configuration file format that caters to humans and helps reduce the errors they make.

For details and syntax see http://hjson.org.

Decoding Hjson::

>>> import hjson
>>> text = "{\n  foo: a\n  bar: 1\n}"
>>> hjson.loads(text)
OrderedDict([('foo', 'a'), ('bar', 1)])

Encoding Python object hierarchies::

>>> import hjson
>>> # hjson.dumps({'foo': 'text', 'bar': (1, 2)})
>>> hjson.dumps(OrderedDict([('foo', 'text'), ('bar', (1, 2))]))
'{\n  foo: text\n  bar:\n  [\n    1\n    2\n  ]\n}'

Encoding as JSON::

Note that this is probably not as performant as the simplejson version.

>>> import hjson
>>> hjson.dumpsJSON(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'

Using hjson.tool from the shell to validate and pretty-print::

$ echo '{"json":"obj"}' | python -m hjson.tool
{
  json: obj
}

Other formats are -c for compact or -j for formatted JSON.
r"""Hjson, the Human JSON. A configuration file format that caters to
humans and helps reduce the errors they make.

For details and syntax see .

Decoding Hjson::

    >>> import hjson
    >>> text = "{\n  foo: a\n  bar: 1\n}"
    >>> hjson.loads(text)
    OrderedDict([('foo', 'a'), ('bar', 1)])

Encoding Python object hierarchies::

    >>> import hjson
    >>> # hjson.dumps({'foo': 'text', 'bar': (1, 2)})
    >>> hjson.dumps(OrderedDict([('foo', 'text'), ('bar', (1, 2))]))
    '{\n  foo: text\n  bar:\n  [\n    1\n    2\n  ]\n}'

Encoding as JSON::

    Note that this is probably not as performant as the simplejson version.

    >>> import hjson
    >>> hjson.dumpsJSON(['foo', {'bar': ('baz', None, 1.0, 2)}])
    '["foo", {"bar": ["baz", null, 1.0, 2]}]'

Using hjson.tool from the shell to validate and pretty-print::

    $ echo '{"json":"obj"}' | python -m hjson.tool
    {
      json: obj
    }

    Other formats are -c for compact or -j for formatted JSON.

"""
from __future__ import absolute_import
__version__ = '2.0.0'
__all__ = [
    'dump', 'dumps', 'load', 'loads',
    'dumpJSON', 'dumpsJSON',
    'HjsonDecoder', 'HjsonDecodeError', 'HjsonEncoder', 'JSONEncoder',
    'OrderedDict', 'simple_first',
]

# based on simplejson by
# __author__ = 'Bob Ippolito '
__author__ = 'Christian Zangl '

from decimal import Decimal

from .scanner import HjsonDecodeError
from .decoder import HjsonDecoder
from .encoderH import HjsonEncoder
from .encoder import JSONEncoder
def _import_OrderedDict():
    import collections
    try:
        return collections.OrderedDict
    except AttributeError:
        from . import ordered_dict
        return ordered_dict.OrderedDict
OrderedDict = _import_OrderedDict()


_default_decoder = HjsonDecoder(encoding=None, object_hook=None,
                               object_pairs_hook=OrderedDict)


def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, object_pairs_hook=OrderedDict,
        use_decimal=False, namedtuple_as_object=True, tuple_as_array=True,
        **kw):
    """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
    a JSON document) to a Python object.

    *encoding* determines the encoding used to interpret any
    :class:`str` objects decoded by this instance (``'utf-8'`` by
    default).  It has no effect when decoding :class:`unicode` objects.

    Note that currently only encodings that are a superset of ASCII work,
    strings of other encodings should be passed in as :class:`unicode`.

    *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 :class:`dict`.  This can be used to provide custom
    deserializations (e.g. to support JSON-RPC class hinting).

    *object_pairs_hook* is an optional function that will be called with
    the result of any object literal decode with an ordered list of pairs.
    The return value of *object_pairs_hook* will be used instead of the
    :class:`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, :func:`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. :class:`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. :class:`float`).

    If *use_decimal* is true (default: ``False``) then it implies
    parse_float=decimal.Decimal for parity with ``dump``.

    To use a custom ``HjsonDecoder`` subclass, specify it with the ``cls``
    kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
    of subclassing whenever possible.

    """
    return loads(fp.read(),
        encoding=encoding, cls=cls, object_hook=object_hook,
        parse_float=parse_float, parse_int=parse_int,
        object_pairs_hook=object_pairs_hook,
        use_decimal=use_decimal, **kw)


def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, object_pairs_hook=None,
        use_decimal=False, **kw):
    """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
    document) to a Python object.

    *encoding* determines the encoding used to interpret any
    :class:`str` objects decoded by this instance (``'utf-8'`` by
    default).  It has no effect when decoding :class:`unicode` objects.

    Note that currently only encodings that are a superset of ASCII work,
    strings of other encodings should be passed in as :class:`unicode`.

    *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 :class:`dict`.  This can be used to provide custom
    deserializations (e.g. to support JSON-RPC class hinting).

    *object_pairs_hook* is an optional function that will be called with
    the result of any object literal decode with an ordered list of pairs.
    The return value of *object_pairs_hook* will be used instead of the
    :class:`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, :func:`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. :class:`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. :class:`float`).

    If *use_decimal* is true (default: ``False``) then it implies
    parse_float=decimal.Decimal for parity with ``dump``.

    To use a custom ``HjsonDecoder`` subclass, specify it with the ``cls``
    kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
    of subclassing whenever possible.

    """
    if (cls is None and encoding is None and object_hook is None and
            parse_int is None and parse_float is None and
            object_pairs_hook is None
            and not use_decimal and not kw):
        return _default_decoder.decode(s)
    if cls is None:
        cls = HjsonDecoder
    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 use_decimal:
        if parse_float is not None:
            raise TypeError("use_decimal=True implies parse_float=Decimal")
        kw['parse_float'] = Decimal
    return cls(encoding=encoding, **kw).decode(s)


_default_hjson_encoder = HjsonEncoder(
    skipkeys=False,
    ensure_ascii=True,
    check_circular=True,
    indent=None,
    encoding='utf-8',
    default=None,
    use_decimal=True,
    namedtuple_as_object=True,
    tuple_as_array=True,
    bigint_as_string=False,
    item_sort_key=None,
    for_json=False,
    int_as_string_bitcount=None,
)

def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
         cls=None, indent=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
         for_json=False, int_as_string_bitcount=None, **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``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If *ensure_ascii* is false, then the some chunks written to ``fp``
    may be ``unicode`` instances, subject to normal Python ``str`` to
    ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
    understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
    to cause an error.

    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 *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. For backwards compatibility with
    versions of hjson earlier than 2.1.0, an integer is also accepted
    and is converted to a string with that many spaces.

    *encoding* is the character encoding for str instances, default is UTF-8.

    *default(obj)* is a function that should return a serializable version
    of obj or raise ``TypeError``. The default simply raises ``TypeError``.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise. Note that this is still a
    lossy operation that will not round-trip correctly and should be used
    sparingly.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precedence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``HjsonEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
    of subclassing whenever possible.

    """
    # cached encoder
    if (not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        iterable = _default_hjson_encoder.iterencode(obj)
    else:
        if cls is None:
            cls = HjsonEncoder
        iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
            check_circular=check_circular, indent=indent,
            encoding=encoding,
            default=default, use_decimal=use_decimal,
            namedtuple_as_object=namedtuple_as_object,
            tuple_as_array=tuple_as_array,
            bigint_as_string=bigint_as_string,
            sort_keys=sort_keys,
            item_sort_key=item_sort_key,
            for_json=for_json,
            int_as_string_bitcount=int_as_string_bitcount,
            **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,
          cls=None, indent=None,
          encoding='utf-8', default=None, use_decimal=True,
          namedtuple_as_object=True, tuple_as_array=True,
          bigint_as_string=False, sort_keys=False, item_sort_key=None,
          for_json=False, int_as_string_bitcount=None, **kw):
    """Serialize ``obj`` to a JSON formatted ``str``.

    If ``skipkeys`` is false then ``dict`` keys that are not basic types
    (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If ``ensure_ascii`` is false, then the return value will be a
    ``unicode`` instance subject to normal Python ``str`` to ``unicode``
    coercion rules instead of being escaped to an ASCII ``str``.

    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 ``indent`` is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. For backwards compatibility with
    versions of hjson earlier than 2.1.0, an integer is also accepted
    and is converted to a string with that many spaces.

    ``encoding`` is the character encoding for str instances, default is UTF-8.

    ``default(obj)`` is a function that should return a serializable version
    of obj or raise TypeError. The default simply raises TypeError.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (not the default), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precendence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``HjsonEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
    whenever possible.

    """
    # cached encoder
    if (
        not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        return _default_hjson_encoder.encode(obj)
    if cls is None:
        cls = HjsonEncoder
    return cls(
        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
        check_circular=check_circular, indent=indent,
        encoding=encoding, default=default,
        use_decimal=use_decimal,
        namedtuple_as_object=namedtuple_as_object,
        tuple_as_array=tuple_as_array,
        bigint_as_string=bigint_as_string,
        sort_keys=sort_keys,
        item_sort_key=item_sort_key,
        for_json=for_json,
        int_as_string_bitcount=int_as_string_bitcount,
        **kw).encode(obj)



_default_json_encoder = JSONEncoder(
    skipkeys=False,
    ensure_ascii=True,
    check_circular=True,
    indent=None,
    separators=None,
    encoding='utf-8',
    default=None,
    use_decimal=True,
    namedtuple_as_object=True,
    tuple_as_array=True,
    bigint_as_string=False,
    item_sort_key=None,
    for_json=False,
    int_as_string_bitcount=None,
)

def dumpJSON(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
         cls=None, indent=None, separators=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
         for_json=False, int_as_string_bitcount=None, **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``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If *ensure_ascii* is false, then the some chunks written to ``fp``
    may be ``unicode`` instances, subject to normal Python ``str`` to
    ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
    understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
    to cause an error.

    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 *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. An integer is also accepted
    and is converted to a string with that many spaces.

    If specified, *separators* should be an
    ``(item_separator, key_separator)`` tuple.  The default is ``(', ', ': ')``
    if *indent* is ``None`` and ``(',', ': ')`` otherwise.  To get the most
    compact JSON representation, you should specify ``(',', ':')`` to eliminate
    whitespace.

    *encoding* is the character encoding for str instances, default is UTF-8.

    *default(obj)* is a function that should return a serializable version
    of obj or raise ``TypeError``. The default simply raises ``TypeError``.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise. Note that this is still a
    lossy operation that will not round-trip correctly and should be used
    sparingly.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precedence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
    of subclassing whenever possible.

    """
    # cached encoder
    if (not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and separators is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        iterable = _default_json_encoder.iterencode(obj)
    else:
        if cls is None:
            cls = JSONEncoder
        iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
            check_circular=check_circular, indent=indent,
            separators=separators, encoding=encoding,
            default=default, use_decimal=use_decimal,
            namedtuple_as_object=namedtuple_as_object,
            tuple_as_array=tuple_as_array,
            bigint_as_string=bigint_as_string,
            sort_keys=sort_keys,
            item_sort_key=item_sort_key,
            for_json=for_json,
            int_as_string_bitcount=int_as_string_bitcount,
            **kw).iterencode(obj)
    # could accelerate with writelines in some versions of Python, at
    # a debuggability cost
    for chunk in iterable:
        fp.write(chunk)


def dumpsJSON(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
          cls=None, indent=None, separators=None,
          encoding='utf-8', default=None, use_decimal=True,
          namedtuple_as_object=True, tuple_as_array=True,
          bigint_as_string=False, sort_keys=False, item_sort_key=None,
          for_json=False, int_as_string_bitcount=None, **kw):
    """Serialize ``obj`` to a JSON formatted ``str``.

    If ``skipkeys`` is false then ``dict`` keys that are not basic types
    (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If ``ensure_ascii`` is false, then the return value will be a
    ``unicode`` instance subject to normal Python ``str`` to ``unicode``
    coercion rules instead of being escaped to an ASCII ``str``.

    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 ``indent`` is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. An integer is also accepted
    and is converted to a string with that many spaces.

    If specified, ``separators`` should be an
    ``(item_separator, key_separator)`` tuple.  The default is ``(', ', ': ')``
    if *indent* is ``None`` and ``(',', ': ')`` otherwise.  To get the most
    compact JSON representation, you should specify ``(',', ':')`` to eliminate
    whitespace.

    ``encoding`` is the character encoding for str instances, default is UTF-8.

    ``default(obj)`` is a function that should return a serializable version
    of obj or raise TypeError. The default simply raises TypeError.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (not the default), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precendence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
    whenever possible.

    """
    # cached encoder
    if (
        not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and separators is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        return _default_json_encoder.encode(obj)
    if cls is None:
        cls = JSONEncoder
    return cls(
        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
        check_circular=check_circular, indent=indent,
        separators=separators, encoding=encoding, default=default,
        use_decimal=use_decimal,
        namedtuple_as_object=namedtuple_as_object,
        tuple_as_array=tuple_as_array,
        bigint_as_string=bigint_as_string,
        sort_keys=sort_keys,
        item_sort_key=item_sort_key,
        for_json=for_json,
        int_as_string_bitcount=int_as_string_bitcount,
        **kw).encode(obj)



def simple_first(kv):
    """Helper function to pass to item_sort_key to sort simple
    elements to the top, then container elements.
    """
    return (isinstance(kv[1], (list, dict, tuple)), kv[0])

Functions

def dump(

obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, cls=None, indent=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **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, unicode, int, long, float, bool, None) will be skipped instead of raising a TypeError.

If ensure_ascii is false, then the some chunks written to fp may be unicode instances, subject to normal Python str to unicode coercion rules. Unless fp.write() explicitly understands unicode (as in codecs.getwriter()) this is likely to cause an error.

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 indent is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. None (the default) selects the most compact representation without any newlines. For backwards compatibility with versions of hjson earlier than 2.1.0, an integer is also accepted and is converted to a string with that many spaces.

encoding is the character encoding for str instances, default is UTF-8.

default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.

If use_decimal is true (default: True) then decimal.Decimal will be natively serialized to JSON with full precision.

If namedtuple_as_object is true (default: True), :class:tuple subclasses with _asdict() methods will be encoded as JSON objects.

If tuple_as_array is true (default: True), :class:tuple (and subclasses) will be encoded as JSON arrays.

If bigint_as_string is true (default: False), ints 253 and higher or lower than -253 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this is still a lossy operation that will not round-trip correctly and should be used sparingly.

If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2n or lower than or equal to -2n will be encoded as strings.

If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precedence over sort_keys.

If sort_keys is true (default: False), the output of dictionaries will be sorted by item.

If for_json is true (default: False), objects with a for_json() method will use the return value of that method for encoding as JSON instead of the object.

To use a custom HjsonEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg. NOTE: You should use default or for_json instead of subclassing whenever possible.

def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
         cls=None, indent=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
         for_json=False, int_as_string_bitcount=None, **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``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If *ensure_ascii* is false, then the some chunks written to ``fp``
    may be ``unicode`` instances, subject to normal Python ``str`` to
    ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
    understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
    to cause an error.

    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 *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. For backwards compatibility with
    versions of hjson earlier than 2.1.0, an integer is also accepted
    and is converted to a string with that many spaces.

    *encoding* is the character encoding for str instances, default is UTF-8.

    *default(obj)* is a function that should return a serializable version
    of obj or raise ``TypeError``. The default simply raises ``TypeError``.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise. Note that this is still a
    lossy operation that will not round-trip correctly and should be used
    sparingly.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precedence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``HjsonEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
    of subclassing whenever possible.

    """
    # cached encoder
    if (not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        iterable = _default_hjson_encoder.iterencode(obj)
    else:
        if cls is None:
            cls = HjsonEncoder
        iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
            check_circular=check_circular, indent=indent,
            encoding=encoding,
            default=default, use_decimal=use_decimal,
            namedtuple_as_object=namedtuple_as_object,
            tuple_as_array=tuple_as_array,
            bigint_as_string=bigint_as_string,
            sort_keys=sort_keys,
            item_sort_key=item_sort_key,
            for_json=for_json,
            int_as_string_bitcount=int_as_string_bitcount,
            **kw).iterencode(obj)
    # could accelerate with writelines in some versions of Python, at
    # a debuggability cost
    for chunk in iterable:
        fp.write(chunk)

def dumpJSON(

obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **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, unicode, int, long, float, bool, None) will be skipped instead of raising a TypeError.

If ensure_ascii is false, then the some chunks written to fp may be unicode instances, subject to normal Python str to unicode coercion rules. Unless fp.write() explicitly understands unicode (as in codecs.getwriter()) this is likely to cause an error.

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 indent is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. None (the default) selects the most compact representation without any newlines. An integer is also accepted and is converted to a string with that many spaces.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (', ', ': ') if indent is None and (',', ': ') otherwise. To get the most compact JSON representation, you should specify (',', ':') to eliminate whitespace.

encoding is the character encoding for str instances, default is UTF-8.

default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.

If use_decimal is true (default: True) then decimal.Decimal will be natively serialized to JSON with full precision.

If namedtuple_as_object is true (default: True), :class:tuple subclasses with _asdict() methods will be encoded as JSON objects.

If tuple_as_array is true (default: True), :class:tuple (and subclasses) will be encoded as JSON arrays.

If bigint_as_string is true (default: False), ints 253 and higher or lower than -253 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this is still a lossy operation that will not round-trip correctly and should be used sparingly.

If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2n or lower than or equal to -2n will be encoded as strings.

If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precedence over sort_keys.

If sort_keys is true (default: False), the output of dictionaries will be sorted by item.

If for_json is true (default: False), objects with a for_json() method will use the return value of that method for encoding as JSON instead of the object.

To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg. NOTE: You should use default or for_json instead of subclassing whenever possible.

def dumpJSON(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
         cls=None, indent=None, separators=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
         for_json=False, int_as_string_bitcount=None, **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``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If *ensure_ascii* is false, then the some chunks written to ``fp``
    may be ``unicode`` instances, subject to normal Python ``str`` to
    ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
    understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
    to cause an error.

    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 *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. An integer is also accepted
    and is converted to a string with that many spaces.

    If specified, *separators* should be an
    ``(item_separator, key_separator)`` tuple.  The default is ``(', ', ': ')``
    if *indent* is ``None`` and ``(',', ': ')`` otherwise.  To get the most
    compact JSON representation, you should specify ``(',', ':')`` to eliminate
    whitespace.

    *encoding* is the character encoding for str instances, default is UTF-8.

    *default(obj)* is a function that should return a serializable version
    of obj or raise ``TypeError``. The default simply raises ``TypeError``.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise. Note that this is still a
    lossy operation that will not round-trip correctly and should be used
    sparingly.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precedence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
    of subclassing whenever possible.

    """
    # cached encoder
    if (not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and separators is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        iterable = _default_json_encoder.iterencode(obj)
    else:
        if cls is None:
            cls = JSONEncoder
        iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
            check_circular=check_circular, indent=indent,
            separators=separators, encoding=encoding,
            default=default, use_decimal=use_decimal,
            namedtuple_as_object=namedtuple_as_object,
            tuple_as_array=tuple_as_array,
            bigint_as_string=bigint_as_string,
            sort_keys=sort_keys,
            item_sort_key=item_sort_key,
            for_json=for_json,
            int_as_string_bitcount=int_as_string_bitcount,
            **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, cls=None, indent=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **kw)

Serialize obj to a JSON formatted str.

If skipkeys is false then dict keys that are not basic types (str, unicode, int, long, float, bool, None) will be skipped instead of raising a TypeError.

If ensure_ascii is false, then the return value will be a unicode instance subject to normal Python str to unicode coercion rules instead of being escaped to an ASCII str.

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 indent is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. None (the default) selects the most compact representation without any newlines. For backwards compatibility with versions of hjson earlier than 2.1.0, an integer is also accepted and is converted to a string with that many spaces.

encoding is the character encoding for str instances, default is UTF-8.

default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.

If use_decimal is true (default: True) then decimal.Decimal will be natively serialized to JSON with full precision.

If namedtuple_as_object is true (default: True), :class:tuple subclasses with _asdict() methods will be encoded as JSON objects.

If tuple_as_array is true (default: True), :class:tuple (and subclasses) will be encoded as JSON arrays.

If bigint_as_string is true (not the default), ints 253 and higher or lower than -253 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise.

If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2n or lower than or equal to -2n will be encoded as strings.

If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precendence over sort_keys.

If sort_keys is true (default: False), the output of dictionaries will be sorted by item.

If for_json is true (default: False), objects with a for_json() method will use the return value of that method for encoding as JSON instead of the object.

To use a custom HjsonEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg. NOTE: You should use default instead of subclassing whenever possible.

def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
          cls=None, indent=None,
          encoding='utf-8', default=None, use_decimal=True,
          namedtuple_as_object=True, tuple_as_array=True,
          bigint_as_string=False, sort_keys=False, item_sort_key=None,
          for_json=False, int_as_string_bitcount=None, **kw):
    """Serialize ``obj`` to a JSON formatted ``str``.

    If ``skipkeys`` is false then ``dict`` keys that are not basic types
    (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If ``ensure_ascii`` is false, then the return value will be a
    ``unicode`` instance subject to normal Python ``str`` to ``unicode``
    coercion rules instead of being escaped to an ASCII ``str``.

    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 ``indent`` is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. For backwards compatibility with
    versions of hjson earlier than 2.1.0, an integer is also accepted
    and is converted to a string with that many spaces.

    ``encoding`` is the character encoding for str instances, default is UTF-8.

    ``default(obj)`` is a function that should return a serializable version
    of obj or raise TypeError. The default simply raises TypeError.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (not the default), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precendence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``HjsonEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
    whenever possible.

    """
    # cached encoder
    if (
        not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        return _default_hjson_encoder.encode(obj)
    if cls is None:
        cls = HjsonEncoder
    return cls(
        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
        check_circular=check_circular, indent=indent,
        encoding=encoding, default=default,
        use_decimal=use_decimal,
        namedtuple_as_object=namedtuple_as_object,
        tuple_as_array=tuple_as_array,
        bigint_as_string=bigint_as_string,
        sort_keys=sort_keys,
        item_sort_key=item_sort_key,
        for_json=for_json,
        int_as_string_bitcount=int_as_string_bitcount,
        **kw).encode(obj)

def dumpsJSON(

obj, skipkeys=False, ensure_ascii=True, check_circular=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **kw)

Serialize obj to a JSON formatted str.

If skipkeys is false then dict keys that are not basic types (str, unicode, int, long, float, bool, None) will be skipped instead of raising a TypeError.

If ensure_ascii is false, then the return value will be a unicode instance subject to normal Python str to unicode coercion rules instead of being escaped to an ASCII str.

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 indent is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. None (the default) selects the most compact representation without any newlines. An integer is also accepted and is converted to a string with that many spaces.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (', ', ': ') if indent is None and (',', ': ') otherwise. To get the most compact JSON representation, you should specify (',', ':') to eliminate whitespace.

encoding is the character encoding for str instances, default is UTF-8.

default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.

If use_decimal is true (default: True) then decimal.Decimal will be natively serialized to JSON with full precision.

If namedtuple_as_object is true (default: True), :class:tuple subclasses with _asdict() methods will be encoded as JSON objects.

If tuple_as_array is true (default: True), :class:tuple (and subclasses) will be encoded as JSON arrays.

If bigint_as_string is true (not the default), ints 253 and higher or lower than -253 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise.

If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2n or lower than or equal to -2n will be encoded as strings.

If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precendence over sort_keys.

If sort_keys is true (default: False), the output of dictionaries will be sorted by item.

If for_json is true (default: False), objects with a for_json() method will use the return value of that method for encoding as JSON instead of the object.

To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg. NOTE: You should use default instead of subclassing whenever possible.

def dumpsJSON(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
          cls=None, indent=None, separators=None,
          encoding='utf-8', default=None, use_decimal=True,
          namedtuple_as_object=True, tuple_as_array=True,
          bigint_as_string=False, sort_keys=False, item_sort_key=None,
          for_json=False, int_as_string_bitcount=None, **kw):
    """Serialize ``obj`` to a JSON formatted ``str``.

    If ``skipkeys`` is false then ``dict`` keys that are not basic types
    (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    will be skipped instead of raising a ``TypeError``.

    If ``ensure_ascii`` is false, then the return value will be a
    ``unicode`` instance subject to normal Python ``str`` to ``unicode``
    coercion rules instead of being escaped to an ASCII ``str``.

    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 ``indent`` is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. An integer is also accepted
    and is converted to a string with that many spaces.

    If specified, ``separators`` should be an
    ``(item_separator, key_separator)`` tuple.  The default is ``(', ', ': ')``
    if *indent* is ``None`` and ``(',', ': ')`` otherwise.  To get the most
    compact JSON representation, you should specify ``(',', ':')`` to eliminate
    whitespace.

    ``encoding`` is the character encoding for str instances, default is UTF-8.

    ``default(obj)`` is a function that should return a serializable version
    of obj or raise TypeError. The default simply raises TypeError.

    If *use_decimal* is true (default: ``True``) then decimal.Decimal
    will be natively serialized to JSON with full precision.

    If *namedtuple_as_object* is true (default: ``True``),
    :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
    as JSON objects.

    If *tuple_as_array* is true (default: ``True``),
    :class:`tuple` (and subclasses) will be encoded as JSON arrays.

    If *bigint_as_string* is true (not the default), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise.

    If *int_as_string_bitcount* is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.

    If specified, *item_sort_key* is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key. This option takes precendence over
    *sort_keys*.

    If *sort_keys* is true (default: ``False``), the output of dictionaries
    will be sorted by item.

    If *for_json* is true (default: ``False``), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.

    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
    whenever possible.

    """
    # cached encoder
    if (
        not skipkeys and ensure_ascii and
        check_circular and
        cls is None and indent is None and separators is None and
        encoding == 'utf-8' and default is None and use_decimal
        and namedtuple_as_object and tuple_as_array
        and not bigint_as_string and not sort_keys
        and not item_sort_key and not for_json
        and int_as_string_bitcount is None
        and not kw
    ):
        return _default_json_encoder.encode(obj)
    if cls is None:
        cls = JSONEncoder
    return cls(
        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
        check_circular=check_circular, indent=indent,
        separators=separators, encoding=encoding, default=default,
        use_decimal=use_decimal,
        namedtuple_as_object=namedtuple_as_object,
        tuple_as_array=tuple_as_array,
        bigint_as_string=bigint_as_string,
        sort_keys=sort_keys,
        item_sort_key=item_sort_key,
        for_json=for_json,
        int_as_string_bitcount=int_as_string_bitcount,
        **kw).encode(obj)

def load(

fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, object_pairs_hook=<class 'collections.OrderedDict'>, use_decimal=False, namedtuple_as_object=True, tuple_as_array=True, **kw)

Deserialize fp (a .read()-supporting file-like object containing a JSON document) to a Python object.

encoding determines the encoding used to interpret any :class:str objects decoded by this instance ('utf-8' by default). It has no effect when decoding :class:unicode objects.

Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:unicode.

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 :class:dict. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting).

object_pairs_hook is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the :class: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, :func: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. :class: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. :class:float).

If use_decimal is true (default: False) then it implies parse_float=decimal.Decimal for parity with dump.

To use a custom HjsonDecoder subclass, specify it with the cls kwarg. NOTE: You should use object_hook or object_pairs_hook instead of subclassing whenever possible.

def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, object_pairs_hook=OrderedDict,
        use_decimal=False, namedtuple_as_object=True, tuple_as_array=True,
        **kw):
    """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
    a JSON document) to a Python object.

    *encoding* determines the encoding used to interpret any
    :class:`str` objects decoded by this instance (``'utf-8'`` by
    default).  It has no effect when decoding :class:`unicode` objects.

    Note that currently only encodings that are a superset of ASCII work,
    strings of other encodings should be passed in as :class:`unicode`.

    *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 :class:`dict`.  This can be used to provide custom
    deserializations (e.g. to support JSON-RPC class hinting).

    *object_pairs_hook* is an optional function that will be called with
    the result of any object literal decode with an ordered list of pairs.
    The return value of *object_pairs_hook* will be used instead of the
    :class:`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, :func:`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. :class:`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. :class:`float`).

    If *use_decimal* is true (default: ``False``) then it implies
    parse_float=decimal.Decimal for parity with ``dump``.

    To use a custom ``HjsonDecoder`` subclass, specify it with the ``cls``
    kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
    of subclassing whenever possible.

    """
    return loads(fp.read(),
        encoding=encoding, cls=cls, object_hook=object_hook,
        parse_float=parse_float, parse_int=parse_int,
        object_pairs_hook=object_pairs_hook,
        use_decimal=use_decimal, **kw)

def loads(

s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, object_pairs_hook=None, use_decimal=False, **kw)

Deserialize s (a str or unicode instance containing a JSON document) to a Python object.

encoding determines the encoding used to interpret any :class:str objects decoded by this instance ('utf-8' by default). It has no effect when decoding :class:unicode objects.

Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:unicode.

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 :class:dict. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting).

object_pairs_hook is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the :class: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, :func: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. :class: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. :class:float).

If use_decimal is true (default: False) then it implies parse_float=decimal.Decimal for parity with dump.

To use a custom HjsonDecoder subclass, specify it with the cls kwarg. NOTE: You should use object_hook or object_pairs_hook instead of subclassing whenever possible.

def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, object_pairs_hook=None,
        use_decimal=False, **kw):
    """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
    document) to a Python object.

    *encoding* determines the encoding used to interpret any
    :class:`str` objects decoded by this instance (``'utf-8'`` by
    default).  It has no effect when decoding :class:`unicode` objects.

    Note that currently only encodings that are a superset of ASCII work,
    strings of other encodings should be passed in as :class:`unicode`.

    *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 :class:`dict`.  This can be used to provide custom
    deserializations (e.g. to support JSON-RPC class hinting).

    *object_pairs_hook* is an optional function that will be called with
    the result of any object literal decode with an ordered list of pairs.
    The return value of *object_pairs_hook* will be used instead of the
    :class:`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, :func:`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. :class:`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. :class:`float`).

    If *use_decimal* is true (default: ``False``) then it implies
    parse_float=decimal.Decimal for parity with ``dump``.

    To use a custom ``HjsonDecoder`` subclass, specify it with the ``cls``
    kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
    of subclassing whenever possible.

    """
    if (cls is None and encoding is None and object_hook is None and
            parse_int is None and parse_float is None and
            object_pairs_hook is None
            and not use_decimal and not kw):
        return _default_decoder.decode(s)
    if cls is None:
        cls = HjsonDecoder
    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 use_decimal:
        if parse_float is not None:
            raise TypeError("use_decimal=True implies parse_float=Decimal")
        kw['parse_float'] = Decimal
    return cls(encoding=encoding, **kw).decode(s)

def simple_first(

kv)

Helper function to pass to item_sort_key to sort simple elements to the top, then container elements.

def simple_first(kv):
    """Helper function to pass to item_sort_key to sort simple
    elements to the top, then container elements.
    """
    return (isinstance(kv[1], (list, dict, tuple)), kv[0])

Classes

class HjsonDecodeError

Subclass of ValueError with the following additional properties:

msg: The unformatted error message doc: The JSON document being parsed pos: The start index of doc where parsing failed end: The end index of doc where parsing failed (may be None) lineno: The line corresponding to pos colno: The column corresponding to pos endlineno: The line corresponding to end (may be None) endcolno: The column corresponding to end (may be None)

class HjsonDecodeError(ValueError):
    """Subclass of ValueError with the following additional properties:

    msg: The unformatted error message
    doc: The JSON document being parsed
    pos: The start index of doc where parsing failed
    end: The end index of doc where parsing failed (may be None)
    lineno: The line corresponding to pos
    colno: The column corresponding to pos
    endlineno: The line corresponding to end (may be None)
    endcolno: The column corresponding to end (may be None)

    """
    # Note that this exception is used from _speedups
    def __init__(self, msg, doc, pos, end=None):
        ValueError.__init__(self, errmsg(msg, doc, pos, end=end))
        self.msg = msg
        self.doc = doc
        self.pos = pos
        self.end = end
        self.lineno, self.colno = linecol(doc, pos)
        if end is not None:
            self.endlineno, self.endcolno = linecol(doc, end)
        else:
            self.endlineno, self.endcolno = None, None

    def __reduce__(self):
        return self.__class__, (self.msg, self.doc, self.pos, self.end)

Ancestors (in MRO)

  • HjsonDecodeError
  • exceptions.ValueError
  • exceptions.StandardError
  • exceptions.Exception
  • exceptions.BaseException
  • __builtin__.object

Class variables

var args

var message

Instance variables

var doc

var end

var msg

var pos

Methods

def __init__(

self, msg, doc, pos, end=None)

def __init__(self, msg, doc, pos, end=None):
    ValueError.__init__(self, errmsg(msg, doc, pos, end=end))
    self.msg = msg
    self.doc = doc
    self.pos = pos
    self.end = end
    self.lineno, self.colno = linecol(doc, pos)
    if end is not None:
        self.endlineno, self.endcolno = linecol(doc, end)
    else:
        self.endlineno, self.endcolno = None, None

class HjsonDecoder

Hjson decoder

Performs the following translations in decoding by default:

+---------------+-------------------+ | JSON | Python | +===============+===================+ | object | dict | +---------------+-------------------+ | array | list | +---------------+-------------------+ | string | str, unicode | +---------------+-------------------+ | number (int) | int, long | +---------------+-------------------+ | number (real) | float | +---------------+-------------------+ | true | True | +---------------+-------------------+ | false | False | +---------------+-------------------+ | null | None | +---------------+-------------------+

class HjsonDecoder(object):
    """Hjson decoder

    Performs the following translations in decoding by default:

    +---------------+-------------------+
    | JSON          | Python            |
    +===============+===================+
    | object        | dict              |
    +---------------+-------------------+
    | array         | list              |
    +---------------+-------------------+
    | string        | str, unicode      |
    +---------------+-------------------+
    | number (int)  | int, long         |
    +---------------+-------------------+
    | number (real) | float             |
    +---------------+-------------------+
    | true          | True              |
    +---------------+-------------------+
    | false         | False             |
    +---------------+-------------------+
    | null          | None              |
    +---------------+-------------------+

    """

    def __init__(self, encoding=None, object_hook=None, parse_float=None,
            parse_int=None, strict=True,
            object_pairs_hook=None):
        """
        *encoding* determines the encoding used to interpret any
        :class:`str` objects decoded by this instance (``'utf-8'`` by
        default).  It has no effect when decoding :class:`unicode` objects.

        Note that currently only encodings that are a superset of ASCII work,
        strings of other encodings should be passed in as :class:`unicode`.

        *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 :class:`dict`.  This can be used to provide custom
        deserializations (e.g. to support JSON-RPC class hinting).

        *object_pairs_hook* is an optional function that will be called with
        the result of any object literal decode with an ordered list of pairs.
        The return value of *object_pairs_hook* will be used instead of the
        :class:`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, :func:`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. :class:`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. :class:`float`).

        *strict* controls the parser's behavior when it encounters an
        invalid control character in a string. The default setting of
        ``True`` means that unescaped control characters are parse errors, if
        ``False`` then control characters will be allowed in strings.

        """
        if encoding is None:
            encoding = DEFAULT_ENCODING
        self.encoding = encoding
        self.object_hook = object_hook
        self.object_pairs_hook = object_pairs_hook
        self.parse_float = parse_float or float
        self.parse_int = parse_int or int
        self.strict = strict
        self.parse_object = JSONObject
        self.parse_array = JSONArray
        self.parse_string = scanstring
        self.parse_mlstring = mlscanstring
        self.parse_tfnns = scantfnns
        self.memo = {}
        (self.scan_once, self.scan_object_once) = make_scanner(self)

    def decode(self, s, _PY3=PY3):
        """Return the Python representation of ``s`` (a ``str`` or ``unicode``
        instance containing a JSON document)

        """
        if _PY3 and isinstance(s, binary_type):
            s = s.decode(self.encoding)
        obj, end = self.raw_decode(s)
        ch, end = getNext(s, end)
        if end != len(s):
            raise HjsonDecodeError("Extra data", s, end, len(s))
        return obj

    def raw_decode(self, s, idx=0, _PY3=PY3):
        """Decode a JSON document from ``s`` (a ``str`` or ``unicode``
        beginning with a JSON document) and return a 2-tuple of the Python
        representation and the index in ``s`` where the document ended.
        Optionally, ``idx`` can be used to specify an offset in ``s`` where
        the JSON document begins.

        This can be used to decode a JSON document from a string that may
        have extraneous data at the end.

        """
        if idx < 0:
            # Ensure that raw_decode bails on negative indexes, the regex
            # would otherwise mask this behavior. #98
            raise HjsonDecodeError('Expecting value', s, idx)
        if _PY3 and not isinstance(s, text_type):
            raise TypeError("Input string must be text, not bytes")
        # strip UTF-8 bom
        if len(s) > idx:
            ord0 = ord(s[idx])
            if ord0 == 0xfeff:
                idx += 1
            elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
                idx += 3

        ch, idx = getNext(s, idx)

        if ch == '{' or ch == '[':
            return self.scan_once(s, idx)
        else:
            # assume we have a root object without braces
            try:
                return self.scan_object_once(s, idx)
            except HjsonDecodeError as e:
                # test if we are dealing with a single JSON value instead (true/false/null/num/"")
                try:
                    return self.scan_once(s, idx)
                except:
                    raise e

Ancestors (in MRO)

Instance variables

var encoding

var memo

var object_hook

var object_pairs_hook

var parse_array

var parse_float

var parse_int

var parse_mlstring

var parse_object

var parse_string

var parse_tfnns

var strict

Methods

def __init__(

self, encoding=None, object_hook=None, parse_float=None, parse_int=None, strict=True, object_pairs_hook=None)

encoding determines the encoding used to interpret any :class:str objects decoded by this instance ('utf-8' by default). It has no effect when decoding :class:unicode objects.

Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:unicode.

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 :class:dict. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting).

object_pairs_hook is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the :class: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, :func: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. :class: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. :class:float).

strict controls the parser's behavior when it encounters an invalid control character in a string. The default setting of True means that unescaped control characters are parse errors, if False then control characters will be allowed in strings.

def __init__(self, encoding=None, object_hook=None, parse_float=None,
        parse_int=None, strict=True,
        object_pairs_hook=None):
    """
    *encoding* determines the encoding used to interpret any
    :class:`str` objects decoded by this instance (``'utf-8'`` by
    default).  It has no effect when decoding :class:`unicode` objects.
    Note that currently only encodings that are a superset of ASCII work,
    strings of other encodings should be passed in as :class:`unicode`.
    *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 :class:`dict`.  This can be used to provide custom
    deserializations (e.g. to support JSON-RPC class hinting).
    *object_pairs_hook* is an optional function that will be called with
    the result of any object literal decode with an ordered list of pairs.
    The return value of *object_pairs_hook* will be used instead of the
    :class:`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, :func:`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. :class:`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. :class:`float`).
    *strict* controls the parser's behavior when it encounters an
    invalid control character in a string. The default setting of
    ``True`` means that unescaped control characters are parse errors, if
    ``False`` then control characters will be allowed in strings.
    """
    if encoding is None:
        encoding = DEFAULT_ENCODING
    self.encoding = encoding
    self.object_hook = object_hook
    self.object_pairs_hook = object_pairs_hook
    self.parse_float = parse_float or float
    self.parse_int = parse_int or int
    self.strict = strict
    self.parse_object = JSONObject
    self.parse_array = JSONArray
    self.parse_string = scanstring
    self.parse_mlstring = mlscanstring
    self.parse_tfnns = scantfnns
    self.memo = {}
    (self.scan_once, self.scan_object_once) = make_scanner(self)

def decode(

self, s, _PY3=False)

Return the Python representation of s (a str or unicode instance containing a JSON document)

def decode(self, s, _PY3=PY3):
    """Return the Python representation of ``s`` (a ``str`` or ``unicode``
    instance containing a JSON document)
    """
    if _PY3 and isinstance(s, binary_type):
        s = s.decode(self.encoding)
    obj, end = self.raw_decode(s)
    ch, end = getNext(s, end)
    if end != len(s):
        raise HjsonDecodeError("Extra data", s, end, len(s))
    return obj

def raw_decode(

self, s, idx=0, _PY3=False)

Decode a JSON document from s (a str or unicode beginning with a JSON document) and return a 2-tuple of the Python representation and the index in s where the document ended. Optionally, idx can be used to specify an offset in s where the JSON document begins.

This can be used to decode a JSON document from a string that may have extraneous data at the end.

def raw_decode(self, s, idx=0, _PY3=PY3):
    """Decode a JSON document from ``s`` (a ``str`` or ``unicode``
    beginning with a JSON document) and return a 2-tuple of the Python
    representation and the index in ``s`` where the document ended.
    Optionally, ``idx`` can be used to specify an offset in ``s`` where
    the JSON document begins.
    This can be used to decode a JSON document from a string that may
    have extraneous data at the end.
    """
    if idx < 0:
        # Ensure that raw_decode bails on negative indexes, the regex
        # would otherwise mask this behavior. #98
        raise HjsonDecodeError('Expecting value', s, idx)
    if _PY3 and not isinstance(s, text_type):
        raise TypeError("Input string must be text, not bytes")
    # strip UTF-8 bom
    if len(s) > idx:
        ord0 = ord(s[idx])
        if ord0 == 0xfeff:
            idx += 1
        elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
            idx += 3
    ch, idx = getNext(s, idx)
    if ch == '{' or ch == '[':
        return self.scan_once(s, idx)
    else:
        # assume we have a root object without braces
        try:
            return self.scan_object_once(s, idx)
        except HjsonDecodeError as e:
            # test if we are dealing with a single JSON value instead (true/false/null/num/"")
            try:
                return self.scan_once(s, idx)
            except:
                raise e

class HjsonEncoder

Extensible JSON http://json.org encoder for Python data structures.

Supports the following objects and types by default:

+-------------------+---------------+ | Python | JSON | +===================+===============+ | dict, namedtuple | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str, unicode | string | +-------------------+---------------+ | int, long, 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).

class HjsonEncoder(object):
    """Extensible JSON  encoder for Python data structures.

    Supports the following objects and types by default:

    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict, namedtuple  | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str, unicode      | string        |
    +-------------------+---------------+
    | int, long, 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``).

    """

    def __init__(self, skipkeys=False, ensure_ascii=True,
                 check_circular=True, sort_keys=False,
                 indent='  ', encoding='utf-8', default=None,
                 use_decimal=True, namedtuple_as_object=True,
                 tuple_as_array=True, bigint_as_string=False,
                 item_sort_key=None, for_json=False,
                 int_as_string_bitcount=None):
        """Constructor for HjsonEncoder, with sensible defaults.

        If skipkeys is false, then it is a TypeError to attempt
        encoding of keys that are not str, int, long, 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 unicode characters escaped.  If
        ensure_ascii is false, the output will be unicode object.

        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 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 string, then JSON array elements and object members
        will be pretty-printed with a newline followed by that string repeated
        for each level of nesting.

        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``.

        If encoding is not None, then all input strings will be
        transformed into unicode using that encoding prior to JSON-encoding.
        The default is UTF-8.

        If use_decimal is true (not the default), ``decimal.Decimal`` will
        be supported directly by the encoder. For the inverse, decode JSON
        with ``parse_float=decimal.Decimal``.

        If namedtuple_as_object is true (the default), objects with
        ``_asdict()`` methods will be encoded as JSON objects.

        If tuple_as_array is true (the default), tuple (and subclasses) will
        be encoded as JSON arrays.

        If bigint_as_string is true (not the default), ints 2**53 and higher
        or lower than -2**53 will be encoded as strings. This is to avoid the
        rounding that happens in Javascript otherwise.

        If int_as_string_bitcount is a positive number (n), then int of size
        greater than or equal to 2**n or lower than or equal to -2**n will be
        encoded as strings.

        If specified, item_sort_key is a callable used to sort the items in
        each dictionary. This is useful if you want to sort items other than
        in alphabetical order by key.

        If for_json is true (not the default), objects with a ``for_json()``
        method will use the return value of that method for encoding as JSON
        instead of the object.

        """

        self.skipkeys = skipkeys
        self.ensure_ascii = ensure_ascii
        self.check_circular = check_circular
        self.sort_keys = sort_keys
        self.use_decimal = use_decimal
        self.namedtuple_as_object = namedtuple_as_object
        self.tuple_as_array = tuple_as_array
        self.bigint_as_string = bigint_as_string
        self.item_sort_key = item_sort_key
        self.for_json = for_json
        self.int_as_string_bitcount = int_as_string_bitcount
        if indent is not None and not isinstance(indent, string_types):
            indent = indent * ' '
        elif indent is None:
            indent = '  '
        self.indent = indent
        if default is not None:
            self.default = default
        self.encoding = encoding

    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)
                return HjsonEncoder.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.

        >>> from hjson import HjsonEncoder
        >>> HjsonEncoder().encode({"foo": ["bar", "baz"]})
        '{"foo": ["bar", "baz"]}'

        """
        # This is for extremely simple cases and benchmarks.
        if isinstance(o, binary_type):
            _encoding = self.encoding
            if (_encoding is not None and not (_encoding == 'utf-8')):
                o = o.decode(_encoding)

        # 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)
        if self.ensure_ascii:
            return ''.join(chunks)
        else:
            return u''.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 HjsonEncoder().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
        if self.encoding != 'utf-8':
            def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
                if isinstance(o, binary_type):
                    o = o.decode(_encoding)
                return _orig_encoder(o)

        def floatstr(o, _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
            # 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 or o == _inf or o == _neginf:
                return 'null'
            else:
                return _repr(o)

        key_memo = {}
        int_as_string_bitcount = (
            53 if self.bigint_as_string else self.int_as_string_bitcount)
        _iterencode = _make_iterencode(
            markers, self.default, _encoder, self.indent, floatstr,
            self.sort_keys, self.skipkeys, _one_shot, self.use_decimal,
            self.namedtuple_as_object, self.tuple_as_array,
            int_as_string_bitcount,
            self.item_sort_key, self.encoding, self.for_json,
            Decimal=Decimal)
        try:
            return _iterencode(o, 0, True)
        finally:
            key_memo.clear()

Ancestors (in MRO)

Instance variables

var bigint_as_string

var check_circular

var encoding

var ensure_ascii

var for_json

var indent

var int_as_string_bitcount

var item_sort_key

var namedtuple_as_object

var skipkeys

var sort_keys

var tuple_as_array

var use_decimal

Methods

def __init__(

self, skipkeys=False, ensure_ascii=True, check_circular=True, sort_keys=False, indent=' ', encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None)

Constructor for HjsonEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, long, 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 unicode characters escaped. If ensure_ascii is false, the output will be unicode object.

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 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 string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting.

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.

If encoding is not None, then all input strings will be transformed into unicode using that encoding prior to JSON-encoding. The default is UTF-8.

If use_decimal is true (not the default), decimal.Decimal will be supported directly by the encoder. For the inverse, decode JSON with parse_float=decimal.Decimal.

If namedtuple_as_object is true (the default), objects with _asdict() methods will be encoded as JSON objects.

If tuple_as_array is true (the default), tuple (and subclasses) will be encoded as JSON arrays.

If bigint_as_string is true (not the default), ints 253 and higher or lower than -253 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise.

If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2n or lower than or equal to -2n will be encoded as strings.

If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key.

If for_json is true (not the default), objects with a for_json() method will use the return value of that method for encoding as JSON instead of the object.

def __init__(self, skipkeys=False, ensure_ascii=True,
             check_circular=True, sort_keys=False,
             indent='  ', encoding='utf-8', default=None,
             use_decimal=True, namedtuple_as_object=True,
             tuple_as_array=True, bigint_as_string=False,
             item_sort_key=None, for_json=False,
             int_as_string_bitcount=None):
    """Constructor for HjsonEncoder, with sensible defaults.
    If skipkeys is false, then it is a TypeError to attempt
    encoding of keys that are not str, int, long, 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 unicode characters escaped.  If
    ensure_ascii is false, the output will be unicode object.
    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 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 string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting.
    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``.
    If encoding is not None, then all input strings will be
    transformed into unicode using that encoding prior to JSON-encoding.
    The default is UTF-8.
    If use_decimal is true (not the default), ``decimal.Decimal`` will
    be supported directly by the encoder. For the inverse, decode JSON
    with ``parse_float=decimal.Decimal``.
    If namedtuple_as_object is true (the default), objects with
    ``_asdict()`` methods will be encoded as JSON objects.
    If tuple_as_array is true (the default), tuple (and subclasses) will
    be encoded as JSON arrays.
    If bigint_as_string is true (not the default), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise.
    If int_as_string_bitcount is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.
    If specified, item_sort_key is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key.
    If for_json is true (not the default), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.
    """
    self.skipkeys = skipkeys
    self.ensure_ascii = ensure_ascii
    self.check_circular = check_circular
    self.sort_keys = sort_keys
    self.use_decimal = use_decimal
    self.namedtuple_as_object = namedtuple_as_object
    self.tuple_as_array = tuple_as_array
    self.bigint_as_string = bigint_as_string
    self.item_sort_key = item_sort_key
    self.for_json = for_json
    self.int_as_string_bitcount = int_as_string_bitcount
    if indent is not None and not isinstance(indent, string_types):
        indent = indent * ' '
    elif indent is None:
        indent = '  '
    self.indent = indent
    if default is not None:
        self.default = default
    self.encoding = encoding

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)
    return HjsonEncoder.default(self, o)
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)
            return HjsonEncoder.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.

from hjson import HjsonEncoder HjsonEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'

def encode(self, o):
    """Return a JSON string representation of a Python data structure.
    >>> from hjson import HjsonEncoder
    >>> HjsonEncoder().encode({"foo": ["bar", "baz"]})
    '{"foo": ["bar", "baz"]}'
    """
    # This is for extremely simple cases and benchmarks.
    if isinstance(o, binary_type):
        _encoding = self.encoding
        if (_encoding is not None and not (_encoding == 'utf-8')):
            o = o.decode(_encoding)
    # 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)
    if self.ensure_ascii:
        return ''.join(chunks)
    else:
        return u''.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 HjsonEncoder().iterencode(bigobject):
    mysocket.write(chunk)
def iterencode(self, o, _one_shot=False):
    """Encode the given object and yield each string
    representation as available.
    For example::
        for chunk in HjsonEncoder().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
    if self.encoding != 'utf-8':
        def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
            if isinstance(o, binary_type):
                o = o.decode(_encoding)
            return _orig_encoder(o)
    def floatstr(o, _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
        # 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 or o == _inf or o == _neginf:
            return 'null'
        else:
            return _repr(o)
    key_memo = {}
    int_as_string_bitcount = (
        53 if self.bigint_as_string else self.int_as_string_bitcount)
    _iterencode = _make_iterencode(
        markers, self.default, _encoder, self.indent, floatstr,
        self.sort_keys, self.skipkeys, _one_shot, self.use_decimal,
        self.namedtuple_as_object, self.tuple_as_array,
        int_as_string_bitcount,
        self.item_sort_key, self.encoding, self.for_json,
        Decimal=Decimal)
    try:
        return _iterencode(o, 0, True)
    finally:
        key_memo.clear()

class JSONEncoder

Extensible JSON http://json.org encoder for Python data structures.

Supports the following objects and types by default:

+-------------------+---------------+ | Python | JSON | +===================+===============+ | dict, namedtuple | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str, unicode | string | +-------------------+---------------+ | int, long, 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).

class JSONEncoder(object):
    """Extensible JSON  encoder for Python data structures.

    Supports the following objects and types by default:

    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict, namedtuple  | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str, unicode      | string        |
    +-------------------+---------------+
    | int, long, 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, sort_keys=False,
                 indent=None, separators=None, encoding='utf-8', default=None,
                 use_decimal=True, namedtuple_as_object=True,
                 tuple_as_array=True, bigint_as_string=False,
                 item_sort_key=None, for_json=False,
                 int_as_string_bitcount=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, long, 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 unicode characters escaped.  If
        ensure_ascii is false, the output will be unicode object.

        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 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 string, then JSON array elements and object members
        will be pretty-printed with a newline followed by that string repeated
        for each level of nesting. ``None`` (the default) selects the most compact
        representation without any newlines. For backwards compatibility with
        versions of hjson earlier than 2.1.0, an integer is also accepted
        and is converted to a string with that many spaces.

        If specified, separators should be an (item_separator, key_separator)
        tuple.  The default is (', ', ': ') if *indent* is ``None`` and
        (',', ': ') otherwise.  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``.

        If encoding is not None, then all input strings will be
        transformed into unicode using that encoding prior to JSON-encoding.
        The default is UTF-8.

        If use_decimal is true (not the default), ``decimal.Decimal`` will
        be supported directly by the encoder. For the inverse, decode JSON
        with ``parse_float=decimal.Decimal``.

        If namedtuple_as_object is true (the default), objects with
        ``_asdict()`` methods will be encoded as JSON objects.

        If tuple_as_array is true (the default), tuple (and subclasses) will
        be encoded as JSON arrays.

        If bigint_as_string is true (not the default), ints 2**53 and higher
        or lower than -2**53 will be encoded as strings. This is to avoid the
        rounding that happens in Javascript otherwise.

        If int_as_string_bitcount is a positive number (n), then int of size
        greater than or equal to 2**n or lower than or equal to -2**n will be
        encoded as strings.

        If specified, item_sort_key is a callable used to sort the items in
        each dictionary. This is useful if you want to sort items other than
        in alphabetical order by key.

        If for_json is true (not the default), objects with a ``for_json()``
        method will use the return value of that method for encoding as JSON
        instead of the object.

        """

        self.skipkeys = skipkeys
        self.ensure_ascii = ensure_ascii
        self.check_circular = check_circular
        self.sort_keys = sort_keys
        self.use_decimal = use_decimal
        self.namedtuple_as_object = namedtuple_as_object
        self.tuple_as_array = tuple_as_array
        self.bigint_as_string = bigint_as_string
        self.item_sort_key = item_sort_key
        self.for_json = for_json
        self.int_as_string_bitcount = int_as_string_bitcount
        if indent is not None and not isinstance(indent, string_types):
            indent = indent * ' '
        self.indent = indent
        if separators is not None:
            self.item_separator, self.key_separator = separators
        elif indent is not None:
            self.item_separator = ','
        if default is not None:
            self.default = default
        self.encoding = encoding

    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)
                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.

        >>> from hjson import JSONEncoder
        >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
        '{"foo": ["bar", "baz"]}'

        """
        # This is for extremely simple cases and benchmarks.
        if isinstance(o, binary_type):
            _encoding = self.encoding
            if (_encoding is not None and not (_encoding == 'utf-8')):
                o = o.decode(_encoding)
        if isinstance(o, string_types):
            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)
        if self.ensure_ascii:
            return ''.join(chunks)
        else:
            return u''.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
        if self.encoding != 'utf-8':
            def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
                if isinstance(o, binary_type):
                    o = o.decode(_encoding)
                return _orig_encoder(o)

        def floatstr(o, _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
            # 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 = 'null'
            elif o == _inf:
                text = 'null'
            elif o == _neginf:
                text = 'null'
            else:
                return _repr(o)

            return text

        key_memo = {}
        int_as_string_bitcount = (
            53 if self.bigint_as_string else self.int_as_string_bitcount)
        _iterencode = _make_iterencode(
            markers, self.default, _encoder, self.indent, floatstr,
            self.key_separator, self.item_separator, self.sort_keys,
            self.skipkeys, _one_shot, self.use_decimal,
            self.namedtuple_as_object, self.tuple_as_array,
            int_as_string_bitcount,
            self.item_sort_key, self.encoding, self.for_json,
            Decimal=Decimal)
        try:
            return _iterencode(o, 0)
        finally:
            key_memo.clear()

Ancestors (in MRO)

Class variables

var item_separator

var key_separator

Instance variables

var bigint_as_string

var check_circular

var encoding

var ensure_ascii

var for_json

var indent

var int_as_string_bitcount

var item_sort_key

var namedtuple_as_object

var skipkeys

var sort_keys

var tuple_as_array

var use_decimal

Methods

def __init__(

self, skipkeys=False, ensure_ascii=True, check_circular=True, sort_keys=False, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, int_as_string_bitcount=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, long, 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 unicode characters escaped. If ensure_ascii is false, the output will be unicode object.

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 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 string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. None (the default) selects the most compact representation without any newlines. For backwards compatibility with versions of hjson earlier than 2.1.0, an integer is also accepted and is converted to a string with that many spaces.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (', ', ': ') if indent is None and (',', ': ') otherwise. 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.

If encoding is not None, then all input strings will be transformed into unicode using that encoding prior to JSON-encoding. The default is UTF-8.

If use_decimal is true (not the default), decimal.Decimal will be supported directly by the encoder. For the inverse, decode JSON with parse_float=decimal.Decimal.

If namedtuple_as_object is true (the default), objects with _asdict() methods will be encoded as JSON objects.

If tuple_as_array is true (the default), tuple (and subclasses) will be encoded as JSON arrays.

If bigint_as_string is true (not the default), ints 253 and higher or lower than -253 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise.

If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2n or lower than or equal to -2n will be encoded as strings.

If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key.

If for_json is true (not the default), objects with a for_json() method will use the return value of that method for encoding as JSON instead of the object.

def __init__(self, skipkeys=False, ensure_ascii=True,
             check_circular=True, sort_keys=False,
             indent=None, separators=None, encoding='utf-8', default=None,
             use_decimal=True, namedtuple_as_object=True,
             tuple_as_array=True, bigint_as_string=False,
             item_sort_key=None, for_json=False,
             int_as_string_bitcount=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, long, 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 unicode characters escaped.  If
    ensure_ascii is false, the output will be unicode object.
    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 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 string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
    representation without any newlines. For backwards compatibility with
    versions of hjson earlier than 2.1.0, an integer is also accepted
    and is converted to a string with that many spaces.
    If specified, separators should be an (item_separator, key_separator)
    tuple.  The default is (', ', ': ') if *indent* is ``None`` and
    (',', ': ') otherwise.  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``.
    If encoding is not None, then all input strings will be
    transformed into unicode using that encoding prior to JSON-encoding.
    The default is UTF-8.
    If use_decimal is true (not the default), ``decimal.Decimal`` will
    be supported directly by the encoder. For the inverse, decode JSON
    with ``parse_float=decimal.Decimal``.
    If namedtuple_as_object is true (the default), objects with
    ``_asdict()`` methods will be encoded as JSON objects.
    If tuple_as_array is true (the default), tuple (and subclasses) will
    be encoded as JSON arrays.
    If bigint_as_string is true (not the default), ints 2**53 and higher
    or lower than -2**53 will be encoded as strings. This is to avoid the
    rounding that happens in Javascript otherwise.
    If int_as_string_bitcount is a positive number (n), then int of size
    greater than or equal to 2**n or lower than or equal to -2**n will be
    encoded as strings.
    If specified, item_sort_key is a callable used to sort the items in
    each dictionary. This is useful if you want to sort items other than
    in alphabetical order by key.
    If for_json is true (not the default), objects with a ``for_json()``
    method will use the return value of that method for encoding as JSON
    instead of the object.
    """
    self.skipkeys = skipkeys
    self.ensure_ascii = ensure_ascii
    self.check_circular = check_circular
    self.sort_keys = sort_keys
    self.use_decimal = use_decimal
    self.namedtuple_as_object = namedtuple_as_object
    self.tuple_as_array = tuple_as_array
    self.bigint_as_string = bigint_as_string
    self.item_sort_key = item_sort_key
    self.for_json = for_json
    self.int_as_string_bitcount = int_as_string_bitcount
    if indent is not None and not isinstance(indent, string_types):
        indent = indent * ' '
    self.indent = indent
    if separators is not None:
        self.item_separator, self.key_separator = separators
    elif indent is not None:
        self.item_separator = ','
    if default is not None:
        self.default = default
    self.encoding = encoding

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)
    return JSONEncoder.default(self, o)
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)
            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.

from hjson import JSONEncoder JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'

def encode(self, o):
    """Return a JSON string representation of a Python data structure.
    >>> from hjson import JSONEncoder
    >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
    '{"foo": ["bar", "baz"]}'
    """
    # This is for extremely simple cases and benchmarks.
    if isinstance(o, binary_type):
        _encoding = self.encoding
        if (_encoding is not None and not (_encoding == 'utf-8')):
            o = o.decode(_encoding)
    if isinstance(o, string_types):
        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)
    if self.ensure_ascii:
        return ''.join(chunks)
    else:
        return u''.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)
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
    if self.encoding != 'utf-8':
        def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
            if isinstance(o, binary_type):
                o = o.decode(_encoding)
            return _orig_encoder(o)
    def floatstr(o, _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
        # 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 = 'null'
        elif o == _inf:
            text = 'null'
        elif o == _neginf:
            text = 'null'
        else:
            return _repr(o)
        return text
    key_memo = {}
    int_as_string_bitcount = (
        53 if self.bigint_as_string else self.int_as_string_bitcount)
    _iterencode = _make_iterencode(
        markers, self.default, _encoder, self.indent, floatstr,
        self.key_separator, self.item_separator, self.sort_keys,
        self.skipkeys, _one_shot, self.use_decimal,
        self.namedtuple_as_object, self.tuple_as_array,
        int_as_string_bitcount,
        self.item_sort_key, self.encoding, self.for_json,
        Decimal=Decimal)
    try:
        return _iterencode(o, 0)
    finally:
        key_memo.clear()

class OrderedDict

Dictionary that remembers insertion order

class OrderedDict(dict):
    'Dictionary that remembers insertion order'
    # An inherited dict maps keys to values.
    # The inherited dict provides __getitem__, __len__, __contains__, and get.
    # The remaining methods are order-aware.
    # Big-O running times for all methods are the same as regular dictionaries.

    # The internal self.__map dict maps keys to links in a doubly linked list.
    # The circular doubly linked list starts and ends with a sentinel element.
    # The sentinel element never gets deleted (this simplifies the algorithm).
    # Each link is stored as a list of length three:  [PREV, NEXT, KEY].

    def __init__(*args, **kwds):
        '''Initialize an ordered dictionary.  The signature is the same as
        regular dictionaries, but keyword arguments are not recommended because
        their insertion order is arbitrary.

        '''
        if not args:
            raise TypeError("descriptor '__init__' of 'OrderedDict' object "
                            "needs an argument")
        self = args[0]
        args = args[1:]
        if len(args) > 1:
            raise TypeError('expected at most 1 arguments, got %d' % len(args))
        try:
            self.__root
        except AttributeError:
            self.__root = root = []                     # sentinel node
            root[:] = [root, root, None]
            self.__map = {}
        self.__update(*args, **kwds)

    def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
        'od.__setitem__(i, y) <==> od[i]=y'
        # Setting a new item creates a new link at the end of the linked list,
        # and the inherited dictionary is updated with the new key/value pair.
        if key not in self:
            root = self.__root
            last = root[0]
            last[1] = root[0] = self.__map[key] = [last, root, key]
        return dict_setitem(self, key, value)

    def __delitem__(self, key, dict_delitem=dict.__delitem__):
        'od.__delitem__(y) <==> del od[y]'
        # Deleting an existing item uses self.__map to find the link which gets
        # removed by updating the links in the predecessor and successor nodes.
        dict_delitem(self, key)
        link_prev, link_next, _ = self.__map.pop(key)
        link_prev[1] = link_next                        # update link_prev[NEXT]
        link_next[0] = link_prev                        # update link_next[PREV]

    def __iter__(self):
        'od.__iter__() <==> iter(od)'
        # Traverse the linked list in order.
        root = self.__root
        curr = root[1]                                  # start at the first node
        while curr is not root:
            yield curr[2]                               # yield the curr[KEY]
            curr = curr[1]                              # move to next node

    def __reversed__(self):
        'od.__reversed__() <==> reversed(od)'
        # Traverse the linked list in reverse order.
        root = self.__root
        curr = root[0]                                  # start at the last node
        while curr is not root:
            yield curr[2]                               # yield the curr[KEY]
            curr = curr[0]                              # move to previous node

    def clear(self):
        'od.clear() -> None.  Remove all items from od.'
        root = self.__root
        root[:] = [root, root, None]
        self.__map.clear()
        dict.clear(self)

    # -- the following methods do not depend on the internal structure --

    def keys(self):
        'od.keys() -> list of keys in od'
        return list(self)

    def values(self):
        'od.values() -> list of values in od'
        return [self[key] for key in self]

    def items(self):
        'od.items() -> list of (key, value) pairs in od'
        return [(key, self[key]) for key in self]

    def iterkeys(self):
        'od.iterkeys() -> an iterator over the keys in od'
        return iter(self)

    def itervalues(self):
        'od.itervalues -> an iterator over the values in od'
        for k in self:
            yield self[k]

    def iteritems(self):
        'od.iteritems -> an iterator over the (key, value) pairs in od'
        for k in self:
            yield (k, self[k])

    update = MutableMapping.update

    __update = update # let subclasses override update without breaking __init__

    __marker = object()

    def pop(self, key, default=__marker):
        '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
        value.  If key is not found, d is returned if given, otherwise KeyError
        is raised.

        '''
        if key in self:
            result = self[key]
            del self[key]
            return result
        if default is self.__marker:
            raise KeyError(key)
        return default

    def setdefault(self, key, default=None):
        'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
        if key in self:
            return self[key]
        self[key] = default
        return default

    def popitem(self, last=True):
        '''od.popitem() -> (k, v), return and remove a (key, value) pair.
        Pairs are returned in LIFO order if last is true or FIFO order if false.

        '''
        if not self:
            raise KeyError('dictionary is empty')
        key = next(reversed(self) if last else iter(self))
        value = self.pop(key)
        return key, value

    def __repr__(self, _repr_running={}):
        'od.__repr__() <==> repr(od)'
        call_key = id(self), _get_ident()
        if call_key in _repr_running:
            return '...'
        _repr_running[call_key] = 1
        try:
            if not self:
                return '%s()' % (self.__class__.__name__,)
            return '%s(%r)' % (self.__class__.__name__, self.items())
        finally:
            del _repr_running[call_key]

    def __reduce__(self):
        'Return state information for pickling'
        items = [[k, self[k]] for k in self]
        inst_dict = vars(self).copy()
        for k in vars(OrderedDict()):
            inst_dict.pop(k, None)
        if inst_dict:
            return (self.__class__, (items,), inst_dict)
        return self.__class__, (items,)

    def copy(self):
        'od.copy() -> a shallow copy of od'
        return self.__class__(self)

    @classmethod
    def fromkeys(cls, iterable, value=None):
        '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
        If not specified, the value defaults to None.

        '''
        self = cls()
        for key in iterable:
            self[key] = value
        return self

    def __eq__(self, other):
        '''od.__eq__(y) <==> od==y.  Comparison to another OD is order-sensitive
        while comparison to a regular mapping is order-insensitive.

        '''
        if isinstance(other, OrderedDict):
            return dict.__eq__(self, other) and all(_imap(_eq, self, other))
        return dict.__eq__(self, other)

    def __ne__(self, other):
        'od.__ne__(y) <==> od!=y'
        return not self == other

    # -- the following methods support python 3.x style dictionary views --

    def viewkeys(self):
        "od.viewkeys() -> a set-like object providing a view on od's keys"
        return KeysView(self)

    def viewvalues(self):
        "od.viewvalues() -> an object providing a view on od's values"
        return ValuesView(self)

    def viewitems(self):
        "od.viewitems() -> a set-like object providing a view on od's items"
        return ItemsView(self)

Ancestors (in MRO)

Methods

def __init__(

*args, **kwds)

Initialize an ordered dictionary. The signature is the same as regular dictionaries, but keyword arguments are not recommended because their insertion order is arbitrary.

def __init__(*args, **kwds):
    '''Initialize an ordered dictionary.  The signature is the same as
    regular dictionaries, but keyword arguments are not recommended because
    their insertion order is arbitrary.
    '''
    if not args:
        raise TypeError("descriptor '__init__' of 'OrderedDict' object "
                        "needs an argument")
    self = args[0]
    args = args[1:]
    if len(args) > 1:
        raise TypeError('expected at most 1 arguments, got %d' % len(args))
    try:
        self.__root
    except AttributeError:
        self.__root = root = []                     # sentinel node
        root[:] = [root, root, None]
        self.__map = {}
    self.__update(*args, **kwds)

def clear(

self)

od.clear() -> None. Remove all items from od.

def clear(self):
    'od.clear() -> None.  Remove all items from od.'
    root = self.__root
    root[:] = [root, root, None]
    self.__map.clear()
    dict.clear(self)

def copy(

self)

od.copy() -> a shallow copy of od

def copy(self):
    'od.copy() -> a shallow copy of od'
    return self.__class__(self)

def fromkeys(

cls, iterable, value=None)

OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. If not specified, the value defaults to None.

@classmethod
def fromkeys(cls, iterable, value=None):
    '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
    If not specified, the value defaults to None.
    '''
    self = cls()
    for key in iterable:
        self[key] = value
    return self

def items(

self)

od.items() -> list of (key, value) pairs in od

def items(self):
    'od.items() -> list of (key, value) pairs in od'
    return [(key, self[key]) for key in self]

def iteritems(

self)

od.iteritems -> an iterator over the (key, value) pairs in od

def iteritems(self):
    'od.iteritems -> an iterator over the (key, value) pairs in od'
    for k in self:
        yield (k, self[k])

def iterkeys(

self)

od.iterkeys() -> an iterator over the keys in od

def iterkeys(self):
    'od.iterkeys() -> an iterator over the keys in od'
    return iter(self)

def itervalues(

self)

od.itervalues -> an iterator over the values in od

def itervalues(self):
    'od.itervalues -> an iterator over the values in od'
    for k in self:
        yield self[k]

def keys(

self)

od.keys() -> list of keys in od

def keys(self):
    'od.keys() -> list of keys in od'
    return list(self)

def pop(

self, key, default=<object object at 0x1081ca0a0>)

od.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised.

def pop(self, key, default=__marker):
    '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
    value.  If key is not found, d is returned if given, otherwise KeyError
    is raised.
    '''
    if key in self:
        result = self[key]
        del self[key]
        return result
    if default is self.__marker:
        raise KeyError(key)
    return default

def popitem(

self, last=True)

od.popitem() -> (k, v), return and remove a (key, value) pair. Pairs are returned in LIFO order if last is true or FIFO order if false.

def popitem(self, last=True):
    '''od.popitem() -> (k, v), return and remove a (key, value) pair.
    Pairs are returned in LIFO order if last is true or FIFO order if false.
    '''
    if not self:
        raise KeyError('dictionary is empty')
    key = next(reversed(self) if last else iter(self))
    value = self.pop(key)
    return key, value

def setdefault(

self, key, default=None)

od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od

def setdefault(self, key, default=None):
    'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
    if key in self:
        return self[key]
    self[key] = default
    return default

def update(

*args, **kwds)

D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

def update(*args, **kwds):
    ''' D.update([E, ]**F) -> None.  Update D from mapping/iterable E and F.
        If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
        If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
        In either case, this is followed by: for k, v in F.items(): D[k] = v
    '''
    if not args:
        raise TypeError("descriptor 'update' of 'MutableMapping' object "
                        "needs an argument")
    self = args[0]
    args = args[1:]
    if len(args) > 1:
        raise TypeError('update expected at most 1 arguments, got %d' %
                        len(args))
    if args:
        other = args[0]
        if isinstance(other, Mapping):
            for key in other:
                self[key] = other[key]
        elif hasattr(other, "keys"):
            for key in other.keys():
                self[key] = other[key]
        else:
            for key, value in other:
                self[key] = value
    for key, value in kwds.items():
        self[key] = value

def values(

self)

od.values() -> list of values in od

def values(self):
    'od.values() -> list of values in od'
    return [self[key] for key in self]

def viewitems(

self)

od.viewitems() -> a set-like object providing a view on od's items

def viewitems(self):
    "od.viewitems() -> a set-like object providing a view on od's items"
    return ItemsView(self)

def viewkeys(

self)

od.viewkeys() -> a set-like object providing a view on od's keys

def viewkeys(self):
    "od.viewkeys() -> a set-like object providing a view on od's keys"
    return KeysView(self)

def viewvalues(

self)

od.viewvalues() -> an object providing a view on od's values

def viewvalues(self):
    "od.viewvalues() -> an object providing a view on od's values"
    return ValuesView(self)
hjson-py-3.0.2/history.md000066400000000000000000000015731372777051600153330ustar00rootroot00000000000000# History - v3.0.2 - Use relative import - Fix empty multiline strings - v3.0.1 - change hjson (cli tool) to use unicode - v3.0.0 - add support for single quoted strings - v2.0.7 - multiline strings allow tabs - v2.0.6 - add support for blank and comment only files - v2.0.5 - fix stringify for strings staring with a punctuator char - v2.0.2 - fix err on bad ML string - v2.0.1 - move to hjson org - v2.0.0 - fix quoteless string starting with punctuator - v1.5.8 - add CLI scripts for pip - v1.5.6 - fix dump for comment tokens in keyname - v1.5.4 - fix decode/encode single JSON value files - v1.5.3 - fix trailing whitespace in keyname - v1.5.2 - fix trailing space in quoteless strings - v1.5.1 - better error messages & root check - v1.5.0 - Added support for optional root braces - v1.4.1 - Added documentation, links. - v1.4.0 - First release. hjson-py-3.0.2/hjson/000077500000000000000000000000001372777051600144235ustar00rootroot00000000000000hjson-py-3.0.2/hjson/__init__.py000066400000000000000000000637151372777051600165500ustar00rootroot00000000000000r"""Hjson, the Human JSON. A configuration file format that caters to humans and helps reduce the errors they make. For details and syntax see . Decoding Hjson:: >>> import hjson >>> text = "{\n foo: a\n bar: 1\n}" >>> hjson.loads(text) OrderedDict([('foo', 'a'), ('bar', 1)]) Encoding Python object hierarchies:: >>> import hjson >>> # hjson.dumps({'foo': 'text', 'bar': (1, 2)}) >>> hjson.dumps(OrderedDict([('foo', 'text'), ('bar', (1, 2))])) '{\n foo: text\n bar:\n [\n 1\n 2\n ]\n}' Encoding as JSON:: Note that this is probably not as performant as the simplejson version. >>> import hjson >>> hjson.dumpsJSON(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' Using hjson.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m hjson.tool { json: obj } Other formats are -c for compact or -j for formatted JSON. """ from __future__ import absolute_import __version__ = '3.0.2' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'dumpJSON', 'dumpsJSON', 'HjsonDecoder', 'HjsonDecodeError', 'HjsonEncoder', 'JSONEncoder', 'OrderedDict', 'simple_first', ] # based on simplejson by # __author__ = 'Bob Ippolito ' __author__ = 'Christian Zangl ' from decimal import Decimal from .scanner import HjsonDecodeError from .decoder import HjsonDecoder from .encoderH import HjsonEncoder from .encoder import JSONEncoder def _import_OrderedDict(): import collections try: return collections.OrderedDict except AttributeError: from . import ordered_dict return ordered_dict.OrderedDict OrderedDict = _import_OrderedDict() _default_decoder = HjsonDecoder(encoding=None, object_hook=None, object_pairs_hook=OrderedDict) def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, object_pairs_hook=OrderedDict, use_decimal=False, namedtuple_as_object=True, tuple_as_array=True, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. *encoding* determines the encoding used to interpret any :class:`str` objects decoded by this instance (``'utf-8'`` by default). It has no effect when decoding :class:`unicode` objects. Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:`unicode`. *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 :class:`dict`. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting). *object_pairs_hook* is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of *object_pairs_hook* will be used instead of the :class:`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, :func:`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. :class:`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. :class:`float`). If *use_decimal* is true (default: ``False``) then it implies parse_float=decimal.Decimal for parity with ``dump``. To use a custom ``HjsonDecoder`` subclass, specify it with the ``cls`` kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead of subclassing whenever possible. """ return loads(fp.read(), encoding=encoding, cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, object_pairs_hook=object_pairs_hook, use_decimal=use_decimal, **kw) def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, object_pairs_hook=None, use_decimal=False, **kw): """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) to a Python object. *encoding* determines the encoding used to interpret any :class:`str` objects decoded by this instance (``'utf-8'`` by default). It has no effect when decoding :class:`unicode` objects. Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:`unicode`. *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 :class:`dict`. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting). *object_pairs_hook* is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of *object_pairs_hook* will be used instead of the :class:`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, :func:`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. :class:`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. :class:`float`). If *use_decimal* is true (default: ``False``) then it implies parse_float=decimal.Decimal for parity with ``dump``. To use a custom ``HjsonDecoder`` subclass, specify it with the ``cls`` kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead of subclassing whenever possible. """ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and object_pairs_hook is None and not use_decimal and not kw): return _default_decoder.decode(s) if cls is None: cls = HjsonDecoder 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 use_decimal: if parse_float is not None: raise TypeError("use_decimal=True implies parse_float=Decimal") kw['parse_float'] = Decimal return cls(encoding=encoding, **kw).decode(s) _default_hjson_encoder = HjsonEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, indent=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, ) def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, cls=None, indent=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **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``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If *ensure_ascii* is false, then the some chunks written to ``fp`` may be ``unicode`` instances, subject to normal Python ``str`` to ``unicode`` coercion rules. Unless ``fp.write()`` explicitly understands ``unicode`` (as in ``codecs.getwriter()``) this is likely to cause an error. 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). *indent* defines the amount of whitespace that the JSON array elements and object members will be indented for each level of nesting. The default is two spaces. *encoding* is the character encoding for str instances, default is UTF-8. *default(obj)* is a function that should return a serializable version of obj or raise ``TypeError``. The default simply raises ``TypeError``. If *use_decimal* is true (default: ``True``) then decimal.Decimal will be natively serialized to JSON with full precision. If *namedtuple_as_object* is true (default: ``True``), :class:`tuple` subclasses with ``_asdict()`` methods will be encoded as JSON objects. If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this is still a lossy operation that will not round-trip correctly and should be used sparingly. If *int_as_string_bitcount* is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, *item_sort_key* is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precedence over *sort_keys*. If *sort_keys* is true (default: ``False``), the output of dictionaries will be sorted by item. If *for_json* is true (default: ``False``), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. To use a custom ``HjsonEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead of subclassing whenever possible. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and cls is None and indent is None and encoding == 'utf-8' and default is None and use_decimal and namedtuple_as_object and tuple_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and int_as_string_bitcount is None and not kw ): iterable = _default_hjson_encoder.iterencode(obj) else: if cls is None: cls = HjsonEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, indent=indent, encoding=encoding, default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, for_json=for_json, int_as_string_bitcount=int_as_string_bitcount, **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, cls=None, indent=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is false then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value will be a ``unicode`` instance subject to normal Python ``str`` to ``unicode`` coercion rules instead of being escaped to an ASCII ``str``. 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). *indent* defines the amount of whitespace that the JSON array elements and object members will be indented for each level of nesting. The default is two spaces. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *use_decimal* is true (default: ``True``) then decimal.Decimal will be natively serialized to JSON with full precision. If *namedtuple_as_object* is true (default: ``True``), :class:`tuple` subclasses with ``_asdict()`` methods will be encoded as JSON objects. If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. If *bigint_as_string* is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. If *int_as_string_bitcount* is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, *item_sort_key* is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precendence over *sort_keys*. If *sort_keys* is true (default: ``False``), the output of dictionaries will be sorted by item. If *for_json* is true (default: ``False``), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. To use a custom ``HjsonEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing whenever possible. """ # cached encoder if ( not skipkeys and ensure_ascii and check_circular and cls is None and indent is None and encoding == 'utf-8' and default is None and use_decimal and namedtuple_as_object and tuple_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and int_as_string_bitcount is None and not kw ): return _default_hjson_encoder.encode(obj) if cls is None: cls = HjsonEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, indent=indent, encoding=encoding, default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, for_json=for_json, int_as_string_bitcount=int_as_string_bitcount, **kw).encode(obj) _default_json_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, ) def dumpJSON(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **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``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If *ensure_ascii* is false, then the some chunks written to ``fp`` may be ``unicode`` instances, subject to normal Python ``str`` to ``unicode`` coercion rules. Unless ``fp.write()`` explicitly understands ``unicode`` (as in ``codecs.getwriter()``) this is likely to cause an error. 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 *indent* is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. ``None`` (the default) selects the most compact representation without any newlines. An integer is also accepted and is converted to a string with that many spaces. If specified, *separators* should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. *encoding* is the character encoding for str instances, default is UTF-8. *default(obj)* is a function that should return a serializable version of obj or raise ``TypeError``. The default simply raises ``TypeError``. If *use_decimal* is true (default: ``True``) then decimal.Decimal will be natively serialized to JSON with full precision. If *namedtuple_as_object* is true (default: ``True``), :class:`tuple` subclasses with ``_asdict()`` methods will be encoded as JSON objects. If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this is still a lossy operation that will not round-trip correctly and should be used sparingly. If *int_as_string_bitcount* is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, *item_sort_key* is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precedence over *sort_keys*. If *sort_keys* is true (default: ``False``), the output of dictionaries will be sorted by item. If *for_json* is true (default: ``False``), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead of subclassing whenever possible. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and use_decimal and namedtuple_as_object and tuple_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and int_as_string_bitcount is None and not kw ): iterable = _default_json_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, indent=indent, separators=separators, encoding=encoding, default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, for_json=for_json, int_as_string_bitcount=int_as_string_bitcount, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumpsJSON(obj, skipkeys=False, ensure_ascii=True, check_circular=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is false then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value will be a ``unicode`` instance subject to normal Python ``str`` to ``unicode`` coercion rules instead of being escaped to an ASCII ``str``. 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 ``indent`` is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. ``None`` (the default) selects the most compact representation without any newlines. An integer is also accepted and is converted to a string with that many spaces. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *use_decimal* is true (default: ``True``) then decimal.Decimal will be natively serialized to JSON with full precision. If *namedtuple_as_object* is true (default: ``True``), :class:`tuple` subclasses with ``_asdict()`` methods will be encoded as JSON objects. If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. If *bigint_as_string* is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. If *int_as_string_bitcount* is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, *item_sort_key* is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precendence over *sort_keys*. If *sort_keys* is true (default: ``False``), the output of dictionaries will be sorted by item. If *for_json* is true (default: ``False``), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing whenever possible. """ # cached encoder if ( not skipkeys and ensure_ascii and check_circular and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and use_decimal and namedtuple_as_object and tuple_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and int_as_string_bitcount is None and not kw ): return _default_json_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, indent=indent, separators=separators, encoding=encoding, default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, for_json=for_json, int_as_string_bitcount=int_as_string_bitcount, **kw).encode(obj) def simple_first(kv): """Helper function to pass to item_sort_key to sort simple elements to the top, then container elements. """ return (isinstance(kv[1], (list, dict, tuple)), kv[0]) hjson-py-3.0.2/hjson/compat.py000066400000000000000000000020141372777051600162550ustar00rootroot00000000000000"""Python 3 compatibility shims """ import sys if sys.version_info[0] < 3: PY3 = False def b(s): return s def u(s): return unicode(s, 'unicode_escape') import cStringIO as StringIO StringIO = BytesIO = StringIO.StringIO text_type = unicode binary_type = str string_types = (basestring,) integer_types = (int, long) unichr = unichr reload_module = reload def fromhex(s): return s.decode('hex') else: PY3 = True if sys.version_info[:2] >= (3, 4): from importlib import reload as reload_module else: from imp import reload as reload_module import codecs def b(s): return codecs.latin_1_encode(s)[0] def u(s): return s import io StringIO = io.StringIO BytesIO = io.BytesIO text_type = str binary_type = bytes string_types = (str,) integer_types = (int,) def unichr(s): return u(chr(s)) def fromhex(s): return bytes.fromhex(s) long_type = integer_types[-1] hjson-py-3.0.2/hjson/decoder.py000066400000000000000000000461531372777051600164130ustar00rootroot00000000000000"""Implementation of HjsonDecoder """ from __future__ import absolute_import import re import sys import struct from .compat import fromhex, b, u, text_type, binary_type, PY3, unichr from .scanner import HjsonDecodeError # NOTE (3.1.0): HjsonDecodeError may still be imported from this module for # compatibility, but it was never in the __all__ __all__ = ['HjsonDecoder'] FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL def _floatconstants(): _BYTES = fromhex('7FF80000000000007FF0000000000000') # The struct module in Python 2.4 would get frexp() out of range here # when an endian is specified in the format string. Fixed in Python 2.5+ if sys.byteorder != 'big': _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1] nan, inf = struct.unpack('dd', _BYTES) return nan, inf, -inf NaN, PosInf, NegInf = _floatconstants() WHITESPACE = ' \t\n\r' PUNCTUATOR = '{}[],:' NUMBER_RE = re.compile(r'[\t ]*(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?[\t ]*') STRINGCHUNK = re.compile(r'(.*?)([\'"\\\x00-\x1f])', FLAGS) BACKSLASH = { '"': u('"'), '\'': u('\''), '\\': u('\u005c'), '/': u('/'), 'b': u('\b'), 'f': u('\f'), 'n': u('\n'), 'r': u('\r'), 't': u('\t'), } DEFAULT_ENCODING = "utf-8" def getNext(s, end): while 1: # Use a slice to prevent IndexError from being raised ch = s[end:end + 1] # Skip whitespace. while ch in WHITESPACE: if ch == '': return ch, end end += 1 ch = s[end:end + 1] # Hjson allows comments ch2 = s[end + 1:end + 2] if ch == '#' or ch == '/' and ch2 == '/': end = getEol(s, end) elif ch == '/' and ch2 == '*': end += 2 ch = s[end] while ch != '' and not (ch == '*' and s[end + 1] == '/'): end += 1 ch = s[end] if ch != '': end += 2 else: break return ch, end def getEol(s, end): # skip until eol while 1: ch = s[end:end + 1] if ch == '\r' or ch == '\n' or ch == '': return end end += 1 def skipIndent(s, end, n): ch = s[end:end + 1] while ch != '' and ch in " \t\r" and (n > 0 or n < 0): end += 1 n -= 1 ch = s[end:end + 1] return end def scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match, _join=u('').join, _PY3=PY3, _maxunicode=sys.maxunicode): """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.""" if encoding is None: encoding = DEFAULT_ENCODING chunks = [] _append = chunks.append begin = end - 1 # callers make sure that string starts with " or ' exitCh = s[begin] while 1: chunk = _m(s, end) if chunk is None: raise HjsonDecodeError( "Unterminated string starting at", s, begin) end = chunk.end() content, terminator = chunk.groups() # Content is contains zero or more unescaped string characters if content: if not _PY3 and not isinstance(content, text_type): content = text_type(content, encoding) _append(content) # Terminator is the end of string, a literal control character, # or a backslash denoting that an escape sequence follows if terminator == exitCh: break elif terminator == '"' or terminator == '\'': _append(terminator) continue elif terminator != '\\': if strict: msg = "Invalid control character %r at" raise HjsonDecodeError(msg, s, end) else: _append(terminator) continue try: esc = s[end] except IndexError: raise HjsonDecodeError( "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 \\X escape sequence %r" raise HjsonDecodeError(msg, s, end) end += 1 else: # Unicode escape sequence msg = "Invalid \\uXXXX escape sequence" esc = s[end + 1:end + 5] escX = esc[1:2] if len(esc) != 4 or escX == 'x' or escX == 'X': raise HjsonDecodeError(msg, s, end - 1) try: uni = int(esc, 16) except ValueError: raise HjsonDecodeError(msg, s, end - 1) end += 5 # Check for surrogate pair on UCS-4 systems # Note that this will join high/low surrogate pairs # but will also pass unpaired surrogates through if (_maxunicode > 65535 and uni & 0xfc00 == 0xd800 and s[end:end + 2] == '\\u'): esc2 = s[end + 2:end + 6] escX = esc2[1:2] if len(esc2) == 4 and not (escX == 'x' or escX == 'X'): try: uni2 = int(esc2, 16) except ValueError: raise HjsonDecodeError(msg, s, end) if uni2 & 0xfc00 == 0xdc00: uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) end += 6 char = unichr(uni) # Append the unescaped character _append(char) return _join(chunks), end def mlscanstring(s, end): """Scan a multiline string""" string = "" triple = 0 # we are at ''' - get indent indent = 0 while 1: ch = s[end-indent-1] if ch == '\n': break indent += 1 # skip white/to (newline) end = skipIndent(s, end + 3, -1) ch = s[end] if ch == '\n': end = skipIndent(s, end + 1, indent) # When parsing multiline string values, we must look for ' characters while 1: ch = s[end:end + 1] if ch == '': raise HjsonDecodeError("Bad multiline string", s, end); elif ch == '\'': triple += 1 end += 1 if triple == 3: if string and string[-1] == '\n': string = string[:-1] # remove last EOL return string, end else: continue else: while triple > 0: string += '\'' triple -= 1 if ch == '\n': string += ch end = skipIndent(s, end + 1, indent) else: if ch != '\r': string += ch end += 1 def scantfnns(context, s, end): """Scan s until eol. return string, True, False or None""" chf, begin = getNext(s, end) end = begin if chf in PUNCTUATOR: raise HjsonDecodeError("Found a punctuator character when expecting a quoteless string (check your syntax)", s, end); while 1: ch = s[end:end + 1] isEol = ch == '\r' or ch == '\n' or ch == '' if isEol or ch == ',' or \ ch == '}' or ch == ']' or \ ch == '#' or \ ch == '/' and (s[end + 1:end + 2] == '/' or s[end + 1:end + 2] == '*'): m = None mend = end if next: mend -= 1 if chf == 'n' and s[begin:end].strip() == 'null': return None, end elif chf == 't' and s[begin:end].strip() == 'true': return True, end elif chf == 'f' and s[begin:end].strip() == 'false': return False, end elif chf == '-' or chf >= '0' and chf <= '9': m = NUMBER_RE.match(s, begin) if m is not None and m.end() == end: integer, frac, exp = m.groups() if frac or exp: res = context.parse_float(integer + (frac or '') + (exp or '')) if int(res) == res and abs(res)<1e10: res = int(res) else: res = context.parse_int(integer) return res, end if isEol: return s[begin:end].strip(), end end += 1 def scanKeyName(s, end, encoding=None, strict=True): """Scan the string s for a JSON/Hjson key. see scanstring""" ch, end = getNext(s, end) if ch == '"' or ch == '\'': return scanstring(s, end + 1, encoding, strict) begin = end space = -1 while 1: ch = s[end:end + 1] if ch == '': raise HjsonDecodeError("Bad key name (eof)", s, end); elif ch == ':': if begin == end: raise HjsonDecodeError("Found ':' but no key name (for an empty key name use quotes)", s, begin) elif space >= 0: if space != end - 1: raise HjsonDecodeError("Found whitespace in your key name (use quotes to include)", s, space) return s[begin:end].rstrip(), end else: return s[begin:end], end elif ch in WHITESPACE: if space < 0 or space == end - 1: space = end elif ch == '{' or ch == '}' or ch == '[' or ch == ']' or ch == ',': raise HjsonDecodeError("Found '" + ch + "' where a key name was expected (check your syntax or use quotes if the key name includes {}[],: or whitespace)", s, begin) end += 1 def make_scanner(context): parse_object = context.parse_object parse_array = context.parse_array parse_string = context.parse_string parse_mlstring = context.parse_mlstring parse_tfnns = context.parse_tfnns encoding = context.encoding strict = context.strict object_hook = context.object_hook object_pairs_hook = context.object_pairs_hook memo = context.memo def _scan_once(string, idx): try: ch = string[idx] except IndexError: raise HjsonDecodeError('Expecting value', string, idx) if ch == '"' or ch == '\'': if string[idx:idx + 3] == '\'\'\'': return parse_mlstring(string, idx) else: return parse_string(string, idx + 1, encoding, strict) elif ch == '{': return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook, object_pairs_hook, memo) elif ch == '[': return parse_array((string, idx + 1), _scan_once) return parse_tfnns(context, string, idx) def scan_once(string, idx): if idx < 0: raise HjsonDecodeError('Expecting value', string, idx) try: return _scan_once(string, idx) finally: memo.clear() def scan_object_once(string, idx): if idx < 0: raise HjsonDecodeError('Expecting value', string, idx) try: return parse_object((string, idx), encoding, strict, _scan_once, object_hook, object_pairs_hook, memo, True) finally: memo.clear() return scan_once, scan_object_once def JSONObject(state, encoding, strict, scan_once, object_hook, object_pairs_hook, memo=None, objectWithoutBraces=False): (s, end) = state # Backwards compatibility if memo is None: memo = {} memo_get = memo.setdefault pairs = [] ch, end = getNext(s, end) # Trivial empty object if not objectWithoutBraces and ch == '}': 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 while True: key, end = scanKeyName(s, end, encoding, strict) key = memo_get(key, key) ch, end = getNext(s, end) if ch != ':': raise HjsonDecodeError("Expecting ':' delimiter", s, end) ch, end = getNext(s, end + 1) value, end = scan_once(s, end) pairs.append((key, value)) ch, end = getNext(s, end) if ch == ',': ch, end = getNext(s, end + 1) if objectWithoutBraces: if ch == '': break; else: if ch == '}': end += 1 break ch, end = getNext(s, end) 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(state, scan_once): (s, end) = state values = [] ch, end = getNext(s, end) # Look-ahead for trivial empty array if ch == ']': return values, end + 1 elif ch == '': raise HjsonDecodeError("End of input while parsing an array (did you forget a closing ']'?)", s, end) _append = values.append while True: value, end = scan_once(s, end) _append(value) ch, end = getNext(s, end) if ch == ',': ch, end = getNext(s, end + 1) if ch == ']': end += 1 break ch, end = getNext(s, end) return values, end class HjsonDecoder(object): """Hjson decoder Performs the following translations in decoding by default: +---------------+-------------------+ | JSON | Python | +===============+===================+ | object | dict | +---------------+-------------------+ | array | list | +---------------+-------------------+ | string | str, unicode | +---------------+-------------------+ | number (int) | int, long | +---------------+-------------------+ | number (real) | float | +---------------+-------------------+ | true | True | +---------------+-------------------+ | false | False | +---------------+-------------------+ | null | None | +---------------+-------------------+ """ def __init__(self, encoding=None, object_hook=None, parse_float=None, parse_int=None, strict=True, object_pairs_hook=None): """ *encoding* determines the encoding used to interpret any :class:`str` objects decoded by this instance (``'utf-8'`` by default). It has no effect when decoding :class:`unicode` objects. Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:`unicode`. *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 :class:`dict`. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting). *object_pairs_hook* is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of *object_pairs_hook* will be used instead of the :class:`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, :func:`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. :class:`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. :class:`float`). *strict* controls the parser's behavior when it encounters an invalid control character in a string. The default setting of ``True`` means that unescaped control characters are parse errors, if ``False`` then control characters will be allowed in strings. """ if encoding is None: encoding = DEFAULT_ENCODING self.encoding = encoding self.object_hook = object_hook self.object_pairs_hook = object_pairs_hook self.parse_float = parse_float or float self.parse_int = parse_int or int self.strict = strict self.parse_object = JSONObject self.parse_array = JSONArray self.parse_string = scanstring self.parse_mlstring = mlscanstring self.parse_tfnns = scantfnns self.memo = {} (self.scan_once, self.scan_object_once) = make_scanner(self) def decode(self, s, _PY3=PY3): """Return the Python representation of ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) """ if _PY3 and isinstance(s, binary_type): s = s.decode(self.encoding) obj, end = self.raw_decode(s) ch, end = getNext(s, end) if end != len(s): raise HjsonDecodeError("Extra data", s, end, len(s)) return obj def raw_decode(self, s, idx=0, _PY3=PY3): """Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning with a JSON document) and return a 2-tuple of the Python representation and the index in ``s`` where the document ended. Optionally, ``idx`` can be used to specify an offset in ``s`` where the JSON document begins. This can be used to decode a JSON document from a string that may have extraneous data at the end. """ if idx < 0: # Ensure that raw_decode bails on negative indexes, the regex # would otherwise mask this behavior. #98 raise HjsonDecodeError('Expecting value', s, idx) if _PY3 and not isinstance(s, text_type): raise TypeError("Input string must be text") # strip UTF-8 bom if len(s) > idx: ord0 = ord(s[idx]) if ord0 == 0xfeff: idx += 1 elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf': idx += 3 start_index = idx ch, idx = getNext(s, idx) # If blank or comment only file, return dict if start_index == 0 and ch == '': return {}, 0 if ch == '{' or ch == '[': return self.scan_once(s, idx) else: # assume we have a root object without braces try: return self.scan_object_once(s, idx) except HjsonDecodeError as e: # test if we are dealing with a single JSON value instead (true/false/null/num/"") try: return self.scan_once(s, idx) except: raise e hjson-py-3.0.2/hjson/encoder.py000066400000000000000000000453401372777051600164220ustar00rootroot00000000000000"""Implementation of JSONEncoder """ from __future__ import absolute_import import re from operator import itemgetter from decimal import Decimal from .compat import u, unichr, binary_type, string_types, integer_types, PY3 from .decoder import PosInf #ESCAPE = re.compile(ur'[\x00-\x1f\\"\b\f\n\r\t\u2028\u2029]') # This is required because u() will mangle the string and ur'' isn't valid # python3 syntax ESCAPE = re.compile(u'[\\x00-\\x1f\\\\"\\b\\f\\n\\r\\t\u2028\u2029]') ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') HAS_UTF8 = re.compile(r'[\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,)) for i in [0x2028, 0x2029]: ESCAPE_DCT.setdefault(unichr(i), '\\u%04x' % (i,)) FLOAT_REPR = repr def encode_basestring(s, _PY3=PY3, _q=u('"')): """Return a JSON representation of a Python string """ if _PY3: if isinstance(s, binary_type): s = s.decode('utf-8') else: if isinstance(s, str) and HAS_UTF8.search(s) is not None: s = s.decode('utf-8') def replace(match): return ESCAPE_DCT[match.group(0)] return _q + ESCAPE.sub(replace, s) + _q def py_encode_basestring_ascii(s, _PY3=PY3): """Return an ASCII-only JSON representation of a Python string """ if _PY3: if isinstance(s, binary_type): s = s.decode('utf-8') else: if isinstance(s, str) and HAS_UTF8.search(s) is not None: s = s.decode('utf-8') 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 '\\u%04x\\u%04x' % (s1, s2) return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' encode_basestring_ascii = ( 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, namedtuple | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str, unicode | string | +-------------------+---------------+ | int, long, 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, sort_keys=False, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, int_as_string_bitcount=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, long, 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 unicode characters escaped. If ensure_ascii is false, the output will be unicode object. 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 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 string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. ``None`` (the default) selects the most compact representation without any newlines. For backwards compatibility with versions of hjson earlier than 2.1.0, an integer is also accepted and is converted to a string with that many spaces. If specified, separators should be an (item_separator, key_separator) tuple. The default is (', ', ': ') if *indent* is ``None`` and (',', ': ') otherwise. 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``. If encoding is not None, then all input strings will be transformed into unicode using that encoding prior to JSON-encoding. The default is UTF-8. If use_decimal is true (not the default), ``decimal.Decimal`` will be supported directly by the encoder. For the inverse, decode JSON with ``parse_float=decimal.Decimal``. If namedtuple_as_object is true (the default), objects with ``_asdict()`` methods will be encoded as JSON objects. If tuple_as_array is true (the default), tuple (and subclasses) will be encoded as JSON arrays. If bigint_as_string is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. If for_json is true (not the default), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. """ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii self.check_circular = check_circular self.sort_keys = sort_keys self.use_decimal = use_decimal self.namedtuple_as_object = namedtuple_as_object self.tuple_as_array = tuple_as_array self.bigint_as_string = bigint_as_string self.item_sort_key = item_sort_key self.for_json = for_json self.int_as_string_bitcount = int_as_string_bitcount if indent is not None and not isinstance(indent, string_types): indent = indent * ' ' self.indent = indent if separators is not None: self.item_separator, self.key_separator = separators elif indent is not None: self.item_separator = ',' if default is not None: self.default = default self.encoding = encoding 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) 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. >>> from hjson import JSONEncoder >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}' """ # This is for extremely simple cases and benchmarks. if isinstance(o, binary_type): _encoding = self.encoding if (_encoding is not None and not (_encoding == 'utf-8')): o = o.decode(_encoding) if isinstance(o, string_types): 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) if self.ensure_ascii: return ''.join(chunks) else: return u''.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 if self.encoding != 'utf-8': def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): if isinstance(o, binary_type): o = o.decode(_encoding) return _orig_encoder(o) def floatstr(o, _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf): # 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 = 'null' elif o == _inf: text = 'null' elif o == _neginf: text = 'null' else: return _repr(o) return text key_memo = {} int_as_string_bitcount = ( 53 if self.bigint_as_string else self.int_as_string_bitcount) _iterencode = _make_iterencode( markers, self.default, _encoder, self.indent, floatstr, self.key_separator, self.item_separator, self.sort_keys, self.skipkeys, _one_shot, self.use_decimal, self.namedtuple_as_object, self.tuple_as_array, int_as_string_bitcount, self.item_sort_key, self.encoding, self.for_json, Decimal=Decimal) try: return _iterencode(o, 0) finally: key_memo.clear() def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot, _use_decimal, _namedtuple_as_object, _tuple_as_array, _int_as_string_bitcount, _item_sort_key, _encoding,_for_json, ## HACK: hand-optimized bytecode; turn globals into locals _PY3=PY3, ValueError=ValueError, string_types=string_types, Decimal=Decimal, dict=dict, float=float, id=id, integer_types=integer_types, isinstance=isinstance, list=list, str=str, tuple=tuple, ): if _item_sort_key and not callable(_item_sort_key): raise TypeError("item_sort_key must be None or callable") elif _sort_keys and not _item_sort_key: _item_sort_key = itemgetter(0) if (_int_as_string_bitcount is not None and (_int_as_string_bitcount <= 0 or not isinstance(_int_as_string_bitcount, integer_types))): raise TypeError("int_as_string_bitcount must be a positive integer") def _encode_int(value): skip_quoting = ( _int_as_string_bitcount is None or _int_as_string_bitcount < 1 ) if ( skip_quoting or (-1 << _int_as_string_bitcount) < value < (1 << _int_as_string_bitcount) ): return str(value) return '"' + str(value) + '"' 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 yield buf for chunk in _iterencode(value, _current_indent_level): 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 _stringify_key(key): if isinstance(key, string_types): # pragma: no cover pass elif isinstance(key, binary_type): key = key.decode(_encoding) 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, integer_types): key = str(key) elif _use_decimal and isinstance(key, Decimal): key = str(key) elif _skipkeys: key = None else: raise TypeError("key " + repr(key) + " is not a string") return key 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 _PY3: iteritems = dct.items() else: iteritems = dct.iteritems() if _item_sort_key: items = [] for k, v in dct.items(): if not isinstance(k, string_types): k = _stringify_key(k) if k is None: continue items.append((k, v)) items.sort(key=_item_sort_key) else: items = iteritems for key, value in items: if not (_item_sort_key or isinstance(key, string_types)): key = _stringify_key(key) if key is None: # _skipkeys must be True continue if first: first = False else: yield item_separator yield _encoder(key) yield _key_separator for chunk in _iterencode(value, _current_indent_level): 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, string_types) or (_PY3 and isinstance(o, binary_type))): yield _encoder(o) elif o is None: yield 'null' elif o is True: yield 'true' elif o is False: yield 'false' elif isinstance(o, integer_types): yield _encode_int(o) elif isinstance(o, float): yield _floatstr(o) else: for_json = _for_json and getattr(o, 'for_json', None) if for_json and callable(for_json): for chunk in _iterencode(for_json(), _current_indent_level): yield chunk elif isinstance(o, list): for chunk in _iterencode_list(o, _current_indent_level): yield chunk else: _asdict = _namedtuple_as_object and getattr(o, '_asdict', None) if _asdict and callable(_asdict): for chunk in _iterencode_dict(_asdict(), _current_indent_level): yield chunk elif (_tuple_as_array and isinstance(o, 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 elif _use_decimal and isinstance(o, Decimal): yield str(o) 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 hjson-py-3.0.2/hjson/encoderH.py000066400000000000000000000500011372777051600165200ustar00rootroot00000000000000"""Implementation of HjsonEncoder """ from __future__ import absolute_import import re from operator import itemgetter from decimal import Decimal from .compat import u, unichr, binary_type, string_types, integer_types, PY3 from .decoder import PosInf # This is required because u() will mangle the string and ur'' isn't valid # python3 syntax ESCAPE = re.compile(u'[\\x00-\\x1f\\\\"\\b\\f\\n\\r\\t\u2028\u2029\uffff]') ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') HAS_UTF8 = re.compile(r'[\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,)) for i in [0x2028, 0x2029, 0xffff]: ESCAPE_DCT.setdefault(unichr(i), '\\u%04x' % (i,)) COMMONRANGE=u'\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff' # NEEDSESCAPE tests if the string can be written without escapes NEEDSESCAPE = re.compile(u'[\\\"\x00-\x1f'+COMMONRANGE+']') # NEEDSQUOTES tests if the string can be written as a quoteless string (like needsEscape but without \\ and \") NEEDSQUOTES = re.compile(u'^\\s|^"|^\'|^#|^\\/\\*|^\\/\\/|^\\{|^\\}|^\\[|^\\]|^:|^,|\\s$|[\x00-\x1f'+COMMONRANGE+u']') # NEEDSESCAPEML tests if the string can be written as a multiline string (like needsEscape but without \n, \r, \\, \", \t) NEEDSESCAPEML = re.compile(u'\'\'\'|^[\\s]+$|[\x00-\x08\x0b\x0c\x0e-\x1f'+COMMONRANGE+u']') WHITESPACE = ' \t\n\r' STARTSWITHNUMBER = re.compile(r'^[\t ]*(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?\s*((,|\]|\}|#|\/\/|\/\*).*)?$'); STARTSWITHKEYWORD = re.compile(r'^(true|false|null)\s*((,|\]|\}|#|\/\/|\/\*).*)?$'); NEEDSESCAPENAME = re.compile(r'[,\{\[\}\]\s:#"\']|\/\/|\/\*|'+"'''") FLOAT_REPR = repr def encode_basestring(s, _PY3=PY3, _q=u('"')): """Return a JSON representation of a Python string """ if _PY3: if isinstance(s, binary_type): s = s.decode('utf-8') else: if isinstance(s, str) and HAS_UTF8.search(s) is not None: s = s.decode('utf-8') def replace(match): return ESCAPE_DCT[match.group(0)] return _q + ESCAPE.sub(replace, s) + _q def encode_basestring_ascii(s, _PY3=PY3): """Return an ASCII-only JSON representation of a Python string """ if _PY3: if isinstance(s, binary_type): s = s.decode('utf-8') else: if isinstance(s, str) and HAS_UTF8.search(s) is not None: s = s.decode('utf-8') 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 '\\u%04x\\u%04x' % (s1, s2) return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' class HjsonEncoder(object): """Extensible JSON encoder for Python data structures. Supports the following objects and types by default: +-------------------+---------------+ | Python | JSON | +===================+===============+ | dict, namedtuple | object | +-------------------+---------------+ | list, tuple | array | +-------------------+---------------+ | str, unicode | string | +-------------------+---------------+ | int, long, 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``). """ def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, sort_keys=False, indent=' ', encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, item_sort_key=None, for_json=False, int_as_string_bitcount=None): """Constructor for HjsonEncoder, with sensible defaults. If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, long, 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 unicode characters escaped. If ensure_ascii is false, the output will be unicode object. 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 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 string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. 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``. If encoding is not None, then all input strings will be transformed into unicode using that encoding prior to JSON-encoding. The default is UTF-8. If use_decimal is true (not the default), ``decimal.Decimal`` will be supported directly by the encoder. For the inverse, decode JSON with ``parse_float=decimal.Decimal``. If namedtuple_as_object is true (the default), objects with ``_asdict()`` methods will be encoded as JSON objects. If tuple_as_array is true (the default), tuple (and subclasses) will be encoded as JSON arrays. If bigint_as_string is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. If int_as_string_bitcount is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, item_sort_key is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. If for_json is true (not the default), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. """ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii self.check_circular = check_circular self.sort_keys = sort_keys self.use_decimal = use_decimal self.namedtuple_as_object = namedtuple_as_object self.tuple_as_array = tuple_as_array self.bigint_as_string = bigint_as_string self.item_sort_key = item_sort_key self.for_json = for_json self.int_as_string_bitcount = int_as_string_bitcount if indent is not None and not isinstance(indent, string_types): indent = indent * ' ' elif indent is None: indent = ' ' self.indent = indent if default is not None: self.default = default self.encoding = encoding 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) return HjsonEncoder.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. >>> from hjson import HjsonEncoder >>> HjsonEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}' """ # This is for extremely simple cases and benchmarks. if isinstance(o, binary_type): _encoding = self.encoding if (_encoding is not None and not (_encoding == 'utf-8')): o = o.decode(_encoding) # 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) if self.ensure_ascii: return ''.join(chunks) else: return u''.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 HjsonEncoder().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 if self.encoding != 'utf-8': def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): if isinstance(o, binary_type): o = o.decode(_encoding) return _orig_encoder(o) def floatstr(o, _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf): # 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 or o == _inf or o == _neginf: return 'null' else: return _repr(o) key_memo = {} int_as_string_bitcount = ( 53 if self.bigint_as_string else self.int_as_string_bitcount) _iterencode = _make_iterencode( markers, self.default, _encoder, self.indent, floatstr, self.sort_keys, self.skipkeys, _one_shot, self.use_decimal, self.namedtuple_as_object, self.tuple_as_array, int_as_string_bitcount, self.item_sort_key, self.encoding, self.for_json, Decimal=Decimal) try: return _iterencode(o, 0, True) finally: key_memo.clear() def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, _sort_keys, _skipkeys, _one_shot, _use_decimal, _namedtuple_as_object, _tuple_as_array, _int_as_string_bitcount, _item_sort_key, _encoding,_for_json, ## HACK: hand-optimized bytecode; turn globals into locals _PY3=PY3, ValueError=ValueError, string_types=string_types, Decimal=Decimal, dict=dict, float=float, id=id, integer_types=integer_types, isinstance=isinstance, list=list, str=str, tuple=tuple, ): if _item_sort_key and not callable(_item_sort_key): raise TypeError("item_sort_key must be None or callable") elif _sort_keys and not _item_sort_key: _item_sort_key = itemgetter(0) if (_int_as_string_bitcount is not None and (_int_as_string_bitcount <= 0 or not isinstance(_int_as_string_bitcount, integer_types))): raise TypeError("int_as_string_bitcount must be a positive integer") def _encode_int(value): return str(value) def _stringify_key(key): if isinstance(key, string_types): # pragma: no cover pass elif isinstance(key, binary_type): key = key.decode(_encoding) 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, integer_types): key = str(key) elif _use_decimal and isinstance(key, Decimal): key = str(key) elif _skipkeys: key = None else: raise TypeError("key " + repr(key) + " is not a string") return key def _encoder_key(name): if not name: return '""' # Check if we can insert this name without quotes if NEEDSESCAPENAME.search(name): return _encoder(name) else: # return without quotes return name def _encoder_str(str, _current_indent_level): if not str: return '""' # Check if we can insert this string without quotes # see hjson syntax (must not parse as true, false, null or number) first = str[0] isNumber = False if first == '-' or first >= '0' and first <= '9': isNumber = STARTSWITHNUMBER.match(str) is not None if (NEEDSQUOTES.search(str) or isNumber or STARTSWITHKEYWORD.match(str) is not None): # If the string contains no control characters, no quote characters, and no # backslash characters, then we can safely slap some quotes around it. # Otherwise we first check if the string can be expressed in multiline # format or we must replace the offending characters with safe escape # sequences. if not NEEDSESCAPE.search(str): return '"' + str + '"' elif not NEEDSESCAPEML.search(str): return _encoder_str_ml(str, _current_indent_level + 1) else: return _encoder(str) else: # return without quotes return str def _encoder_str_ml(str, _current_indent_level): a = str.replace('\r', '').split('\n') # gap += indent; if len(a) == 1: # The string contains only a single line. We still use the multiline # format as it avoids escaping the \ character (e.g. when used in a # regex). return "'''" + a[0] + "'''" else: gap = _indent * _current_indent_level res = '\n' + gap + "'''" for line in a: res += '\n' if line: res += gap + line return res + '\n' + gap + "'''" def _iterencode_dict(dct, _current_indent_level, _isRoot=False): 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 if not _isRoot: yield '\n' + (_indent * _current_indent_level) _current_indent_level += 1 newline_indent = '\n' + (_indent * _current_indent_level) yield '{' if _PY3: iteritems = dct.items() else: iteritems = dct.iteritems() if _item_sort_key: items = [] for k, v in dct.items(): if not isinstance(k, string_types): k = _stringify_key(k) if k is None: continue items.append((k, v)) items.sort(key=_item_sort_key) else: items = iteritems for key, value in items: if not (_item_sort_key or isinstance(key, string_types)): key = _stringify_key(key) if key is None: # _skipkeys must be True continue yield newline_indent yield _encoder_key(key) first = True for chunk in _iterencode(value, _current_indent_level): if first: first = False if chunk[0 : 1] == '\n': yield ':' else: yield ': ' 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_list(lst, _current_indent_level, _isRoot=False): 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 if not _isRoot: yield '\n' + (_indent * _current_indent_level) _current_indent_level += 1 newline_indent = '\n' + (_indent * _current_indent_level) yield '[' for value in lst: yield newline_indent for chunk in _iterencode(value, _current_indent_level, True): 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, _isRoot=False): if (isinstance(o, string_types) or (_PY3 and isinstance(o, binary_type))): yield _encoder_str(o, _current_indent_level) elif o is None: yield 'null' elif o is True: yield 'true' elif o is False: yield 'false' elif isinstance(o, integer_types): yield _encode_int(o) elif isinstance(o, float): yield _floatstr(o) else: for_json = _for_json and getattr(o, 'for_json', None) if for_json and callable(for_json): for chunk in _iterencode(for_json(), _current_indent_level, _isRoot): yield chunk elif isinstance(o, list): for chunk in _iterencode_list(o, _current_indent_level, _isRoot): yield chunk else: _asdict = _namedtuple_as_object and getattr(o, '_asdict', None) if _asdict and callable(_asdict): for chunk in _iterencode_dict(_asdict(), _current_indent_level, _isRoot): yield chunk elif (_tuple_as_array and isinstance(o, tuple)): for chunk in _iterencode_list(o, _current_indent_level, _isRoot): yield chunk elif isinstance(o, dict): for chunk in _iterencode_dict(o, _current_indent_level, _isRoot): yield chunk elif _use_decimal and isinstance(o, Decimal): yield str(o) 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, _isRoot): yield chunk if markers is not None: del markers[markerid] return _iterencode hjson-py-3.0.2/hjson/ordered_dict.py000066400000000000000000000064521372777051600174330ustar00rootroot00000000000000"""Drop-in replacement for collections.OrderedDict by Raymond Hettinger http://code.activestate.com/recipes/576693/ """ from UserDict import DictMixin # Modified from original to support Python 2.4, see # http://code.google.com/p/simplejson/issues/detail?id=53 try: all except NameError: def all(seq): for elem in seq: if not elem: return False return True class OrderedDict(dict, DictMixin): def __init__(self, *args, **kwds): if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__end except AttributeError: self.clear() self.update(*args, **kwds) def clear(self): self.__end = end = [] end += [None, end, end] # sentinel node for doubly linked list self.__map = {} # key --> [key, prev, next] dict.clear(self) def __setitem__(self, key, value): if key not in self: end = self.__end curr = end[1] curr[2] = end[1] = self.__map[key] = [key, curr, end] dict.__setitem__(self, key, value) def __delitem__(self, key): dict.__delitem__(self, key) key, prev, next = self.__map.pop(key) prev[2] = next next[1] = prev def __iter__(self): end = self.__end curr = end[2] while curr is not end: yield curr[0] curr = curr[2] def __reversed__(self): end = self.__end curr = end[1] while curr is not end: yield curr[0] curr = curr[1] def popitem(self, last=True): if not self: raise KeyError('dictionary is empty') # Modified from original to support Python 2.4, see # http://code.google.com/p/simplejson/issues/detail?id=53 if last: key = reversed(self).next() else: key = iter(self).next() value = self.pop(key) return key, value def __reduce__(self): items = [[k, self[k]] for k in self] tmp = self.__map, self.__end del self.__map, self.__end inst_dict = vars(self).copy() self.__map, self.__end = tmp if inst_dict: return (self.__class__, (items,), inst_dict) return self.__class__, (items,) def keys(self): return list(self) setdefault = DictMixin.setdefault update = DictMixin.update pop = DictMixin.pop values = DictMixin.values items = DictMixin.items iterkeys = DictMixin.iterkeys itervalues = DictMixin.itervalues iteritems = DictMixin.iteritems def __repr__(self): if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, self.items()) def copy(self): return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): if isinstance(other, OrderedDict): return len(self)==len(other) and \ all(p==q for p, q in zip(self.items(), other.items())) return dict.__eq__(self, other) def __ne__(self, other): return not self == other hjson-py-3.0.2/hjson/scanner.py000066400000000000000000000033631372777051600164330ustar00rootroot00000000000000"""JSON token scanner """ import re __all__ = ['HjsonDecodeError'] class HjsonDecodeError(ValueError): """Subclass of ValueError with the following additional properties: msg: The unformatted error message doc: The JSON document being parsed pos: The start index of doc where parsing failed end: The end index of doc where parsing failed (may be None) lineno: The line corresponding to pos colno: The column corresponding to pos endlineno: The line corresponding to end (may be None) endcolno: The column corresponding to end (may be None) """ # Note that this exception is used from _speedups def __init__(self, msg, doc, pos, end=None): ValueError.__init__(self, errmsg(msg, doc, pos, end=end)) self.msg = msg self.doc = doc self.pos = pos self.end = end self.lineno, self.colno = linecol(doc, pos) if end is not None: self.endlineno, self.endcolno = linecol(doc, end) else: self.endlineno, self.endcolno = None, None def __reduce__(self): return self.__class__, (self.msg, self.doc, self.pos, self.end) def linecol(doc, pos): lineno = doc.count('\n', 0, pos) + 1 if lineno == 1: colno = pos + 1 else: colno = pos - doc.rindex('\n', 0, pos) return lineno, colno def errmsg(msg, doc, pos, end=None): lineno, colno = linecol(doc, pos) msg = msg.replace('%r', repr(doc[pos:pos + 1])) if end is None: fmt = '%s: line %d column %d (char %d)' return fmt % (msg, lineno, colno, pos) endlineno, endcolno = linecol(doc, end) fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) hjson-py-3.0.2/hjson/tests/000077500000000000000000000000001372777051600155655ustar00rootroot00000000000000hjson-py-3.0.2/hjson/tests/__init__.py000066400000000000000000000037331372777051600177040ustar00rootroot00000000000000from __future__ import absolute_import import unittest import doctest import sys def additional_tests(suite=None): import hjson import hjson.encoder import hjson.decoder if suite is None: suite = unittest.TestSuite() for mod in (hjson, hjson.encoder, hjson.decoder): suite.addTest(doctest.DocTestSuite(mod)) return suite def all_tests_suite(): def get_suite(): return additional_tests( unittest.TestLoader().loadTestsFromNames([ 'hjson.tests.test_hjson', 'hjson.tests.test_bitsize_int_as_string', 'hjson.tests.test_bigint_as_string', 'hjson.tests.test_check_circular', 'hjson.tests.test_decode', 'hjson.tests.test_default', 'hjson.tests.test_dump', 'hjson.tests.test_encode_basestring_ascii', 'hjson.tests.test_errors', 'hjson.tests.test_fail', 'hjson.tests.test_float', 'hjson.tests.test_indent', 'hjson.tests.test_pass1', 'hjson.tests.test_pass2', 'hjson.tests.test_pass3', 'hjson.tests.test_recursion', 'hjson.tests.test_scanstring', 'hjson.tests.test_separators', 'hjson.tests.test_unicode', 'hjson.tests.test_decimal', 'hjson.tests.test_tuple', 'hjson.tests.test_namedtuple', #'hjson.tests.test_tool', # fails on windows 'hjson.tests.test_for_json', ])) suite = get_suite() return suite def main(): runner = unittest.TextTestRunner(verbosity=1 + sys.argv.count('-v')) suite = all_tests_suite() raise SystemExit(not runner.run(suite).wasSuccessful()) if __name__ == '__main__': import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) main() hjson-py-3.0.2/hjson/tests/assets/000077500000000000000000000000001372777051600170675ustar00rootroot00000000000000hjson-py-3.0.2/hjson/tests/assets/charset2_result.hjson000066400000000000000000000004311372777051600232410ustar00rootroot00000000000000{ uescape: "\u0000,\u0001,\uffff" French: ยฐ รฎ รข รช รŽ ร‚ รŠ รฉ ร‰ รจ ร  รน รˆ ร€ ร™ รซ ร‹ รง ร‡ ล“ ยซ ยป German: รค ร„ รถ ร– รผ รœ รŸ Italian: ยฐ รฉ รง ร  รจ รฌ รฒ รน ร€ รˆ รŒ ร’ ร™ Spanish: รฑ ร‘ รผ รœ รก รฉ รญ รณ รบ ร ร‰ ร ร“ รš ยบ ยฟ ยก hex: ฤฃไ•ง่ฆซ์ทฏ๊ฏ๎ฝŠ }hjson-py-3.0.2/hjson/tests/assets/charset2_result.json000066400000000000000000000004611372777051600230740ustar00rootroot00000000000000{ "uescape": "\u0000,\u0001,๏ฟฟ", "French": "ยฐ รฎ รข รช รŽ ร‚ รŠ รฉ ร‰ รจ ร  รน รˆ ร€ ร™ รซ ร‹ รง ร‡ ล“ ยซ ยป", "German": "รค ร„ รถ ร– รผ รœ รŸ", "Italian": "ยฐ รฉ รง ร  รจ รฌ รฒ รน ร€ รˆ รŒ ร’ ร™", "Spanish": "รฑ ร‘ รผ รœ รก รฉ รญ รณ รบ ร ร‰ ร ร“ รš ยบ ยฟ ยก", "hex": "ฤฃไ•ง่ฆซ์ทฏ๊ฏ๎ฝŠ" }hjson-py-3.0.2/hjson/tests/assets/charset2_test.hjson000066400000000000000000000004571372777051600227120ustar00rootroot00000000000000{ uescape: "\u0000,\u0001,\uffff" French: ยฐ รฎ รข รช รŽ ร‚ รŠ รฉ ร‰ รจ ร  รน รˆ ร€ ร™ รซ ร‹ รง ร‡ ล“ ยซ ยป German: รค ร„ รถ ร– รผ รœ รŸ Italian: ยฐ รฉ รง ร  รจ รฌ รฒ รน ร€ รˆ รŒ ร’ ร™ Spanish: รฑ ร‘ รผ รœ รก รฉ รญ รณ รบ ร ร‰ ร ร“ รš ยบ ยฟ ยก hex: "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A" } hjson-py-3.0.2/hjson/tests/assets/charset_result.hjson000066400000000000000000000005071372777051600231630ustar00rootroot00000000000000{ ql-ascii: ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ js-ascii: ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ml-ascii: ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ }hjson-py-3.0.2/hjson/tests/assets/charset_result.json000066400000000000000000000005331372777051600230120ustar00rootroot00000000000000{ "ql-ascii": "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "js-ascii": "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", "ml-ascii": "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" }hjson-py-3.0.2/hjson/tests/assets/charset_test.hjson000066400000000000000000000005401372777051600226210ustar00rootroot00000000000000{ ql-ascii: ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ js-ascii: "! \"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" ml-ascii: ''' ! "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ''' } hjson-py-3.0.2/hjson/tests/assets/comments_result.hjson000066400000000000000000000011151372777051600233530ustar00rootroot00000000000000{ foo1: This is a string value. # part of the string foo2: This is a string value. bar1: This is a string value. // part of the string bar2: This is a string value. foobar1: This is a string value./* part of the string */ foobar2: This is a string value. rem1: "# test" rem2: "// test" rem3: "/* test */" num1: 0 num2: 0 num3: 2 true1: true true2: true true3: true false1: false false2: false false3: false null1: null null2: null null3: null str1: 00 # part of the string str2: 00.0 // part of the string str3: 02 /* part of the string */ }hjson-py-3.0.2/hjson/tests/assets/comments_result.json000066400000000000000000000012461372777051600232100ustar00rootroot00000000000000{ "foo1": "This is a string value. # part of the string", "foo2": "This is a string value.", "bar1": "This is a string value. // part of the string", "bar2": "This is a string value.", "foobar1": "This is a string value./* part of the string */", "foobar2": "This is a string value.", "rem1": "# test", "rem2": "// test", "rem3": "/* test */", "num1": 0, "num2": 0, "num3": 2, "true1": true, "true2": true, "true3": true, "false1": false, "false2": false, "false3": false, "null1": null, "null2": null, "null3": null, "str1": "00 # part of the string", "str2": "00.0 // part of the string", "str3": "02 /* part of the string */" }hjson-py-3.0.2/hjson/tests/assets/comments_test.hjson000066400000000000000000000017041372777051600230200ustar00rootroot00000000000000// test # all // comment /* styles */ # with lf # ! { # hjson style comment foo1: This is a string value. # part of the string foo2: "This is a string value." # a comment // js style comment bar1: This is a string value. // part of the string bar2: "This is a string value." // a comment /* js block style comments */foobar1:/* more */This is a string value./* part of the string */ /* js block style comments */foobar2:/* more */"This is a string value."/* a comment */ rem1: "# test" rem2: "// test" rem3: "/* test */" num1: 0 # comment num2: 0.0 // comment num3: 2 /* comment */ true1: true # comment true2: true // comment true3: true /* comment */ false1: false # comment false2: false // comment false3: false /* comment */ null1: null # comment null2: null // comment null3: null /* comment */ str1: 00 # part of the string str2: 00.0 // part of the string str3: 02 /* part of the string */ } hjson-py-3.0.2/hjson/tests/assets/empty_result.hjson000066400000000000000000000000171372777051600226640ustar00rootroot00000000000000{ "": empty }hjson-py-3.0.2/hjson/tests/assets/empty_result.json000066400000000000000000000000211372777051600225070ustar00rootroot00000000000000{ "": "empty" }hjson-py-3.0.2/hjson/tests/assets/empty_test.hjson000066400000000000000000000000201372777051600223170ustar00rootroot00000000000000{ "": empty } hjson-py-3.0.2/hjson/tests/assets/extra/000077500000000000000000000000001372777051600202125ustar00rootroot00000000000000hjson-py-3.0.2/hjson/tests/assets/extra/notabs_result.hjson000066400000000000000000000000561372777051600241420ustar00rootroot00000000000000{ foo: "bar\tjoe\noki\tdoki\n\t\ttwo tabs" }hjson-py-3.0.2/hjson/tests/assets/extra/notabs_result.json000066400000000000000000000000601372777051600237650ustar00rootroot00000000000000{ "foo": "bar\tjoe\noki\tdoki\n\t\ttwo tabs" }hjson-py-3.0.2/hjson/tests/assets/extra/notabs_test.json000066400000000000000000000000621372777051600234300ustar00rootroot00000000000000{ "foo": "bar\tjoe\noki\tdoki\n\t\ttwo tabs" }hjson-py-3.0.2/hjson/tests/assets/extra/notabs_testmeta.hjson000066400000000000000000000000551372777051600244510ustar00rootroot00000000000000{ options: { multiline: no-tabs } } hjson-py-3.0.2/hjson/tests/assets/extra/root_result.hjson000066400000000000000000000000711372777051600236340ustar00rootroot00000000000000{ database: { host: 127.0.0.1 port: 555 } }hjson-py-3.0.2/hjson/tests/assets/extra/root_result.json000066400000000000000000000001001372777051600234550ustar00rootroot00000000000000{ "database": { "host": "127.0.0.1", "port": 555 } }hjson-py-3.0.2/hjson/tests/assets/extra/root_test.hjson000066400000000000000000000001251372777051600232750ustar00rootroot00000000000000// a object with the root braces omitted database: { host: 127.0.0.1 port: 555 } hjson-py-3.0.2/hjson/tests/assets/extra/root_testmeta.hjson000066400000000000000000000000521372777051600241430ustar00rootroot00000000000000{ options: { legacyRoot: true } } hjson-py-3.0.2/hjson/tests/assets/extra/separator_result.hjson000066400000000000000000000001271372777051600246530ustar00rootroot00000000000000{ foo: "bar", unicorn: "rainbow", cat: 1, hello: [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/extra/separator_result.json000066400000000000000000000001351372777051600245020ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/extra/separator_test.json000066400000000000000000000001271372777051600241440ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/extra/separator_testmeta.hjson000066400000000000000000000000511372777051600251570ustar00rootroot00000000000000{ options: { separator: true } } hjson-py-3.0.2/hjson/tests/assets/failCharset1_test.hjson000066400000000000000000000000511372777051600234730ustar00rootroot00000000000000{ # invalid \u char char: "\uxxxx" } hjson-py-3.0.2/hjson/tests/assets/failJSON02_test.json000066400000000000000000000000211372777051600225610ustar00rootroot00000000000000["Unclosed array"hjson-py-3.0.2/hjson/tests/assets/failJSON05_test.json000066400000000000000000000000301372777051600225640ustar00rootroot00000000000000["double extra comma",,]hjson-py-3.0.2/hjson/tests/assets/failJSON06_test.json000066400000000000000000000000321372777051600225670ustar00rootroot00000000000000[ , "<-- missing value"]hjson-py-3.0.2/hjson/tests/assets/failJSON07_test.json000066400000000000000000000000321372777051600225700ustar00rootroot00000000000000["Comma after the close"],hjson-py-3.0.2/hjson/tests/assets/failJSON08_test.json000066400000000000000000000000201372777051600225660ustar00rootroot00000000000000["Extra close"]]hjson-py-3.0.2/hjson/tests/assets/failJSON10_test.json000066400000000000000000000000721372777051600225660ustar00rootroot00000000000000{"Extra value after close": true} "misplaced quoted value"hjson-py-3.0.2/hjson/tests/assets/failJSON11_test.json000066400000000000000000000000351372777051600225660ustar00rootroot00000000000000{"Illegal expression": 1 + 2}hjson-py-3.0.2/hjson/tests/assets/failJSON12_test.json000066400000000000000000000000371372777051600225710ustar00rootroot00000000000000{"Illegal invocation": alert()}hjson-py-3.0.2/hjson/tests/assets/failJSON13_test.json000066400000000000000000000000531372777051600225700ustar00rootroot00000000000000{"Numbers cannot have leading zeroes": 013}hjson-py-3.0.2/hjson/tests/assets/failJSON14_test.json000066400000000000000000000000371372777051600225730ustar00rootroot00000000000000{"Numbers cannot be hex": 0x14}hjson-py-3.0.2/hjson/tests/assets/failJSON15_test.json000066400000000000000000000000421372777051600225700ustar00rootroot00000000000000["Illegal backslash escape: \x15"]hjson-py-3.0.2/hjson/tests/assets/failJSON16_test.json000066400000000000000000000000101372777051600225640ustar00rootroot00000000000000[\naked]hjson-py-3.0.2/hjson/tests/assets/failJSON17_test.json000066400000000000000000000000421372777051600225720ustar00rootroot00000000000000["Illegal backslash escape: \017"]hjson-py-3.0.2/hjson/tests/assets/failJSON19_test.json000066400000000000000000000000261372777051600225760ustar00rootroot00000000000000{"Missing colon" null}hjson-py-3.0.2/hjson/tests/assets/failJSON20_test.json000066400000000000000000000000271372777051600225670ustar00rootroot00000000000000{"Double colon":: null}hjson-py-3.0.2/hjson/tests/assets/failJSON21_test.json000066400000000000000000000000401372777051600225630ustar00rootroot00000000000000{"Comma instead of colon", null}hjson-py-3.0.2/hjson/tests/assets/failJSON22_test.json000066400000000000000000000000411372777051600225650ustar00rootroot00000000000000["Colon instead of comma": false]hjson-py-3.0.2/hjson/tests/assets/failJSON23_test.json000066400000000000000000000000241372777051600225670ustar00rootroot00000000000000["Bad value", truth]hjson-py-3.0.2/hjson/tests/assets/failJSON26_test.json000066400000000000000000000000461372777051600225760ustar00rootroot00000000000000["tab\ character\ in\ string\ "]hjson-py-3.0.2/hjson/tests/assets/failJSON28_test.json000066400000000000000000000000171372777051600225760ustar00rootroot00000000000000["line\ break"]hjson-py-3.0.2/hjson/tests/assets/failJSON29_test.json000066400000000000000000000000041372777051600225730ustar00rootroot00000000000000[0e]hjson-py-3.0.2/hjson/tests/assets/failJSON30_test.json000066400000000000000000000000051372777051600225640ustar00rootroot00000000000000[0e+]hjson-py-3.0.2/hjson/tests/assets/failJSON31_test.json000066400000000000000000000000071372777051600225670ustar00rootroot00000000000000[0e+-1]hjson-py-3.0.2/hjson/tests/assets/failJSON32_test.json000066400000000000000000000000501372777051600225660ustar00rootroot00000000000000{"Comma instead if closing brace": true,hjson-py-3.0.2/hjson/tests/assets/failJSON33_test.json000066400000000000000000000000141372777051600225670ustar00rootroot00000000000000["mismatch"}hjson-py-3.0.2/hjson/tests/assets/failJSON34_test.json000066400000000000000000000001011372777051600225650ustar00rootroot00000000000000A quoteless string is OK, but two must be contained in an array. hjson-py-3.0.2/hjson/tests/assets/failKey1_test.hjson000066400000000000000000000000451372777051600226350ustar00rootroot00000000000000{ # invalid name wrong name: 0 } hjson-py-3.0.2/hjson/tests/assets/failKey2_test.hjson000066400000000000000000000000401372777051600226310ustar00rootroot00000000000000{ # invalid name {name: 0 } hjson-py-3.0.2/hjson/tests/assets/failKey3_test.hjson000066400000000000000000000000431372777051600226350ustar00rootroot00000000000000{ # invalid name key,name: 0 } hjson-py-3.0.2/hjson/tests/assets/failKey4_test.hjson000066400000000000000000000000331372777051600226350ustar00rootroot00000000000000{ # invalid name : 0 } hjson-py-3.0.2/hjson/tests/assets/failKey5_test.hjson000066400000000000000000000000441372777051600226400ustar00rootroot00000000000000{ # invalid name '''foo''': 0 } hjson-py-3.0.2/hjson/tests/assets/failMLStr1_test.hjson000066400000000000000000000000511372777051600231030ustar00rootroot00000000000000{ # invalid multiline string ml: ''' hjson-py-3.0.2/hjson/tests/assets/failObj1_test.hjson000066400000000000000000000000521372777051600226150ustar00rootroot00000000000000{ # invalid obj noDelimiter { } } hjson-py-3.0.2/hjson/tests/assets/failObj2_test.hjson000066400000000000000000000000411372777051600226140ustar00rootroot00000000000000{ # invalid obj noEnd { } hjson-py-3.0.2/hjson/tests/assets/failObj3_test.hjson000066400000000000000000000000461372777051600226220ustar00rootroot00000000000000{ # missing key [ test ] } hjson-py-3.0.2/hjson/tests/assets/failStr1a_test.hjson000066400000000000000000000000511372777051600230130ustar00rootroot00000000000000{ # invalid quoteless string ql: ] } hjson-py-3.0.2/hjson/tests/assets/failStr1b_test.hjson000066400000000000000000000000521372777051600230150ustar00rootroot00000000000000{ # invalid quoteless string ql: ]x } hjson-py-3.0.2/hjson/tests/assets/failStr1c_test.hjson000066400000000000000000000000531372777051600230170ustar00rootroot00000000000000[ foo # invalid quoteless string ] ] hjson-py-3.0.2/hjson/tests/assets/failStr1d_test.hjson000066400000000000000000000000541372777051600230210ustar00rootroot00000000000000[ foo # invalid quoteless string ]x ] hjson-py-3.0.2/hjson/tests/assets/failStr2a_test.hjson000066400000000000000000000000511372777051600230140ustar00rootroot00000000000000{ # invalid quoteless string ql: } } hjson-py-3.0.2/hjson/tests/assets/failStr2b_test.hjson000066400000000000000000000000521372777051600230160ustar00rootroot00000000000000{ # invalid quoteless string ql: }x } hjson-py-3.0.2/hjson/tests/assets/failStr2c_test.hjson000066400000000000000000000000531372777051600230200ustar00rootroot00000000000000[ foo # invalid quoteless string } ] hjson-py-3.0.2/hjson/tests/assets/failStr2d_test.hjson000066400000000000000000000000541372777051600230220ustar00rootroot00000000000000[ foo # invalid quoteless string }x ] hjson-py-3.0.2/hjson/tests/assets/failStr3a_test.hjson000066400000000000000000000000511372777051600230150ustar00rootroot00000000000000{ # invalid quoteless string ql: { } hjson-py-3.0.2/hjson/tests/assets/failStr3b_test.hjson000066400000000000000000000000521372777051600230170ustar00rootroot00000000000000{ # invalid quoteless string ql: {x } hjson-py-3.0.2/hjson/tests/assets/failStr3c_test.hjson000066400000000000000000000000531372777051600230210ustar00rootroot00000000000000[ foo # invalid quoteless string { ] hjson-py-3.0.2/hjson/tests/assets/failStr3d_test.hjson000066400000000000000000000000541372777051600230230ustar00rootroot00000000000000[ foo # invalid quoteless string {x ] hjson-py-3.0.2/hjson/tests/assets/failStr4a_test.hjson000066400000000000000000000000511372777051600230160ustar00rootroot00000000000000{ # invalid quoteless string ql: [ } hjson-py-3.0.2/hjson/tests/assets/failStr4b_test.hjson000066400000000000000000000000521372777051600230200ustar00rootroot00000000000000{ # invalid quoteless string ql: [x } hjson-py-3.0.2/hjson/tests/assets/failStr4c_test.hjson000066400000000000000000000000531372777051600230220ustar00rootroot00000000000000[ foo # invalid quoteless string [ ] hjson-py-3.0.2/hjson/tests/assets/failStr4d_test.hjson000066400000000000000000000000541372777051600230240ustar00rootroot00000000000000[ foo # invalid quoteless string [x ] hjson-py-3.0.2/hjson/tests/assets/failStr5a_test.hjson000066400000000000000000000000511372777051600230170ustar00rootroot00000000000000{ # invalid quoteless string ql: : } hjson-py-3.0.2/hjson/tests/assets/failStr5b_test.hjson000066400000000000000000000000521372777051600230210ustar00rootroot00000000000000{ # invalid quoteless string ql: :x } hjson-py-3.0.2/hjson/tests/assets/failStr5c_test.hjson000066400000000000000000000000531372777051600230230ustar00rootroot00000000000000[ foo # invalid quoteless string : ] hjson-py-3.0.2/hjson/tests/assets/failStr5d_test.hjson000066400000000000000000000000541372777051600230250ustar00rootroot00000000000000[ foo # invalid quoteless string :x ] hjson-py-3.0.2/hjson/tests/assets/failStr6a_test.hjson000066400000000000000000000000511372777051600230200ustar00rootroot00000000000000{ # invalid quoteless string ql: , } hjson-py-3.0.2/hjson/tests/assets/failStr6b_test.hjson000066400000000000000000000000521372777051600230220ustar00rootroot00000000000000{ # invalid quoteless string ql: ,x } hjson-py-3.0.2/hjson/tests/assets/failStr6c_test.hjson000066400000000000000000000002301372777051600230210ustar00rootroot00000000000000[ # invalid quoteless string # note that if there were a preceding value the comma would # be allowed/ignored as a separator/trailing comma , ] hjson-py-3.0.2/hjson/tests/assets/failStr6d_test.hjson000066400000000000000000000002311372777051600230230ustar00rootroot00000000000000[ # invalid quoteless string # note that if there were a preceding value the comma would # be allowed/ignored as a separator/trailing comma ,x ] hjson-py-3.0.2/hjson/tests/assets/failStr7a_test.hjson000066400000000000000000000000721372777051600230240ustar00rootroot00000000000000{ # invalid string containing a newline foo : " " } hjson-py-3.0.2/hjson/tests/assets/failStr8a_test.hjson000066400000000000000000000000551372777051600230260ustar00rootroot00000000000000{ # invalid ml-string foo : ""'text''' } hjson-py-3.0.2/hjson/tests/assets/kan_result.hjson000066400000000000000000000006701372777051600223040ustar00rootroot00000000000000{ numbers: [ 0 0 0 42 42.1 -5 -5.1 1701 -1701 12.345 -12.345 ] native: [ true true false false null null ] strings: [ x 0 .0 00 01 0 0 0 42 x 42.1 asdf 1.2.3 -5 0 - -5.1 -- 17.01e2 + -17.01e2 : 12345e-3 @ -12345e-3 $ true true x true false false x false null null x null ] }hjson-py-3.0.2/hjson/tests/assets/kan_result.json000066400000000000000000000010041372777051600221240ustar00rootroot00000000000000{ "numbers": [ 0, 0, 0, 42, 42.1, -5, -5.1, 1701, -1701, 12.345, -12.345 ], "native": [ true, true, false, false, null, null ], "strings": [ "x 0", ".0", "00", "01", "0 0 0", "42 x", "42.1 asdf", "1.2.3", "-5 0 -", "-5.1 --", "17.01e2 +", "-17.01e2 :", "12345e-3 @", "-12345e-3 $", "true true", "x true", "false false", "x false", "null null", "x null" ] }hjson-py-3.0.2/hjson/tests/assets/kan_test.hjson000066400000000000000000000010071372777051600217400ustar00rootroot00000000000000{ # the comma forces a whitespace check numbers: [ 0 0 , -0 42 , 42.1 , -5 -5.1 17.01e2 -17.01e2 12345e-3 , -12345e-3 , ] native: [ true , true false , false null , null ] strings: [ x 0 .0 00 01 0 0 0 42 x 42.1 asdf 1.2.3 -5 0 - -5.1 -- 17.01e2 + -17.01e2 : 12345e-3 @ -12345e-3 $ true true x true false false x false null null x null ] } hjson-py-3.0.2/hjson/tests/assets/keys_result.hjson000066400000000000000000000010571372777051600225060ustar00rootroot00000000000000{ unquoted_key: test _unquoted: test test-key: test -test: test .key: test trailing: test trailing2: test "#c1": test "foo#bar": test "//bar": test "foo//bar": test "/*foo*/": test "foo/*foo*/bar": test "/*": test "foo/*bar": test "\"": test "foo\"bar": test "'''": test "foo'''bar": test "'": test "'foo": test "foo'bar": test ":": test "foo:bar": test "{": test "foo{bar": test "}": test "foo}bar": test "[": test "foo[bar": test "]": test "foo]bar": test nl1: test nl2: test nl3: test }hjson-py-3.0.2/hjson/tests/assets/keys_result.json000066400000000000000000000012531372777051600223340ustar00rootroot00000000000000{ "unquoted_key": "test", "_unquoted": "test", "test-key": "test", "-test": "test", ".key": "test", "trailing": "test", "trailing2": "test", "#c1": "test", "foo#bar": "test", "//bar": "test", "foo//bar": "test", "/*foo*/": "test", "foo/*foo*/bar": "test", "/*": "test", "foo/*bar": "test", "\"": "test", "foo\"bar": "test", "'''": "test", "foo'''bar": "test", "'": "test", "'foo": "test", "foo'bar": "test", ":": "test", "foo:bar": "test", "{": "test", "foo{bar": "test", "}": "test", "foo}bar": "test", "[": "test", "foo[bar": "test", "]": "test", "foo]bar": "test", "nl1": "test", "nl2": "test", "nl3": "test" }hjson-py-3.0.2/hjson/tests/assets/keys_test.hjson000066400000000000000000000013501372777051600221430ustar00rootroot00000000000000{ # unquoted keys unquoted_key: test _unquoted: test test-key: test -test: test .key: test # trailing spaces in key names are ignored trailing : test trailing2 : test # comment char in key name "#c1": test "foo#bar": test "//bar": test "foo//bar": test "/*foo*/": test "foo/*foo*/bar": test "/*": test "foo/*bar": test # quotes in key name "\"": test "foo\"bar": test "'''": test "foo'''bar": test "'": test "'foo": test "foo'bar": test # control char in key name ":": test "foo:bar": test "{": test "foo{bar": test "}": test "foo}bar": test "[": test "foo[bar": test "]": test "foo]bar": test # newline nl1: test nl2 : test nl3 : test } hjson-py-3.0.2/hjson/tests/assets/mltabs_result.hjson000066400000000000000000000001021372777051600230030ustar00rootroot00000000000000{ foo: ''' bar joe oki doki two tabs ''' }hjson-py-3.0.2/hjson/tests/assets/mltabs_result.json000066400000000000000000000000601372777051600226360ustar00rootroot00000000000000{ "foo": "bar\tjoe\noki\tdoki\n\t\ttwo tabs" }hjson-py-3.0.2/hjson/tests/assets/mltabs_test.json000066400000000000000000000000611372777051600223000ustar00rootroot00000000000000{ "foo": "bar\tjoe\noki\tdoki\n\t\ttwo tabs" } hjson-py-3.0.2/hjson/tests/assets/oa_result.hjson000066400000000000000000000001051372777051600221230ustar00rootroot00000000000000[ a {} {} [] [] { b: 1 c: [] d: {} } [] ]hjson-py-3.0.2/hjson/tests/assets/oa_result.json000066400000000000000000000001251372777051600217550ustar00rootroot00000000000000[ "a", {}, {}, [], [], { "b": 1, "c": [], "d": {} }, [] ]hjson-py-3.0.2/hjson/tests/assets/oa_test.hjson000066400000000000000000000001061372777051600215650ustar00rootroot00000000000000[ a {} {} [] [] { b: 1 c: [] d: {} } [] ] hjson-py-3.0.2/hjson/tests/assets/pass1_result.hjson000066400000000000000000000022641372777051600225630ustar00rootroot00000000000000[ JSON Test Pattern pass1 { "object with 1 member": [ array with 1 element ] } {} [] -42 true false null { integer: 1234567890 real: -9876.54321 e: 1.23456789e-13 E: 1.23456789e+34 -: 2.3456789012e+76 zero: 0 one: 1 space: " " quote: '''"''' backslash: \ controls: "\b\f\n\r\t" slash: / & / alpha: abcdefghijklmnopqrstuvwyz ALPHA: ABCDEFGHIJKLMNOPQRSTUVWYZ digit: 0123456789 0123456789: digit special: `1~!@#$%^&*()_+-={':[,]}|;.? hex: ฤฃไ•ง่ฆซ์ทฏ๊ฏ๎ฝŠ true: true false: false null: null array: [] object: {} address: 50 St. James Street url: http://www.JSON.org/ comment: "// /* */": " " " s p a c e d ": [ 1 2 3 4 5 6 7 ] compact: [ 1 2 3 4 5 6 7 ] jsontext: '''{"object with 1 member":["array with 1 element"]}''' quotes: " " %22 0x22 034 " "/\\\"์ซพ๋ชพ๊ฎ˜๏ณž๋ณš๎ฝŠ\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?": A key can be any string } 0.5 98.6 99.44 1066 10 1 0.1 1 2 2 rosebud ]hjson-py-3.0.2/hjson/tests/assets/pass1_result.json000066400000000000000000000024751372777051600224170ustar00rootroot00000000000000[ "JSON Test Pattern pass1", { "object with 1 member": [ "array with 1 element" ] }, {}, [], -42, true, false, null, { "integer": 1234567890, "real": -9876.54321, "e": 1.23456789e-13, "E": 1.23456789e+34, "-": 2.3456789012e+76, "zero": 0, "one": 1, "space": " ", "quote": "\"", "backslash": "\\", "controls": "\b\f\n\r\t", "slash": "/ & /", "alpha": "abcdefghijklmnopqrstuvwyz", "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", "digit": "0123456789", "0123456789": "digit", "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", "hex": "ฤฃไ•ง่ฆซ์ทฏ๊ฏ๎ฝŠ", "true": true, "false": false, "null": null, "array": [], "object": {}, "address": "50 St. James Street", "url": "http://www.JSON.org/", "comment": "// /* */": " ", " s p a c e d ": [ 1, 2, 3, 4, 5, 6, 7 ], "compact": [ 1, 2, 3, 4, 5, 6, 7 ], "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", "quotes": "" \" %22 0x22 034 "", "/\\\"์ซพ๋ชพ๊ฎ˜๏ณž๋ณš๎ฝŠ\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string" }, 0.5, 98.6, 99.44, 1066, 10, 1, 0.1, 1, 2, 2, "rosebud" ]hjson-py-3.0.2/hjson/tests/assets/pass1_test.json000066400000000000000000000026421372777051600220540ustar00rootroot00000000000000[ "JSON Test Pattern pass1", {"object with 1 member":["array with 1 element"]}, {}, [], -42, true, false, null, { "integer": 1234567890, "real": -9876.543210, "e": 0.123456789e-12, "E": 1.234567890E+34, "-": 23456789012E66, "zero": 0, "one": 1, "space": " ", "quote": "\"", "backslash": "\\", "controls": "\b\f\n\r\t", "slash": "/ & \/", "alpha": "abcdefghijklmnopqrstuvwyz", "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", "digit": "0123456789", "0123456789": "digit", "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", "true": true, "false": false, "null": null, "array":[ ], "object":{ }, "address": "50 St. James Street", "url": "http://www.JSON.org/", "comment": "// /* */": " ", " s p a c e d " :[1,2 , 3 , 4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", "quotes": "" \u0022 %22 0x22 034 "", "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "A key can be any string" }, 0.5 ,98.6 , 99.44 , 1066, 1e1, 0.1e1, 1e-1, 1e00,2e+00,2e-00 ,"rosebud"]hjson-py-3.0.2/hjson/tests/assets/pass2_result.hjson000066400000000000000000000014521372777051600225620ustar00rootroot00000000000000[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ Not too deep ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]hjson-py-3.0.2/hjson/tests/assets/pass2_result.json000066400000000000000000000014541372777051600224140ustar00rootroot00000000000000[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ "Not too deep" ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ]hjson-py-3.0.2/hjson/tests/assets/pass2_test.json000066400000000000000000000000641372777051600220510ustar00rootroot00000000000000[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]hjson-py-3.0.2/hjson/tests/assets/pass3_result.hjson000066400000000000000000000002041372777051600225550ustar00rootroot00000000000000{ "JSON Test Pattern pass3": { "The outermost value": must be an object or array. "In this test": It is an object. } }hjson-py-3.0.2/hjson/tests/assets/pass3_result.json000066400000000000000000000002071372777051600224100ustar00rootroot00000000000000{ "JSON Test Pattern pass3": { "The outermost value": "must be an object or array.", "In this test": "It is an object." } }hjson-py-3.0.2/hjson/tests/assets/pass3_test.json000066400000000000000000000002241372777051600220500ustar00rootroot00000000000000{ "JSON Test Pattern pass3": { "The outermost value": "must be an object or array.", "In this test": "It is an object." } } hjson-py-3.0.2/hjson/tests/assets/pass4_result.hjson000066400000000000000000000000021372777051600225520ustar00rootroot0000000000000010hjson-py-3.0.2/hjson/tests/assets/pass4_result.json000066400000000000000000000000021372777051600224020ustar00rootroot0000000000000010hjson-py-3.0.2/hjson/tests/assets/pass4_test.json000066400000000000000000000000041372777051600220450ustar00rootroot00000000000000 10 hjson-py-3.0.2/hjson/tests/assets/passSingle_result.hjson000066400000000000000000000000271372777051600236370ustar00rootroot00000000000000allow quoteless stringshjson-py-3.0.2/hjson/tests/assets/passSingle_result.json000066400000000000000000000000311372777051600234620ustar00rootroot00000000000000"allow quoteless strings"hjson-py-3.0.2/hjson/tests/assets/passSingle_test.hjson000066400000000000000000000000271372777051600233000ustar00rootroot00000000000000allow quoteless stringshjson-py-3.0.2/hjson/tests/assets/stringify/000077500000000000000000000000001372777051600211055ustar00rootroot00000000000000hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_all_result.hjson000066400000000000000000000001331372777051600257130ustar00rootroot00000000000000{ "foo": "bar" "unicorn": "rainbow" "cat": 1 "hello": [ "world" "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_all_result.json000066400000000000000000000001351372777051600255450ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_all_test.hjson000066400000000000000000000001271372777051600253570ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_all_testmeta.hjson000066400000000000000000000000461372777051600262260ustar00rootroot00000000000000{ options: { quotes: "all" } }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_always_result.hjson000066400000000000000000000001231372777051600264420ustar00rootroot00000000000000{ foo: "bar" unicorn: "rainbow" cat: 1 hello: [ "world" "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_always_result.json000066400000000000000000000001351372777051600262750ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_always_test.hjson000066400000000000000000000002031372777051600261020ustar00rootroot00000000000000// Test if `always` keeps working as before { "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_always_testmeta.hjson000066400000000000000000000000511372777051600267520ustar00rootroot00000000000000{ options: { quotes: "always" } }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_keys_result.hjson000066400000000000000000000001231372777051600261150ustar00rootroot00000000000000{ "foo": bar "unicorn": rainbow "cat": 1 "hello": [ world ! ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_keys_result.json000066400000000000000000000001351372777051600257500ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_keys_test.hjson000066400000000000000000000001271372777051600255620ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_keys_testmeta.hjson000066400000000000000000000000501372777051600264240ustar00rootroot00000000000000{ options: { quotes: "keys" } } hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_ml_result.hjson000066400000000000000000000000421372777051600273230ustar00rootroot00000000000000{ unicorn: "foo\nbar\nrainbow" }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_ml_result.json000066400000000000000000000000441372777051600271550ustar00rootroot00000000000000{ "unicorn": "foo\nbar\nrainbow" }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_ml_test.json000066400000000000000000000000431372777051600266150ustar00rootroot00000000000000{ "unicorn": "foo\nbar\nrainbow" }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_ml_testmeta.hjson000066400000000000000000000000521372777051600276340ustar00rootroot00000000000000{ options: { quotes: strings } } hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_result.hjson000066400000000000000000000001231372777051600266330ustar00rootroot00000000000000{ foo: "bar" unicorn: "rainbow" cat: 1 hello: [ "world" "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_result.json000066400000000000000000000001351372777051600264660ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_test.hjson000066400000000000000000000001271372777051600263000ustar00rootroot00000000000000{ "foo": "bar", "unicorn": "rainbow", "cat": 1, "hello": [ "world", "!" ] }hjson-py-3.0.2/hjson/tests/assets/stringify/quotes_strings_testmeta.hjson000066400000000000000000000000521372777051600271440ustar00rootroot00000000000000{ options: { quotes: "strings" } }hjson-py-3.0.2/hjson/tests/assets/stringify1_result.hjson000066400000000000000000000014161372777051600236310ustar00rootroot00000000000000{ quotes: { num1: "1,2" num2: "-1.1 ," num3: "1e10 ,2" num4: "-1e-10," kw1: "true," kw2: "false ," kw3: "null,123" close1: "1}" close1b: "1 }" close2: "1]" close2b: "1 ]" close3: "1," close3b: "1 ," comment1: "1#str" comment2: "1//str" comment3: "1/*str*/" punc1: "{" punc1b: "{foo" punc2: "}" punc2b: "}foo" punc3: "[" punc3b: "[foo" punc4: "]" punc4b: "]foo" punc5: "," punc5b: ",foo" punc6: ":" punc6b: ":foo" } noquotes: { num0: .1,2 num1: 1.1.1,2 num2: -.1, num3: 1e10e,2 num4: -1e--10, kw1: true1, kw2: false0, kw3: null0, close1: a} close2: a] comment1: a#str comment2: a//str comment3: a/*str*/ } }hjson-py-3.0.2/hjson/tests/assets/stringify1_result.json000066400000000000000000000016421372777051600234620ustar00rootroot00000000000000{ "quotes": { "num1": "1,2", "num2": "-1.1 ,", "num3": "1e10 ,2", "num4": "-1e-10,", "kw1": "true,", "kw2": "false ,", "kw3": "null,123", "close1": "1}", "close1b": "1 }", "close2": "1]", "close2b": "1 ]", "close3": "1,", "close3b": "1 ,", "comment1": "1#str", "comment2": "1//str", "comment3": "1/*str*/", "punc1": "{", "punc1b": "{foo", "punc2": "}", "punc2b": "}foo", "punc3": "[", "punc3b": "[foo", "punc4": "]", "punc4b": "]foo", "punc5": ",", "punc5b": ",foo", "punc6": ":", "punc6b": ":foo" }, "noquotes": { "num0": ".1,2", "num1": "1.1.1,2", "num2": "-.1,", "num3": "1e10e,2", "num4": "-1e--10,", "kw1": "true1,", "kw2": "false0,", "kw3": "null0,", "close1": "a}", "close2": "a]", "comment1": "a#str", "comment2": "a//str", "comment3": "a/*str*/" } }hjson-py-3.0.2/hjson/tests/assets/stringify1_test.hjson000066400000000000000000000015261372777051600232740ustar00rootroot00000000000000// test if stringify produces correct output { quotes: { num1: "1,2" num2: "-1.1 ," num3: "1e10 ,2" num4: "-1e-10," kw1: "true," kw2: "false ," kw3: "null,123" close1: "1}" close1b: "1 }" close2: "1]" close2b: "1 ]" close3: "1," close3b: "1 ," comment1: "1#str" comment2: "1//str" comment3: "1/*str*/" punc1: "{" punc1b: "{foo" punc2: "}" punc2b: "}foo" punc3: "[" punc3b: "[foo" punc4: "]" punc4b: "]foo" punc5: "," punc5b: ",foo" punc6: ":" punc6b: ":foo" } noquotes: { num0: ".1,2" num1: "1.1.1,2" num2: "-.1," num3: "1e10e,2" num4: "-1e--10," kw1: "true1," kw2: "false0," kw3: "null0," close1: "a}" close2: "a]" comment1: "a#str" comment2: "a//str" comment3: "a/*str*/" } } hjson-py-3.0.2/hjson/tests/assets/strings2_result.hjson000066400000000000000000000012311372777051600233000ustar00rootroot00000000000000{ key1: a key in single quotes "key 2": a key in single quotes "key \"": a key in single quotes text: [ single quoted string '''You need quotes for escapes''' " untrimmed " "untrimmed " containing " double quotes containing " double quotes containing " double quotes '''"containing more " double quotes"''' containing ' single quotes containing ' single quotes containing ' single quotes "'containing more ' single quotes'" "'containing more ' single quotes'" "\n" " \n" "\n \n \n \n" "\t\n" ] foo3a: asdf''' foo3b: "'''asdf" foo4a: "asdf'''\nasdf" foo4b: "asdf\n'''asdf" }hjson-py-3.0.2/hjson/tests/assets/strings2_result.json000066400000000000000000000013171372777051600231350ustar00rootroot00000000000000{ "key1": "a key in single quotes", "key 2": "a key in single quotes", "key \"": "a key in single quotes", "text": [ "single quoted string", "You need quotes\tfor escapes", " untrimmed ", "untrimmed ", "containing \" double quotes", "containing \" double quotes", "containing \" double quotes", "\"containing more \" double quotes\"", "containing ' single quotes", "containing ' single quotes", "containing ' single quotes", "'containing more ' single quotes'", "'containing more ' single quotes'", "\n", " \n", "\n \n \n \n", "\t\n" ], "foo3a": "asdf'''", "foo3b": "'''asdf", "foo4a": "asdf'''\nasdf", "foo4b": "asdf\n'''asdf" }hjson-py-3.0.2/hjson/tests/assets/strings2_test.hjson000066400000000000000000000013751372777051600227520ustar00rootroot00000000000000{ # Hjson 3 allows the use of single quotes 'key1': a key in single quotes 'key 2': a key in single quotes 'key "': a key in single quotes text: [ 'single quoted string' 'You need quotes\tfor escapes' ' untrimmed ' 'untrimmed ' 'containing " double quotes' 'containing \" double quotes' "containing \" double quotes" '"containing more " double quotes"' 'containing \' single quotes' "containing ' single quotes" "containing \' single quotes" "'containing more ' single quotes'" "\'containing more \' single quotes\'" '\n' ' \n' '\n \n \n \n' '\t\n' ] # escapes/no escape foo3a: 'asdf\'\'\'' foo3b: '\'\'\'asdf' foo4a: 'asdf\'\'\'\nasdf' foo4b: 'asdf\n\'\'\'asdf' } hjson-py-3.0.2/hjson/tests/assets/strings_result.hjson000066400000000000000000000020531372777051600232210ustar00rootroot00000000000000{ text1: This is a valid string value. text2: a \ is just a \ text3: '''You need quotes for escapes''' text4a: " untrimmed " text4b: " untrimmed" text4c: "untrimmed " notml1: "\n" notml2: " \n" notml3: "\n \n \n \n" notml4: "\t\n" multiline1: ''' first line indented line last line ''' multiline2: ''' first line indented line last line ''' multiline3: ''' first line indented line last line ''' foo1a: asdf\"'a\s\w foo1b: asdf\"'a\s\w foo1c: asdf\"'a\s\w foo2a: '''"asdf"''' foo2b: '''"asdf"''' foo3a: asdf''' foo3b: "'''asdf" foo4a: "asdf'''\nasdf" foo4b: "asdf\n'''asdf" arr: [ one two three four ] not: { number: 5 negative: -4.2 yes: true no: false null: null array: [ 1 2 3 4 5 6 7 8 9 0 -1 0.5 ] } special: { true: "true" false: "false" null: "null" one: "1" two: "2" minus: "-3" } }hjson-py-3.0.2/hjson/tests/assets/strings_result.json000066400000000000000000000021571372777051600230560ustar00rootroot00000000000000{ "text1": "This is a valid string value.", "text2": "a \\ is just a \\", "text3": "You need quotes\tfor escapes", "text4a": " untrimmed ", "text4b": " untrimmed", "text4c": "untrimmed ", "notml1": "\n", "notml2": " \n", "notml3": "\n \n \n \n", "notml4": "\t\n", "multiline1": "first line\n indented line\nlast line", "multiline2": "first line\n indented line\nlast line", "multiline3": "first line\n indented line\nlast line\n", "foo1a": "asdf\\\"'a\\s\\w", "foo1b": "asdf\\\"'a\\s\\w", "foo1c": "asdf\\\"'a\\s\\w", "foo2a": "\"asdf\"", "foo2b": "\"asdf\"", "foo3a": "asdf'''", "foo3b": "'''asdf", "foo4a": "asdf'''\nasdf", "foo4b": "asdf\n'''asdf", "arr": [ "one", "two", "three", "four" ], "not": { "number": 5, "negative": -4.2, "yes": true, "no": false, "null": null, "array": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -1, 0.5 ] }, "special": { "true": "true", "false": "false", "null": "null", "one": "1", "two": "2", "minus": "-3" } }hjson-py-3.0.2/hjson/tests/assets/strings_test.hjson000066400000000000000000000022371372777051600226660ustar00rootroot00000000000000{ # simple text1: This is a valid string value. text2:a \ is just a \ text3: "You need quotes\tfor escapes" text4a: " untrimmed " text4b: " untrimmed" text4c: "untrimmed " notml1: "\n" notml2: " \n" notml3: "\n \n \n \n" notml4: "\t\n" # multiline string multiline1: ''' first line indented line last line ''' multiline2: '''first line indented line last line''' multiline3: ''' first line indented line last line ''' # trailing lf # escapes/no escape foo1a: asdf\"'a\s\w foo1b: '''asdf\"'a\s\w''' foo1c: "asdf\\\"'a\\s\\w" foo2a: "\"asdf\"" foo2b: '''"asdf"''' foo3a: "asdf'''" foo3b: "'''asdf" foo4a: "asdf'''\nasdf" foo4b: "asdf\n'''asdf" # in arrays arr: [ one two "three" '''four''' ] # not strings not: { number: 5 negative: -4.2 yes: true no: false null: null array: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -1, 0.5 ] } # special quoted special: { true: "true" false: "false" null: "null" one: "1" two: "2" minus: "-3" } } hjson-py-3.0.2/hjson/tests/assets/testlist.txt000066400000000000000000000034641372777051600215120ustar00rootroot00000000000000charset2_test.hjson charset_test.hjson comments_test.hjson empty_test.hjson failCharset1_test.hjson failJSON02_test.json failJSON05_test.json failJSON06_test.json failJSON07_test.json failJSON08_test.json failJSON10_test.json failJSON11_test.json failJSON12_test.json failJSON13_test.json failJSON14_test.json failJSON15_test.json failJSON16_test.json failJSON17_test.json failJSON19_test.json failJSON20_test.json failJSON21_test.json failJSON22_test.json failJSON23_test.json failJSON26_test.json failJSON28_test.json failJSON29_test.json failJSON30_test.json failJSON31_test.json failJSON32_test.json failJSON33_test.json failJSON34_test.json failKey1_test.hjson failKey2_test.hjson failKey3_test.hjson failKey4_test.hjson failKey5_test.hjson failMLStr1_test.hjson failObj1_test.hjson failObj2_test.hjson failObj3_test.hjson failStr1a_test.hjson failStr1b_test.hjson failStr1c_test.hjson failStr1d_test.hjson failStr2a_test.hjson failStr2b_test.hjson failStr2c_test.hjson failStr2d_test.hjson failStr3a_test.hjson failStr3b_test.hjson failStr3c_test.hjson failStr3d_test.hjson failStr4a_test.hjson failStr4b_test.hjson failStr4c_test.hjson failStr4d_test.hjson failStr5a_test.hjson failStr5b_test.hjson failStr5c_test.hjson failStr5d_test.hjson failStr6a_test.hjson failStr6b_test.hjson failStr6c_test.hjson failStr6d_test.hjson failStr7a_test.hjson failStr8a_test.hjson kan_test.hjson keys_test.hjson mltabs_test.json oa_test.hjson pass1_test.json pass2_test.json pass3_test.json pass4_test.json passSingle_test.hjson stringify1_test.hjson strings2_test.hjson strings_test.hjson trail_test.hjson stringify/quotes_all_test.hjson stringify/quotes_always_test.hjson stringify/quotes_keys_test.hjson stringify/quotes_strings_ml_test.json stringify/quotes_strings_test.hjson extra/notabs_test.json extra/root_test.hjson extra/separator_test.jsonhjson-py-3.0.2/hjson/tests/assets/trail_result.hjson000066400000000000000000000001541372777051600226430ustar00rootroot00000000000000{ foo: 0 -- this string starts at 0 and ends at 1, preceding and trailing whitespace is ignored -- 1 }hjson-py-3.0.2/hjson/tests/assets/trail_result.json000066400000000000000000000001601372777051600224700ustar00rootroot00000000000000{ "foo": "0 -- this string starts at 0 and ends at 1, preceding and trailing whitespace is ignored -- 1" }hjson-py-3.0.2/hjson/tests/assets/trail_test.hjson000066400000000000000000000002631372777051600223050ustar00rootroot00000000000000{ // the following line contains trailing whitespace: foo: 0 -- this string starts at 0 and ends at 1, preceding and trailing whitespace is ignored -- 1 } hjson-py-3.0.2/hjson/tests/test_bigint_as_string.py000066400000000000000000000043311372777051600225240ustar00rootroot00000000000000from unittest import TestCase import hjson as json class TestBigintAsString(TestCase): # Python 2.5, at least the one that ships on Mac OS X, calculates # 2 ** 53 as 0! It manages to calculate 1 << 53 correctly. values = [(200, 200), ((1 << 53) - 1, 9007199254740991), ((1 << 53), '9007199254740992'), ((1 << 53) + 1, '9007199254740993'), (-100, -100), ((-1 << 53), '-9007199254740992'), ((-1 << 53) - 1, '-9007199254740993'), ((-1 << 53) + 1, -9007199254740991)] options = ( {"bigint_as_string": True}, {"int_as_string_bitcount": 53} ) def test_ints(self): for opts in self.options: for val, expect in self.values: self.assertEqual( val, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, **opts))) def test_lists(self): for opts in self.options: for val, expect in self.values: val = [val, val] expect = [expect, expect] self.assertEqual( val, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, **opts))) def test_dicts(self): for opts in self.options: for val, expect in self.values: val = {'k': val} expect = {'k': expect} self.assertEqual( val, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, **opts))) def test_dict_keys(self): for opts in self.options: for val, _ in self.values: expect = {str(val): 'value'} val = {val: 'value'} self.assertEqual( expect, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, **opts))) hjson-py-3.0.2/hjson/tests/test_bitsize_int_as_string.py000066400000000000000000000044341372777051600235770ustar00rootroot00000000000000from unittest import TestCase import hjson as json class TestBitSizeIntAsString(TestCase): # Python 2.5, at least the one that ships on Mac OS X, calculates # 2 ** 31 as 0! It manages to calculate 1 << 31 correctly. values = [ (200, 200), ((1 << 31) - 1, (1 << 31) - 1), ((1 << 31), str(1 << 31)), ((1 << 31) + 1, str((1 << 31) + 1)), (-100, -100), ((-1 << 31), str(-1 << 31)), ((-1 << 31) - 1, str((-1 << 31) - 1)), ((-1 << 31) + 1, (-1 << 31) + 1), ] def test_invalid_counts(self): for n in ['foo', -1, 0, 1.0]: self.assertRaises( TypeError, json.dumpsJSON, 0, int_as_string_bitcount=n) def test_ints_outside_range_fails(self): self.assertNotEqual( str(1 << 15), json.loads(json.dumpsJSON(1 << 15, int_as_string_bitcount=16)), ) def test_ints(self): for val, expect in self.values: self.assertEqual( val, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, int_as_string_bitcount=31)), ) def test_lists(self): for val, expect in self.values: val = [val, val] expect = [expect, expect] self.assertEqual( val, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, int_as_string_bitcount=31))) def test_dicts(self): for val, expect in self.values: val = {'k': val} expect = {'k': expect} self.assertEqual( val, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, int_as_string_bitcount=31))) def test_dict_keys(self): for val, _ in self.values: expect = {str(val): 'value'} val = {val: 'value'} self.assertEqual( expect, json.loads(json.dumpsJSON(val))) self.assertEqual( expect, json.loads(json.dumpsJSON(val, int_as_string_bitcount=31))) hjson-py-3.0.2/hjson/tests/test_check_circular.py000066400000000000000000000016541372777051600221450ustar00rootroot00000000000000from unittest import TestCase import hjson as json def default_iterable(obj): return list(obj) class TestCheckCircular(TestCase): def test_circular_dict(self): dct = {} dct['a'] = dct self.assertRaises(ValueError, json.dumpsJSON, dct) def test_circular_list(self): lst = [] lst.append(lst) self.assertRaises(ValueError, json.dumpsJSON, lst) def test_circular_composite(self): dct2 = {} dct2['a'] = [] dct2['a'].append(dct2) self.assertRaises(ValueError, json.dumpsJSON, dct2) def test_circular_default(self): json.dumpsJSON([set()], default=default_iterable) self.assertRaises(TypeError, json.dumpsJSON, [set()]) def test_circular_off_default(self): json.dumpsJSON([set()], default=default_iterable, check_circular=False) self.assertRaises(TypeError, json.dumpsJSON, [set()], check_circular=False) hjson-py-3.0.2/hjson/tests/test_decimal.py000066400000000000000000000047741372777051600206100ustar00rootroot00000000000000import decimal from decimal import Decimal from unittest import TestCase from hjson.compat import StringIO, reload_module import hjson as json class TestDecimal(TestCase): NUMS = "1.0", "10.00", "1.1", "1234567890.1234567890", "500" def dumps(self, obj, **kw): sio = StringIO() json.dumpJSON(obj, sio, **kw) res = json.dumpsJSON(obj, **kw) self.assertEqual(res, sio.getvalue()) return res def loads(self, s, **kw): sio = StringIO(s) res = json.loads(s, **kw) self.assertEqual(res, json.load(sio, **kw)) return res def test_decimal_encode(self): for d in map(Decimal, self.NUMS): self.assertEqual(self.dumps(d, use_decimal=True), str(d)) def test_decimal_decode(self): for s in self.NUMS: self.assertEqual(self.loads(s, parse_float=Decimal), Decimal(s)) def test_stringify_key(self): for d in map(Decimal, self.NUMS): v = {d: d} self.assertEqual( self.loads( self.dumps(v, use_decimal=True), parse_float=Decimal), {str(d): d}) def test_decimal_roundtrip(self): for d in map(Decimal, self.NUMS): # The type might not be the same (int and Decimal) but they # should still compare equal. for v in [d, [d], {'': d}]: self.assertEqual( self.loads( self.dumps(v, use_decimal=True), parse_float=Decimal), v) def test_decimal_defaults(self): d = Decimal('1.1') # use_decimal=True is the default self.assertRaises(TypeError, json.dumpsJSON, d, use_decimal=False) self.assertEqual('1.1', json.dumpsJSON(d)) self.assertEqual('1.1', json.dumpsJSON(d, use_decimal=True)) self.assertRaises(TypeError, json.dumpJSON, d, StringIO(), use_decimal=False) sio = StringIO() json.dumpJSON(d, sio) self.assertEqual('1.1', sio.getvalue()) sio = StringIO() json.dumpJSON(d, sio, use_decimal=True) self.assertEqual('1.1', sio.getvalue()) def test_decimal_reload(self): # Simulate a subinterpreter that reloads the Python modules but not # the C code https://github.com/simplejson/simplejson/issues/34 global Decimal Decimal = reload_module(decimal).Decimal import hjson.encoder hjson.encoder.Decimal = Decimal self.test_decimal_roundtrip() hjson-py-3.0.2/hjson/tests/test_decode.py000066400000000000000000000105251372777051600204240ustar00rootroot00000000000000from __future__ import absolute_import import decimal from unittest import TestCase import hjson as json from hjson import OrderedDict from hjson.compat import StringIO class TestDecode(TestCase): if not hasattr(TestCase, "assertIs"): def assertIs(self, a, b): self.assertTrue(a is b, "%r is %r" % (a, b)) def test_decimal(self): rval = json.loads("1.1", parse_float=decimal.Decimal) self.assertTrue(isinstance(rval, decimal.Decimal)) self.assertEqual(rval, decimal.Decimal("1.1")) def test_float(self): rval = json.loads("1", parse_int=float) self.assertTrue(isinstance(rval, float)) self.assertEqual(rval, 1.0) def test_decoder_optimizations(self): # Several optimizations were made that skip over calls to # the whitespace regex, so this test is designed to try and # exercise the uncommon cases. The array cases are already covered. rval = json.loads('{ "key" : "value" , "k":"v" }') self.assertEqual(rval, {"key": "value", "k": "v"}) def test_empty_objects(self): s = "{}" self.assertEqual(json.loads(s), eval(s)) s = "[]" self.assertEqual(json.loads(s), eval(s)) s = '""' self.assertEqual(json.loads(s), eval(s)) def test_object_pairs_hook(self): s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' p = [ ("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4), ("qrt", 5), ("pad", 6), ("hoy", 7), ] self.assertEqual(json.loads(s), eval(s)) self.assertEqual(json.loads(s, object_pairs_hook=lambda x: x), p) self.assertEqual(json.load(StringIO(s), object_pairs_hook=lambda x: x), p) od = json.loads(s, object_pairs_hook=OrderedDict) self.assertEqual(od, OrderedDict(p)) self.assertEqual(type(od), OrderedDict) # the object_pairs_hook takes priority over the object_hook self.assertEqual( json.loads(s, object_pairs_hook=OrderedDict, object_hook=lambda x: None), OrderedDict(p), ) def check_keys_reuse(self, source, loads): rval = loads(source) (a, b), (c, d) = sorted(rval[0]), sorted(rval[1]) self.assertIs(a, c) self.assertIs(b, d) def test_keys_reuse_str(self): s = u'[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'.encode("utf8") self.check_keys_reuse(s, json.loads) def test_keys_reuse_unicode(self): s = u'[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]' self.check_keys_reuse(s, json.loads) def test_empty_strings(self): self.assertEqual(json.loads('""'), "") self.assertEqual(json.loads(u'""'), u"") self.assertEqual(json.loads('[""]'), [""]) self.assertEqual(json.loads(u'[""]'), [u""]) def test_multiline_string(self): s1 = """ hello: ''' ''' """ s2 = """ hello: ''' ''' """ s3 = """ hello: '''''' """ s4 = """ hello: '' """ s5 = """ hello: "" """ self.assertEqual(json.loads(s1), {"hello": ""}) self.assertEqual(json.loads(s2), {"hello": ""}) self.assertEqual(json.loads(s3), {"hello": ""}) self.assertEqual(json.loads(s4), {"hello": ""}) self.assertEqual(json.loads(s5), {"hello": ""}) def test_raw_decode(self): cls = json.decoder.HjsonDecoder self.assertEqual(({"a": {}}, 9), cls().raw_decode('{"a": {}}')) # http://code.google.com/p/simplejson/issues/detail?id=85 self.assertEqual( ({"a": {}}, 9), cls(object_pairs_hook=dict).raw_decode('{"a": {}}') ) # https://github.com/simplejson/simplejson/pull/38 self.assertEqual(({"a": {}}, 11), cls().raw_decode(' \n{"a": {}}')) def test_bounds_checking(self): # https://github.com/simplejson/simplejson/issues/98 j = json.decoder.HjsonDecoder() for i in [4, 5, 6, -1, -2, -3, -4, -5, -6]: self.assertRaises(ValueError, j.scan_once, "1234", i) self.assertRaises(ValueError, j.raw_decode, "1234", i) x, y = sorted(["128931233", "472389423"], key=id) diff = id(x) - id(y) self.assertRaises(ValueError, j.scan_once, y, diff) self.assertRaises(ValueError, j.raw_decode, y, i) hjson-py-3.0.2/hjson/tests/test_default.py000066400000000000000000000003401372777051600206170ustar00rootroot00000000000000from unittest import TestCase import hjson as json class TestDefault(TestCase): def test_default(self): self.assertEqual( json.dumpsJSON(type, default=repr), json.dumpsJSON(repr(type))) hjson-py-3.0.2/hjson/tests/test_dump.py000066400000000000000000000117051372777051600201470ustar00rootroot00000000000000from unittest import TestCase from hjson.compat import StringIO, long_type, b, binary_type, PY3 import hjson as json def as_text_type(s): if PY3 and isinstance(s, binary_type): return s.decode('ascii') return s class TestDump(TestCase): def test_dump(self): sio = StringIO() json.dumpJSON({}, sio) self.assertEqual(sio.getvalue(), '{}') def test_constants(self): for c in [None, True, False]: self.assertTrue(json.loads(json.dumpsJSON(c)) is c) self.assertTrue(json.loads(json.dumpsJSON([c]))[0] is c) self.assertTrue(json.loads(json.dumpsJSON({'a': c}))['a'] is c) def test_stringify_key(self): items = [(b('bytes'), 'bytes'), (1.0, '1.0'), (10, '10'), (True, 'true'), (False, 'false'), (None, 'null'), (long_type(100), '100')] for k, expect in items: self.assertEqual( json.loads(json.dumpsJSON({k: expect})), {expect: expect}) self.assertEqual( json.loads(json.dumpsJSON({k: expect}, sort_keys=True)), {expect: expect}) self.assertRaises(TypeError, json.dumpsJSON, {json: 1}) for v in [{}, {'other': 1}, {b('derp'): 1, 'herp': 2}]: for sort_keys in [False, True]: v0 = dict(v) v0[json] = 1 v1 = dict((as_text_type(key), val) for (key, val) in v.items()) self.assertEqual( json.loads(json.dumpsJSON(v0, skipkeys=True, sort_keys=sort_keys)), v1) self.assertEqual( json.loads(json.dumpsJSON({'': v0}, skipkeys=True, sort_keys=sort_keys)), {'': v1}) self.assertEqual( json.loads(json.dumpsJSON([v0], skipkeys=True, sort_keys=sort_keys)), [v1]) def test_dumps(self): self.assertEqual(json.dumpsJSON({}), '{}') def test_encode_truefalse(self): self.assertEqual(json.dumpsJSON( {True: False, False: True}, sort_keys=True), '{"false": true, "true": false}') self.assertEqual( json.dumpsJSON( {2: 3.0, 4.0: long_type(5), False: 1, long_type(6): True, "7": 0}, sort_keys=True), '{"2": 3.0, "4.0": 5, "6": true, "7": 0, "false": 1}') def test_ordered_dict(self): # http://bugs.python.org/issue6105 items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)] s = json.dumpsJSON(json.OrderedDict(items)) self.assertEqual( s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}') def test_indent_unknown_type_acceptance(self): """ A test against the regression mentioned at `github issue 29`_. The indent parameter should accept any type which pretends to be an instance of int or long when it comes to being multiplied by strings, even if it is not actually an int or long, for backwards compatibility. .. _github issue 29: http://github.com/simplejson/simplejson/issue/29 """ class AwesomeInt(object): """An awesome reimplementation of integers""" def __init__(self, *args, **kwargs): if len(args) > 0: # [construct from literals, objects, etc.] # ... # Finally, if args[0] is an integer, store it if isinstance(args[0], int): self._int = args[0] # [various methods] def __mul__(self, other): # [various ways to multiply AwesomeInt objects] # ... finally, if the right-hand operand is not awesome enough, # try to do a normal integer multiplication if hasattr(self, '_int'): return self._int * other else: raise NotImplementedError("To do non-awesome things with" " this object, please construct it from an integer!") s = json.dumpsJSON([0, 1, 2], indent=AwesomeInt(3)) self.assertEqual(s, '[\n 0,\n 1,\n 2\n]') def test_accumulator(self): # the C API uses an accumulator that collects after 100,000 appends lst = [0] * 100000 self.assertEqual(json.loads(json.dumpsJSON(lst)), lst) def test_sort_keys(self): # https://github.com/simplejson/simplejson/issues/106 for num_keys in range(2, 32): p = dict((str(x), x) for x in range(num_keys)) sio = StringIO() json.dumpJSON(p, sio, sort_keys=True) self.assertEqual(sio.getvalue(), json.dumpsJSON(p, sort_keys=True)) self.assertEqual(json.loads(sio.getvalue()), p) hjson-py-3.0.2/hjson/tests/test_encode_basestring_ascii.py000066400000000000000000000040661372777051600240320ustar00rootroot00000000000000from unittest import TestCase import hjson.encoder from hjson.compat import b CASES = [ (u'/\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\x08\x0c\n\r\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?', '"/\\\\\\"\\ucafe\\ubabe\\uab98\\ufcde\\ubcda\\uef4a\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?"'), (u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'), (u'controls', '"controls"'), (u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'), (u'{"object with 1 member":["array with 1 element"]}', '"{\\"object with 1 member\\":[\\"array with 1 element\\"]}"'), (u' s p a c e d ', '" s p a c e d "'), (u'\U0001d120', '"\\ud834\\udd20"'), (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'), (b('\xce\xb1\xce\xa9'), '"\\u03b1\\u03a9"'), (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'), (b('\xce\xb1\xce\xa9'), '"\\u03b1\\u03a9"'), (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'), (u'\u03b1\u03a9', '"\\u03b1\\u03a9"'), (u"`1~!@#$%^&*()_+-={':[,]}|;.?", '"`1~!@#$%^&*()_+-={\':[,]}|;.?"'), (u'\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'), (u'\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'), ] class TestEncodeBaseStringAscii(TestCase): def test_py_encode_basestring_ascii(self): self._test_encode_basestring_ascii(hjson.encoder.encode_basestring_ascii) def _test_encode_basestring_ascii(self, encode_basestring_ascii): fname = encode_basestring_ascii.__name__ for input_string, expect in CASES: result = encode_basestring_ascii(input_string) #self.assertEqual(result, expect, # '{0!r} != {1!r} for {2}({3!r})'.format( # result, expect, fname, input_string)) self.assertEqual(result, expect, '%r != %r for %s(%r)' % (result, expect, fname, input_string)) def test_sorted_dict(self): items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)] s = hjson.dumpsJSON(dict(items), sort_keys=True) self.assertEqual(s, '{"five": 5, "four": 4, "one": 1, "three": 3, "two": 2}') hjson-py-3.0.2/hjson/tests/test_errors.py000066400000000000000000000030151372777051600205110ustar00rootroot00000000000000import sys, pickle from unittest import TestCase import hjson as json from hjson.compat import u, b class TestErrors(TestCase): def test_string_keys_error(self): data = [{'a': 'A', 'b': (2, 4), 'c': 3.0, ('d',): 'D tuple'}] self.assertRaises(TypeError, json.dumpsJSON, data) def test_decode_error(self): err = None try: json.loads('{}\na\nb') except json.HjsonDecodeError: err = sys.exc_info()[1] else: self.fail('Expected HjsonDecodeError') self.assertEqual(err.lineno, 2) self.assertEqual(err.colno, 1) self.assertEqual(err.endlineno, 3) self.assertEqual(err.endcolno, 2) def test_scan_error(self): err = None for t in (u, b): try: json.loads(t('{"asdf": "')) except json.HjsonDecodeError: err = sys.exc_info()[1] else: self.fail('Expected HjsonDecodeError') self.assertEqual(err.lineno, 1) self.assertEqual(err.colno, 10) def test_error_is_pickable(self): err = None try: json.loads('{}\na\nb') except json.HjsonDecodeError: err = sys.exc_info()[1] else: self.fail('Expected HjsonDecodeError') s = pickle.dumps(err) e = pickle.loads(s) self.assertEqual(err.msg, e.msg) self.assertEqual(err.doc, e.doc) self.assertEqual(err.pos, e.pos) self.assertEqual(err.end, e.end) hjson-py-3.0.2/hjson/tests/test_fail.py000066400000000000000000000130701372777051600201120ustar00rootroot00000000000000import sys from unittest import TestCase import hjson as json # 2007-10-05 JSONDOCS = [ # http://json.org/JSON_checker/test/fail1.json # '"A JSON payload should be an object or array, not a string."', # http://json.org/JSON_checker/test/fail2.json '["Unclosed array"', # http://json.org/JSON_checker/test/fail3.json #'{unquoted_key: "keys must be quoted"}', # http://json.org/JSON_checker/test/fail4.json # '["extra comma",]', # http://json.org/JSON_checker/test/fail5.json '["double extra comma",,]', # http://json.org/JSON_checker/test/fail6.json '[ , "<-- missing value"]', # http://json.org/JSON_checker/test/fail7.json '["Comma after the close"],', # http://json.org/JSON_checker/test/fail8.json '["Extra close"]]', # http://json.org/JSON_checker/test/fail9.json # '{"Extra comma": true,}', # http://json.org/JSON_checker/test/fail10.json '{"Extra value after close": true} "misplaced quoted value"', # http://json.org/JSON_checker/test/fail11.json '{"Illegal expression": 1 + 2}', # http://json.org/JSON_checker/test/fail12.json '{"Illegal invocation": alert()}', # http://json.org/JSON_checker/test/fail13.json '{"Numbers cannot have leading zeroes": 013}', # http://json.org/JSON_checker/test/fail14.json '{"Numbers cannot be hex": 0x14}', # http://json.org/JSON_checker/test/fail15.json '["Illegal backslash escape: \\x15"]', # http://json.org/JSON_checker/test/fail16.json '[\\naked]', # http://json.org/JSON_checker/test/fail17.json '["Illegal backslash escape: \\017"]', # http://json.org/JSON_checker/test/fail18.json # '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]', # http://json.org/JSON_checker/test/fail19.json '{"Missing colon" null}', # http://json.org/JSON_checker/test/fail20.json '{"Double colon":: null}', # http://json.org/JSON_checker/test/fail21.json '{"Comma instead of colon", null}', # http://json.org/JSON_checker/test/fail22.json '["Colon instead of comma": false]', # http://json.org/JSON_checker/test/fail23.json '["Bad value", truth]', # http://json.org/JSON_checker/test/fail24.json #"['single quote']", # http://json.org/JSON_checker/test/fail25.json '["\ttab\tcharacter\tin\tstring\t"]', # http://json.org/JSON_checker/test/fail26.json '["tab\\ character\\ in\\ string\\ "]', # http://json.org/JSON_checker/test/fail27.json '["line\nbreak"]', # http://json.org/JSON_checker/test/fail28.json '["line\\\nbreak"]', # http://json.org/JSON_checker/test/fail29.json '[0e]', # http://json.org/JSON_checker/test/fail30.json '[0e+]', # http://json.org/JSON_checker/test/fail31.json '[0e+-1]', # http://json.org/JSON_checker/test/fail32.json '{"Comma instead if closing brace": true,', # http://json.org/JSON_checker/test/fail33.json '["mismatch"}', # http://code.google.com/p/simplejson/issues/detail?id=3 u'["A\u001FZ control characters in string"]', # misc based on coverage '{', '{]', '{"foo": "bar"]', '{"foo": "bar"', ] class TestFail(TestCase): def test_failures(self): for idx, doc in enumerate(JSONDOCS): idx = idx + 1 try: json.loads(doc) except json.HjsonDecodeError: pass else: self.fail("Expected failure for fail%d.json: %r" % (idx, doc)) def test_array_decoder_issue46(self): # http://code.google.com/p/simplejson/issues/detail?id=46 for doc in [u'[,]', '[,]']: try: json.loads(doc) except json.HjsonDecodeError: pass except Exception: e = sys.exc_info()[1] self.fail("Unexpected exception raised %r %s" % (e, e)) else: self.fail("Unexpected success parsing '[,]'") def test_truncated_input(self): test_cases = [ ('[', "End of input while parsing an array", 1), # ('[42', "Expecting ',' delimiter", 3), ('[42,', 'Expecting value', 4), ('["', 'Unterminated string starting at', 1), ('["spam', 'Unterminated string starting at', 1), # ('["spam"', "Expecting ',' delimiter", 7), ('["spam",', 'Expecting value', 8), ('{', 'Bad key name (eof)', 1), ('{"', 'Unterminated string starting at', 1), ('{"spam', 'Unterminated string starting at', 1), ('{"spam"', "Expecting ':' delimiter", 7), ('{"spam":', 'Expecting value', 8), # ('{"spam":42', "Expecting ',' delimiter", 10), ('{"spam":42,', 'Bad key name (eof)', 11), ('"', 'Unterminated string starting at', 0), ('"spam', 'Unterminated string starting at', 0), ('[,', "Found a punctuator character", 1), ] for data, msg, idx in test_cases: try: json.loads(data) except json.HjsonDecodeError: e = sys.exc_info()[1] self.assertEqual( e.msg[:len(msg)], msg, "%r doesn't start with %r for %r" % (e.msg, msg, data)) self.assertEqual( e.pos, idx, "pos %r != %r for %r" % (e.pos, idx, data)) except Exception: e = sys.exc_info()[1] self.fail("Unexpected exception raised %r %s" % (e, e)) else: self.fail("Unexpected success parsing '%r'" % (data,)) hjson-py-3.0.2/hjson/tests/test_float.py000066400000000000000000000017631372777051600203120ustar00rootroot00000000000000import math from unittest import TestCase from hjson.compat import long_type, text_type import hjson as json from hjson.decoder import NaN, PosInf, NegInf class TestFloat(TestCase): def test_degenerates_ignore(self): for f in (PosInf, NegInf, NaN): self.assertEqual(json.loads(json.dumpsJSON(f)), None) def test_floats(self): for num in [1617161771.7650001, math.pi, math.pi**100, math.pi**-100, 3.1]: self.assertEqual(float(json.dumpsJSON(num)), num) self.assertEqual(json.loads(json.dumpsJSON(num)), num) self.assertEqual(json.loads(text_type(json.dumpsJSON(num))), num) def test_ints(self): for num in [1, long_type(1), 1<<32, 1<<64]: self.assertEqual(json.dumpsJSON(num), str(num)) self.assertEqual(int(json.dumpsJSON(num)), num) self.assertEqual(json.loads(json.dumpsJSON(num)), num) self.assertEqual(json.loads(text_type(json.dumpsJSON(num))), num) hjson-py-3.0.2/hjson/tests/test_for_json.py000066400000000000000000000053321372777051600210200ustar00rootroot00000000000000import unittest import hjson as json class ForJson(object): def for_json(self): return {'for_json': 1} class NestedForJson(object): def for_json(self): return {'nested': ForJson()} class ForJsonList(object): def for_json(self): return ['list'] class DictForJson(dict): def for_json(self): return {'alpha': 1} class ListForJson(list): def for_json(self): return ['list'] class TestForJson(unittest.TestCase): def assertRoundTrip(self, obj, other, for_json=True): if for_json is None: # None will use the default s = json.dumpsJSON(obj) else: s = json.dumpsJSON(obj, for_json=for_json) self.assertEqual( json.loads(s), other) def test_for_json_encodes_stand_alone_object(self): self.assertRoundTrip( ForJson(), ForJson().for_json()) def test_for_json_encodes_object_nested_in_dict(self): self.assertRoundTrip( {'hooray': ForJson()}, {'hooray': ForJson().for_json()}) def test_for_json_encodes_object_nested_in_list_within_dict(self): self.assertRoundTrip( {'list': [0, ForJson(), 2, 3]}, {'list': [0, ForJson().for_json(), 2, 3]}) def test_for_json_encodes_object_nested_within_object(self): self.assertRoundTrip( NestedForJson(), {'nested': {'for_json': 1}}) def test_for_json_encodes_list(self): self.assertRoundTrip( ForJsonList(), ForJsonList().for_json()) def test_for_json_encodes_list_within_object(self): self.assertRoundTrip( {'nested': ForJsonList()}, {'nested': ForJsonList().for_json()}) def test_for_json_encodes_dict_subclass(self): self.assertRoundTrip( DictForJson(a=1), DictForJson(a=1).for_json()) def test_for_json_encodes_list_subclass(self): self.assertRoundTrip( ListForJson(['l']), ListForJson(['l']).for_json()) def test_for_json_ignored_if_not_true_with_dict_subclass(self): for for_json in (None, False): self.assertRoundTrip( DictForJson(a=1), {'a': 1}, for_json=for_json) def test_for_json_ignored_if_not_true_with_list_subclass(self): for for_json in (None, False): self.assertRoundTrip( ListForJson(['l']), ['l'], for_json=for_json) def test_raises_typeerror_if_for_json_not_true_with_object(self): self.assertRaises(TypeError, json.dumpsJSON, ForJson()) self.assertRaises(TypeError, json.dumpsJSON, ForJson(), for_json=False) hjson-py-3.0.2/hjson/tests/test_hjson.py000066400000000000000000000044271372777051600203260ustar00rootroot00000000000000from __future__ import with_statement import os import sys import subprocess import tempfile import codecs # dump from unittest import TestCase import hjson class TestAssets(TestCase): def __init__(self, *args, **kwargs): super(TestAssets, self).__init__(*args, **kwargs) self.assetsDir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "assets") self.assets = self.load('testlist.txt', False).split('\n') self.maxDiff = None self.verma, self.vermi = sys.version_info[0:2] def load(self, name, cr): name = os.path.join(self.assetsDir, name) with open(name, 'rb') as f: text = f.read().decode('utf-8') text = text.replace('\r', '') if cr: text = text.replace('\n', '\r\n') return text def check(self, name, file, inputCr): text = self.load(file, inputCr) shouldFail = name[0:4] == "fail" try: data = hjson.loads(text) self.assertFalse(shouldFail, file) text1 = hjson.dumpsJSON(data) hjson1 = hjson.dumps(data, ensure_ascii=False); result = hjson.loads(self.load(name + "_result.json", inputCr)) text2 = hjson.dumpsJSON(result) hjson2 = self.load(name + "_result.hjson", False) # dbg # with open(name + "_dbg1.txt", "w") as tmp: tmp.write(hjson1.encode("utf-8")) # with open(name + "_dbg2.txt", "w") as tmp: tmp.write(hjson2.encode("utf-8")) # with codecs.open(name + "_dbg3.txt", 'w', 'utf-8') as tmp: hjson.dump(data, tmp) if self.verma>2 or self.vermi>6: # final check fails on py2.6 because of string formatting issues self.assertEqual(text2, text1, file) self.assertEqual(hjson2, hjson1, file) except hjson.HjsonDecodeError as e: if not shouldFail: self.fail("raised error on parsing %s: %r" % (file, e)) def test_files(self): for file in self.assets: name, sep, ext = file.partition("_test.") if name.startswith("stringify/quotes") or \ name.startswith("extra/"): continue # ignore/not supported self.check(name, file, True) self.check(name, file, False) hjson-py-3.0.2/hjson/tests/test_indent.py000066400000000000000000000050351372777051600204620ustar00rootroot00000000000000from unittest import TestCase import textwrap import hjson as json from hjson.compat import StringIO class TestIndent(TestCase): def test_indent(self): h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth', {'nifty': 87}, {'field': 'yes', 'morefield': False} ] expect = textwrap.dedent("""\ [ \t[ \t\t"blorpie" \t], \t[ \t\t"whoops" \t], \t[], \t"d-shtaeou", \t"d-nthiouh", \t"i-vhbjkhnth", \t{ \t\t"nifty": 87 \t}, \t{ \t\t"field": "yes", \t\t"morefield": false \t} ]""") d1 = json.dumpsJSON(h) d2 = json.dumpsJSON(h, indent='\t', sort_keys=True, separators=(',', ': ')) d3 = json.dumpsJSON(h, indent=' ', sort_keys=True, separators=(',', ': ')) d4 = json.dumpsJSON(h, indent=2, sort_keys=True, separators=(',', ': ')) h1 = json.loads(d1) h2 = json.loads(d2) h3 = json.loads(d3) h4 = json.loads(d4) self.assertEqual(h1, h) self.assertEqual(h2, h) self.assertEqual(h3, h) self.assertEqual(h4, h) self.assertEqual(d3, expect.replace('\t', ' ')) self.assertEqual(d4, expect.replace('\t', ' ')) # NOTE: Python 2.4 textwrap.dedent converts tabs to spaces, # so the following is expected to fail. Python 2.4 is not a # supported platform in hjson 2.1.0+. self.assertEqual(d2, expect) def test_indent0(self): h = {3: 1} def check(indent, expected): d1 = json.dumpsJSON(h, indent=indent) self.assertEqual(d1, expected) sio = StringIO() json.dumpJSON(h, sio, indent=indent) self.assertEqual(sio.getvalue(), expected) # indent=0 should emit newlines check(0, '{\n"3": 1\n}') # indent=None is more compact check(None, '{"3": 1}') def test_separators(self): lst = [1,2,3,4] expect = '[\n1,\n2,\n3,\n4\n]' expect_spaces = '[\n1, \n2, \n3, \n4\n]' # Ensure that separators still works self.assertEqual( expect_spaces, json.dumpsJSON(lst, indent=0, separators=(', ', ': '))) # Force the new defaults self.assertEqual( expect, json.dumpsJSON(lst, indent=0, separators=(',', ': '))) # Added in 2.1.4 self.assertEqual( expect, json.dumpsJSON(lst, indent=0)) hjson-py-3.0.2/hjson/tests/test_item_sort_key.py000066400000000000000000000021561372777051600220570ustar00rootroot00000000000000from unittest import TestCase import hjson as json from operator import itemgetter class TestItemSortKey(TestCase): def test_simple_first(self): a = {'a': 1, 'c': 5, 'jack': 'jill', 'pick': 'axe', 'array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'} self.assertEqual( '{"a": 1, "c": 5, "crate": "dog", "jack": "jill", "pick": "axe", "zeak": "oh", "array": [1, 5, 6, 9], "tuple": [83, 12, 3]}', json.dumpsJSON(a, item_sort_key=json.simple_first)) def test_case(self): a = {'a': 1, 'c': 5, 'Jack': 'jill', 'pick': 'axe', 'Array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'} self.assertEqual( '{"Array": [1, 5, 6, 9], "Jack": "jill", "a": 1, "c": 5, "crate": "dog", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}', json.dumpsJSON(a, item_sort_key=itemgetter(0))) self.assertEqual( '{"a": 1, "Array": [1, 5, 6, 9], "c": 5, "crate": "dog", "Jack": "jill", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}', json.dumpsJSON(a, item_sort_key=lambda kv: kv[0].lower())) hjson-py-3.0.2/hjson/tests/test_namedtuple.py000066400000000000000000000077421372777051600213460ustar00rootroot00000000000000from __future__ import absolute_import import unittest import hjson as json from hjson.compat import StringIO try: from collections import namedtuple except ImportError: class Value(tuple): def __new__(cls, *args): return tuple.__new__(cls, args) def _asdict(self): return {'value': self[0]} class Point(tuple): def __new__(cls, *args): return tuple.__new__(cls, args) def _asdict(self): return {'x': self[0], 'y': self[1]} else: Value = namedtuple('Value', ['value']) Point = namedtuple('Point', ['x', 'y']) class DuckValue(object): def __init__(self, *args): self.value = Value(*args) def _asdict(self): return self.value._asdict() class DuckPoint(object): def __init__(self, *args): self.point = Point(*args) def _asdict(self): return self.point._asdict() class DeadDuck(object): _asdict = None class DeadDict(dict): _asdict = None CONSTRUCTORS = [ lambda v: v, lambda v: [v], lambda v: [{'key': v}], ] class TestNamedTuple(unittest.TestCase): def test_namedtuple_dumps(self): for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]: d = v._asdict() self.assertEqual(d, json.loads(json.dumpsJSON(v))) self.assertEqual( d, json.loads(json.dumpsJSON(v, namedtuple_as_object=True))) self.assertEqual(d, json.loads(json.dumpsJSON(v, tuple_as_array=False))) self.assertEqual( d, json.loads(json.dumpsJSON(v, namedtuple_as_object=True, tuple_as_array=False))) def test_namedtuple_dumps_false(self): for v in [Value(1), Point(1, 2)]: l = list(v) self.assertEqual( l, json.loads(json.dumpsJSON(v, namedtuple_as_object=False))) self.assertRaises(TypeError, json.dumpsJSON, v, tuple_as_array=False, namedtuple_as_object=False) def test_namedtuple_dump(self): for v in [Value(1), Point(1, 2), DuckValue(1), DuckPoint(1, 2)]: d = v._asdict() sio = StringIO() json.dumpJSON(v, sio) self.assertEqual(d, json.loads(sio.getvalue())) sio = StringIO() json.dumpJSON(v, sio, namedtuple_as_object=True) self.assertEqual( d, json.loads(sio.getvalue())) sio = StringIO() json.dumpJSON(v, sio, tuple_as_array=False) self.assertEqual(d, json.loads(sio.getvalue())) sio = StringIO() json.dumpJSON(v, sio, namedtuple_as_object=True, tuple_as_array=False) self.assertEqual( d, json.loads(sio.getvalue())) def test_namedtuple_dump_false(self): for v in [Value(1), Point(1, 2)]: l = list(v) sio = StringIO() json.dumpJSON(v, sio, namedtuple_as_object=False) self.assertEqual( l, json.loads(sio.getvalue())) self.assertRaises(TypeError, json.dumpJSON, v, StringIO(), tuple_as_array=False, namedtuple_as_object=False) def test_asdict_not_callable_dump(self): for f in CONSTRUCTORS: self.assertRaises(TypeError, json.dumpJSON, f(DeadDuck()), StringIO(), namedtuple_as_object=True) sio = StringIO() json.dumpJSON(f(DeadDict()), sio, namedtuple_as_object=True) self.assertEqual( json.dumpsJSON(f({})), sio.getvalue()) def test_asdict_not_callable_dumps(self): for f in CONSTRUCTORS: self.assertRaises(TypeError, json.dumpsJSON, f(DeadDuck()), namedtuple_as_object=True) self.assertEqual( json.dumpsJSON(f({})), json.dumpsJSON(f(DeadDict()), namedtuple_as_object=True)) hjson-py-3.0.2/hjson/tests/test_pass1.py000066400000000000000000000033211372777051600202240ustar00rootroot00000000000000from unittest import TestCase import hjson as json # from http://json.org/JSON_checker/test/pass1.json JSON = r''' [ "JSON Test Pattern pass1", {"object with 1 member":["array with 1 element"]}, {}, [], -42, true, false, null, { "integer": 1234567890, "real": -9876.543210, "e": 0.123456789e-12, "E": 1.234567890E+34, "": 23456789012E66, "zero": 0, "one": 1, "space": " ", "quote": "\"", "backslash": "\\", "controls": "\b\f\n\r\t", "slash": "/ & \/", "alpha": "abcdefghijklmnopqrstuvwyz", "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", "digit": "0123456789", "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", "true": true, "false": false, "null": null, "array":[ ], "object":{ }, "address": "50 St. James Street", "url": "http://www.JSON.org/", "comment": "// /* */": " ", " s p a c e d " :[1,2 , 3 , 4 , 5 , 6 ,7 ],"compact": [1,2,3,4,5,6,7], "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", "quotes": "" \u0022 %22 0x22 034 "", "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "A key can be any string" }, 0.5 ,98.6 , 99.44 , 1066, 1e1, 0.1e1, 1e-1, 1e00,2e+00,2e-00 ,"rosebud"] ''' class TestPass1(TestCase): def test_parse(self): # test in/out equivalence and parsing res = json.loads(JSON) out = json.dumpsJSON(res) self.assertEqual(res, json.loads(out)) hjson-py-3.0.2/hjson/tests/test_pass2.py000066400000000000000000000006011372777051600202230ustar00rootroot00000000000000from unittest import TestCase import hjson as json # from http://json.org/JSON_checker/test/pass2.json JSON = r''' [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] ''' class TestPass2(TestCase): def test_parse(self): # test in/out equivalence and parsing res = json.loads(JSON) out = json.dumpsJSON(res) self.assertEqual(res, json.loads(out)) hjson-py-3.0.2/hjson/tests/test_pass3.py000066400000000000000000000007411372777051600202310ustar00rootroot00000000000000from unittest import TestCase import hjson as json # from http://json.org/JSON_checker/test/pass3.json JSON = r''' { "JSON Test Pattern pass3": { "The outermost value": "must be an object or array.", "In this test": "It is an object." } } ''' class TestPass3(TestCase): def test_parse(self): # test in/out equivalence and parsing res = json.loads(JSON) out = json.dumpsJSON(res) self.assertEqual(res, json.loads(out)) hjson-py-3.0.2/hjson/tests/test_recursion.py000066400000000000000000000032361372777051600212130ustar00rootroot00000000000000from unittest import TestCase import hjson as json class JSONTestObject: pass class RecursiveJSONEncoder(json.JSONEncoder): recurse = False def default(self, o): if o is JSONTestObject: if self.recurse: return [JSONTestObject] else: return 'JSONTestObject' return json.JSONEncoder.default(o) class TestRecursion(TestCase): def test_listrecursion(self): x = [] x.append(x) try: json.dumpsJSON(x) except ValueError: pass else: self.fail("didn't raise ValueError on list recursion") x = [] y = [x] x.append(y) try: json.dumpsJSON(x) except ValueError: pass else: self.fail("didn't raise ValueError on alternating list recursion") y = [] x = [y, y] # ensure that the marker is cleared json.dumpsJSON(x) def test_dictrecursion(self): x = {} x["test"] = x try: json.dumpsJSON(x) except ValueError: pass else: self.fail("didn't raise ValueError on dict recursion") x = {} y = {"a": x, "b": x} # ensure that the marker is cleared json.dumpsJSON(y) def test_defaultrecursion(self): enc = RecursiveJSONEncoder() self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"') enc.recurse = True try: enc.encode(JSONTestObject) except ValueError: pass else: self.fail("didn't raise ValueError on default recursion") hjson-py-3.0.2/hjson/tests/test_scanstring.py000066400000000000000000000135011372777051600213510ustar00rootroot00000000000000import sys from unittest import TestCase import hjson as json import hjson.decoder from hjson.compat import b, PY3 class TestScanString(TestCase): # The bytes type is intentionally not used in most of these tests # under Python 3 because the decoder immediately coerces to str before # calling scanstring. In Python 2 we are testing the code paths # for both unicode and str. # # The reason this is done is because Python 3 would require # entirely different code paths for parsing bytes and str. # def test_py_scanstring(self): self._test_scanstring(hjson.decoder.scanstring) def _test_scanstring(self, scanstring): if sys.maxunicode == 65535: self.assertEqual( scanstring(u'"z\U0001d120x"', 1, None, True), (u'z\U0001d120x', 6)) else: self.assertEqual( scanstring(u'"z\U0001d120x"', 1, None, True), (u'z\U0001d120x', 5)) self.assertEqual( scanstring('"\\u007b"', 1, None, True), (u'{', 8)) self.assertEqual( scanstring('"A JSON payload should be an object or array, not a string."', 1, None, True), (u'A JSON payload should be an object or array, not a string.', 60)) self.assertEqual( scanstring('["Unclosed array"', 2, None, True), (u'Unclosed array', 17)) self.assertEqual( scanstring('["extra comma",]', 2, None, True), (u'extra comma', 14)) self.assertEqual( scanstring('["double extra comma",,]', 2, None, True), (u'double extra comma', 21)) self.assertEqual( scanstring('["Comma after the close"],', 2, None, True), (u'Comma after the close', 24)) self.assertEqual( scanstring('["Extra close"]]', 2, None, True), (u'Extra close', 14)) self.assertEqual( scanstring('{"Extra comma": true,}', 2, None, True), (u'Extra comma', 14)) self.assertEqual( scanstring('{"Extra value after close": true} "misplaced quoted value"', 2, None, True), (u'Extra value after close', 26)) self.assertEqual( scanstring('{"Illegal expression": 1 + 2}', 2, None, True), (u'Illegal expression', 21)) self.assertEqual( scanstring('{"Illegal invocation": alert()}', 2, None, True), (u'Illegal invocation', 21)) self.assertEqual( scanstring('{"Numbers cannot have leading zeroes": 013}', 2, None, True), (u'Numbers cannot have leading zeroes', 37)) self.assertEqual( scanstring('{"Numbers cannot be hex": 0x14}', 2, None, True), (u'Numbers cannot be hex', 24)) self.assertEqual( scanstring('[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]', 21, None, True), (u'Too deep', 30)) self.assertEqual( scanstring('{"Missing colon" null}', 2, None, True), (u'Missing colon', 16)) self.assertEqual( scanstring('{"Double colon":: null}', 2, None, True), (u'Double colon', 15)) self.assertEqual( scanstring('{"Comma instead of colon", null}', 2, None, True), (u'Comma instead of colon', 25)) self.assertEqual( scanstring('["Colon instead of comma": false]', 2, None, True), (u'Colon instead of comma', 25)) self.assertEqual( scanstring('["Bad value", truth]', 2, None, True), (u'Bad value', 12)) for c in map(chr, range(0x00, 0x1f)): self.assertEqual( scanstring(c + '"', 0, None, False), (c, 2)) self.assertRaises( ValueError, scanstring, c + '"', 0, None, True) def test_issue3623(self): self.assertRaises(ValueError, json.decoder.scanstring, "xxx", 1, "xxx") self.assertRaises(UnicodeDecodeError, json.encoder.encode_basestring_ascii, b("xx\xff")) def test_surrogates(self): scanstring = json.decoder.scanstring def assertScan(given, expect, test_utf8=True): givens = [given] if not PY3 and test_utf8: givens.append(given.encode('utf8')) for given in givens: (res, count) = scanstring(given, 1, None, True) self.assertEqual(len(given), count) self.assertEqual(res, expect) assertScan( u'"z\\ud834\\u0079x"', u'z\ud834yx') assertScan( u'"z\\ud834\\udd20x"', u'z\U0001d120x') assertScan( u'"z\\ud834\\ud834\\udd20x"', u'z\ud834\U0001d120x') assertScan( u'"z\\ud834x"', u'z\ud834x') assertScan( u'"z\\udd20x"', u'z\udd20x') assertScan( u'"z\ud834x"', u'z\ud834x') # It may look strange to join strings together, but Python is drunk. # https://gist.github.com/etrepum/5538443 assertScan( u'"z\\ud834\udd20x12345"', u''.join([u'z\ud834', u'\udd20x12345'])) assertScan( u'"z\ud834\\udd20x"', u''.join([u'z\ud834', u'\udd20x'])) # these have different behavior given UTF8 input, because the surrogate # pair may be joined (in maxunicode > 65535 builds) assertScan( u''.join([u'"z\ud834', u'\udd20x"']), u''.join([u'z\ud834', u'\udd20x']), test_utf8=False) self.assertRaises(ValueError, scanstring, u'"z\\ud83x"', 1, None, True) self.assertRaises(ValueError, scanstring, u'"z\\ud834\\udd2x"', 1, None, True) hjson-py-3.0.2/hjson/tests/test_separators.py000066400000000000000000000016611372777051600213650ustar00rootroot00000000000000import textwrap from unittest import TestCase import hjson as json class TestSeparators(TestCase): def test_separators(self): h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth', {'nifty': 87}, {'field': 'yes', 'morefield': False} ] expect = textwrap.dedent("""\ [ [ "blorpie" ] , [ "whoops" ] , [] , "d-shtaeou" , "d-nthiouh" , "i-vhbjkhnth" , { "nifty" : 87 } , { "field" : "yes" , "morefield" : false } ]""") d1 = json.dumpsJSON(h) d2 = json.dumpsJSON(h, indent=' ', sort_keys=True, separators=(' ,', ' : ')) h1 = json.loads(d1) h2 = json.loads(d2) self.assertEqual(h1, h) self.assertEqual(h2, h) self.assertEqual(d2, expect) hjson-py-3.0.2/hjson/tests/test_tool.py000066400000000000000000000054121372777051600201550ustar00rootroot00000000000000from __future__ import with_statement import os import sys import textwrap import unittest import subprocess import tempfile try: # Python 3.x from test.support import strip_python_stderr except ImportError: # Python 2.6+ try: from test.test_support import strip_python_stderr except ImportError: # Python 2.5 import re def strip_python_stderr(stderr): return re.sub( r"\[\d+ refs\]\r?\n?$".encode(), "".encode(), stderr).strip() class TestTool(unittest.TestCase): data = """ [["blorpie"],[ "whoops" ] , [ ],\t"d-shtaeou",\r"d-nthiouh", "i-vhbjkhnth", {"nifty":87}, {"morefield" :\tfalse,"field" :"yes"} ] """ expect = textwrap.dedent("""\ [ [ blorpie ] [ whoops ] [] d-shtaeou d-nthiouh i-vhbjkhnth { nifty: 87 } { morefield: false field: yes } ] """) def runTool(self, args=None, data=None): argv = [sys.executable, '-m', 'hjson.tool'] if args: argv.extend(args) proc = subprocess.Popen(argv, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) out, err = proc.communicate(data) self.assertEqual(strip_python_stderr(err), ''.encode()) self.assertEqual(proc.returncode, 0) return out def test_stdin_stdout(self): self.assertEqual( self.runTool(data=self.data.encode()), self.expect.encode()) def test_infile_stdout(self): with tempfile.NamedTemporaryFile() as infile: infile.write(self.data.encode()) infile.flush() self.assertEqual( self.runTool(args=[infile.name]), self.expect.encode()) def x_test_infile_outfile(self): """Not currently an option in tool""" with tempfile.NamedTemporaryFile() as infile: infile.write(self.data.encode()) infile.flush() # outfile will get overwritten by tool, so the delete # may not work on some platforms. Do it manually. outfile = tempfile.NamedTemporaryFile() try: self.assertEqual( self.runTool(args=[infile.name, outfile.name]), ''.encode()) with open(outfile.name, 'rb') as f: self.assertEqual(f.read(), self.expect.encode()) finally: outfile.close() if os.path.exists(outfile.name): os.unlink(outfile.name) hjson-py-3.0.2/hjson/tests/test_tuple.py000066400000000000000000000036701372777051600203350ustar00rootroot00000000000000import unittest from hjson.compat import StringIO import hjson as json class TestTuples(unittest.TestCase): def test_tuple_array_dumps(self): t = (1, 2, 3) expect = json.dumpsJSON(list(t)) # Default is True self.assertEqual(expect, json.dumpsJSON(t)) self.assertEqual(expect, json.dumpsJSON(t, tuple_as_array=True)) self.assertRaises(TypeError, json.dumpsJSON, t, tuple_as_array=False) # Ensure that the "default" does not get called self.assertEqual(expect, json.dumpsJSON(t, default=repr)) self.assertEqual(expect, json.dumpsJSON(t, tuple_as_array=True, default=repr)) # Ensure that the "default" gets called self.assertEqual( json.dumpsJSON(repr(t)), json.dumpsJSON(t, tuple_as_array=False, default=repr)) def test_tuple_array_dump(self): t = (1, 2, 3) expect = json.dumpsJSON(list(t)) # Default is True sio = StringIO() json.dumpJSON(t, sio) self.assertEqual(expect, sio.getvalue()) sio = StringIO() json.dumpJSON(t, sio, tuple_as_array=True) self.assertEqual(expect, sio.getvalue()) self.assertRaises(TypeError, json.dumpJSON, t, StringIO(), tuple_as_array=False) # Ensure that the "default" does not get called sio = StringIO() json.dumpJSON(t, sio, default=repr) self.assertEqual(expect, sio.getvalue()) sio = StringIO() json.dumpJSON(t, sio, tuple_as_array=True, default=repr) self.assertEqual(expect, sio.getvalue()) # Ensure that the "default" gets called sio = StringIO() json.dumpJSON(t, sio, tuple_as_array=False, default=repr) self.assertEqual( json.dumpsJSON(repr(t)), sio.getvalue()) class TestNamedTuple(unittest.TestCase): def test_namedtuple_dump(self): pass hjson-py-3.0.2/hjson/tests/test_unicode.py000066400000000000000000000156731372777051600206400ustar00rootroot00000000000000import sys import codecs from unittest import TestCase import hjson as json from hjson.compat import unichr, text_type, b, u, BytesIO class TestUnicode(TestCase): def test_encoding1(self): encoder = json.JSONEncoder(encoding='utf-8') u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' s = u.encode('utf-8') ju = encoder.encode(u) js = encoder.encode(s) self.assertEqual(ju, js) def test_encoding2(self): u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' s = u.encode('utf-8') ju = json.dumpsJSON(u, encoding='utf-8') js = json.dumpsJSON(s, encoding='utf-8') self.assertEqual(ju, js) def test_encoding3(self): u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' j = json.dumpsJSON(u) self.assertEqual(j, '"\\u03b1\\u03a9"') def test_encoding4(self): u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' j = json.dumpsJSON([u]) self.assertEqual(j, '["\\u03b1\\u03a9"]') def test_encoding5(self): u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' j = json.dumpsJSON(u, ensure_ascii=False) self.assertEqual(j, u'"' + u + u'"') def test_encoding6(self): u = u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}' j = json.dumpsJSON([u], ensure_ascii=False) self.assertEqual(j, u'["' + u + u'"]') def test_big_unicode_encode(self): u = u'\U0001d120' self.assertEqual(json.dumpsJSON(u), '"\\ud834\\udd20"') self.assertEqual(json.dumpsJSON(u, ensure_ascii=False), u'"\U0001d120"') def test_big_unicode_decode(self): u = u'z\U0001d120x' self.assertEqual(json.loads('"' + u + '"'), u) self.assertEqual(json.loads('"z\\ud834\\udd20x"'), u) def test_unicode_decode(self): for i in range(0, 0xd7ff): u = unichr(i) #s = '"\\u{0:04x}"'.format(i) s = '"\\u%04x"' % (i,) self.assertEqual(json.loads(s), u) def test_object_pairs_hook_with_unicode(self): s = u'{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' p = [(u"xkd", 1), (u"kcw", 2), (u"art", 3), (u"hxm", 4), (u"qrt", 5), (u"pad", 6), (u"hoy", 7)] self.assertEqual(json.loads(s), eval(s)) self.assertEqual(json.loads(s, object_pairs_hook=lambda x: x), p) od = json.loads(s, object_pairs_hook=json.OrderedDict) self.assertEqual(od, json.OrderedDict(p)) self.assertEqual(type(od), json.OrderedDict) # the object_pairs_hook takes priority over the object_hook self.assertEqual(json.loads(s, object_pairs_hook=json.OrderedDict, object_hook=lambda x: None), json.OrderedDict(p)) def test_default_encoding(self): self.assertEqual(json.loads(u'{"a": "\xe9"}'.encode('utf-8')), {'a': u'\xe9'}) def test_unicode_preservation(self): self.assertEqual(type(json.loads(u'""')), text_type) self.assertEqual(type(json.loads(u'"a"')), text_type) self.assertEqual(type(json.loads(u'["a"]')[0]), text_type) def test_ensure_ascii_false_returns_unicode(self): # http://code.google.com/p/simplejson/issues/detail?id=48 self.assertEqual(type(json.dumpsJSON([], ensure_ascii=False)), text_type) self.assertEqual(type(json.dumpsJSON(0, ensure_ascii=False)), text_type) self.assertEqual(type(json.dumpsJSON({}, ensure_ascii=False)), text_type) self.assertEqual(type(json.dumpsJSON("", ensure_ascii=False)), text_type) def test_ensure_ascii_false_bytestring_encoding(self): # http://code.google.com/p/simplejson/issues/detail?id=48 doc1 = {u'quux': b('Arr\xc3\xaat sur images')} doc2 = {u'quux': u('Arr\xeat sur images')} doc_ascii = '{"quux": "Arr\\u00eat sur images"}' doc_unicode = u'{"quux": "Arr\xeat sur images"}' self.assertEqual(json.dumpsJSON(doc1), doc_ascii) self.assertEqual(json.dumpsJSON(doc2), doc_ascii) self.assertEqual(json.dumpsJSON(doc1, ensure_ascii=False), doc_unicode) self.assertEqual(json.dumpsJSON(doc2, ensure_ascii=False), doc_unicode) def test_ensure_ascii_linebreak_encoding(self): # http://timelessrepo.com/json-isnt-a-javascript-subset s1 = u'\u2029\u2028' s2 = s1.encode('utf8') expect = '"\\u2029\\u2028"' self.assertEqual(json.dumpsJSON(s1), expect) self.assertEqual(json.dumpsJSON(s2), expect) self.assertEqual(json.dumpsJSON(s1, ensure_ascii=False), expect) self.assertEqual(json.dumpsJSON(s2, ensure_ascii=False), expect) def test_invalid_escape_sequences(self): # incomplete escape sequence self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u1') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u12') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u123') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u1234') # invalid escape sequence self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u123x"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u12x4"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\u1x34"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ux234"') if sys.maxunicode > 65535: # invalid escape sequence for low surrogate self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u0"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u00"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u000"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u000x"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u00x0"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\u0x00"') self.assertRaises(json.HjsonDecodeError, json.loads, '"\\ud800\\ux000"') def test_ensure_ascii_still_works(self): # in the ascii range, ensure that everything is the same for c in map(unichr, range(0, 127)): self.assertEqual( json.dumpsJSON(c, ensure_ascii=False), json.dumpsJSON(c)) snowman = u'\N{SNOWMAN}' self.assertEqual( json.dumpsJSON(c, ensure_ascii=False), '"' + c + '"') def test_strip_bom(self): content = u"\u3053\u3093\u306b\u3061\u308f" json_doc = codecs.BOM_UTF8 + b(json.dumpsJSON(content)) self.assertEqual(json.load(BytesIO(json_doc)), content) for doc in json_doc, json_doc.decode('utf8'): self.assertEqual(json.loads(doc), content) hjson-py-3.0.2/hjson/tool.py000066400000000000000000000036541372777051600157620ustar00rootroot00000000000000r"""Command-line tool to validate and pretty-print JSON Usage:: $ echo '{"json":"obj"}' | hjson { "json": "obj" } """ from __future__ import with_statement import sys import hjson import pkg_resources # part of setuptools HELP="""Hjson, a user interface for JSON Usage: hjson [options] hjson [options] hjson (-h | --help) hjson (-V | --version) Options: -h --help Show this screen. -j Output as formatted JSON. -c Output as JSON. -V --version Show version. """; def showerr(msg): sys.stderr.write(msg) sys.stderr.write("\n") def main(): format = 'hjson' args = [] for arg in sys.argv[1:]: if arg == '-h' or arg == '--help': showerr(HELP) return elif arg == '-j': format = 'json' elif arg == '-c': format = 'compact' elif arg == '-V' or arg == '--version': showerr('Hjson ' + pkg_resources.require("Hjson")[0].version) return elif arg[0] == '-': showerr(HELP) raise SystemExit('unknown option ' + arg) else: args.append(arg) outfile = sys.stdout if len(args) == 0: infile = sys.stdin elif len(args) == 1: infile = open(args[0], 'r') else: showerr(HELP) raise SystemExit('unknown options') with infile: try: obj = hjson.load(infile, use_decimal=True) except ValueError: raise SystemExit(sys.exc_info()[1]) with outfile: if format == 'json': hjson.dumpJSON(obj, outfile, ensure_ascii=False, use_decimal=True, indent=' ') elif format == 'compact': hjson.dumpJSON(obj, outfile, ensure_ascii=False, use_decimal=True, separators=(',', ':')) else: hjson.dump(obj, outfile, ensure_ascii=False, use_decimal=True) outfile.write('\n') if __name__ == '__main__': main() hjson-py-3.0.2/setup.py000066400000000000000000000042731372777051600150220ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import with_statement import sys try: from setuptools import setup, Command except ImportError: from distutils.core import setup, Command from distutils.errors import CCompilerError, DistutilsExecError, \ DistutilsPlatformError IS_PYPY = hasattr(sys, 'pypy_translation_info') VERSION = '3.0.2' DESCRIPTION = "Hjson, a user interface for JSON." with open('README.rst', 'r') as f: LONG_DESCRIPTION = f.read() CLASSIFIERS = filter(None, map(str.strip, """ Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: OSI Approved :: MIT License License :: OSI Approved :: Academic Free License (AFL) Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.6 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.3 Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: Implementation :: PyPy Topic :: Software Development :: Libraries :: Python Modules """.splitlines())) class BuildFailed(Exception): pass class TestCommand(Command): user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): import sys, subprocess raise SystemExit( subprocess.call([sys.executable, # Turn on deprecation warnings '-Wd', 'hjson/tests/__init__.py'])) def run_setup(): cmdclass = dict(test=TestCommand) kw = dict(cmdclass=cmdclass) setup( name="hjson", version=VERSION, description=DESCRIPTION, long_description=LONG_DESCRIPTION, keywords="json comments configuration", classifiers=CLASSIFIERS, author="Christian Zangl", author_email="laktak@cdak.net", url="http://github.com/hjson/hjson-py", license="MIT License", packages=['hjson', 'hjson.tests'], platforms=['any'], scripts=['bin/hjson', 'bin/hjson.cmd',], **kw) run_setup()