view configmix/json.py @ 186:fa101fb0cd7a

Implement an "append" keyword to "configmix.set_assoc()"
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 03 May 2019 19:41:35 +0200
parents b5ce9a8461bf
children b3b5ed34d180
line wrap: on
line source

# -*- coding: utf-8 -*-
#-
# :Copyright: (c) 2018-2019, Franz Glasner. All rights reserved.
# :License:   3-clause BSD. See LICENSE.txt for details.
#-
"""Read JSON-style configuration files.

"""

from __future__ import division, absolute_import, print_function

import io
import json.decoder
try:
    from collections import OrderedDict as DictImpl
except ImportError:
    try:
        from ordereddict import OrderedDict as DictImpl
    except ImportError:
        DictImpl = dict

from .compat import u2fs        


__all__ = ["load"]


#
# Determine whether the JSONDecoder has the "object_pairs_hook"
# parameter once
#
try:
    json.decoder.JSONDecoder(object_pairs_hook=DictImpl)
except TypeError:
    _with_object_pairs_hook = False
else:
    _with_object_pairs_hook = True


def load(filename, encoding="utf-8"):
    """Load a single JSON file with name `filename` and encoding `encoding`.

    """
    with io.open(u2fs(filename), mode="rt", encoding=encoding) as jsfp:
        #
        # The scanner (not to be changed yet) does only recognize decimal
        # integers yet.
        #
        kwds = {
            "parse_int": lambda s: int(s, 0),
            "strict": False
        }
        if _with_object_pairs_hook:
            kwds["object_pairs_hook"] = DictImpl
        decoder = json.decoder.JSONDecoder(**kwds)
        data = decoder.decode(jsfp.read())
        if not isinstance(data, DictImpl):
            raise TypeError("JSON root must be an object (i.e. dict)")
        return data