Completed
Pull Request — master (#39)
by Satoru
01:04
created

anyconfig.backend.Parser._load()   A

Complexity

Conditions 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
dl 0
loc 15
rs 9.4285
1
#
2
# Copyright (C) 2011 - 2015 Satoru SATOH <ssato @ redhat.com>
3
# License: MIT
4
#
5
# Ref. python -c "import json; help(json)"
6
#
7
# pylint: disable=import-error
8
"""JSON file backend.
9
10
- Format to support: JSON, http://www.json.org
11
- Requirements: json in python standard library (>= python 2.6) or simplejson
12
- Limitations: None obvious
13
- Special options:
14
15
  - All options of json.load{s,} and json.dump{s,} except object_hook
16
    should work.
17
18
  - See also: https://docs.python.org/3/library/json.html or
19
    https://docs.python.org/2/library/json.html dependent on the python version
20
    to use.
21
"""
22
from __future__ import absolute_import
23
24
import anyconfig.backend.base
25
import anyconfig.compat
26
27
try:
28
    import json
29
except ImportError:
30
    import simplejson as json
31
32
33
_LOAD_OPTS = ["cls", "parse_float", "parse_int", "parse_constant"]
34
_DUMP_OPTS = ["skipkeys", "ensure_ascii", "check_circular", "allow_nan",
35
              "cls", "indent", "separators", "default", "sort_keys"]
36
37
# It seems that 'encoding' argument is not allowed in json.load[s] and
38
# json.dump[s] in JSON module in python 3.x.
39
if not anyconfig.compat.IS_PYTHON_3:
40
    _LOAD_OPTS.append("encoding")
41
    _DUMP_OPTS.append("encoding")
42
43
if not anyconfig.compat.IS_PYTHON_2_6:
44
    _LOAD_OPTS.append("object_pairs_hook")
45
46
47
class Parser(anyconfig.backend.base.FromStreamLoader,
48
             anyconfig.backend.base.ToStreamDumper):
49
    """
50
    Parser for JSON files.
51
    """
52
    _type = "json"
53
    _extensions = ["json", "jsn", "js"]
54
    _load_opts = _LOAD_OPTS
55
    _dump_opts = _DUMP_OPTS
56
57
    dump_to_string = anyconfig.backend.base.to_method(json.dumps)
58
    dump_to_stream = anyconfig.backend.base.to_method(json.dump)
59
60
    def _load(self, load_fn, cntnt_or_strm, to_container, **opts):
61
        """
62
        Load JSON config from given string or stream `cntnt_or_strm`.
63
64
        :param cntnt_or_strm: JSON config content or stream will provide it
65
        :param to_container: callble to make a container object
66
        :param opts: keyword options passed to `json.load[s]`
67
68
        :return: Dict-like object holding configuration
69
        """
70
        if "object_pairs_hook" in self._load_opts:
71
            opts["object_pairs_hook"] = anyconfig.compat.OrderedDict
72
            return to_container(load_fn(cntnt_or_strm, **opts))
73
        else:
74
            return load_fn(cntnt_or_strm, object_hook=to_container, **opts)
75
76
    def load_from_string(self, content, to_container, **opts):
77
        """
78
        Load JSON config from given string `content`.
79
80
        :param content: JSON config content
81
        :param to_container: callble to make a container object
82
        :param opts: keyword options passed to `json.loads`
83
84
        :return: Dict-like object holding configuration
85
        """
86
        return self._load(json.loads, content, to_container, **opts)
87
88
    def load_from_stream(self, stream, to_container, **opts):
89
        """
90
        Load JSON config from given stream `stream`.
91
92
        :param stream: Stream will provide JSON config content string
93
        :param to_container: callble to make a container object
94
        :param opts: keyword options passed to `json.load`
95
96
        :return: Dict-like object holding configuration
97
        """
98
        return self._load(json.load, stream, to_container, **opts)
99
100
# vim:sw=4:ts=4:et:
101