annotate configmix/json.py @ 654:0d6673d06c2c

Add support for using "tomllib" (in Python's stdlib since 3.11) and "tomli" TOML packages. They are preferred if they are found to be installed. But note that the declared dependency for the "toml" extra nevertheless is the "toml" package. Because it is available for all supported Python versions. So use Python 3.11+ or install "tomli" manually if you want to use the alternate packages.
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 19 May 2022 22:10:59 +0200
parents f454889e41fa
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
122
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
208
bbe8513ea649 Handle flake8 E265 "block comment should start with '# ': use '# :-' instead of '#-' to mark copyright and license comments
Franz Glasner <fzglas.hg@dom66.de>
parents: 207
diff changeset
2 # :-
593
f454889e41fa Adjust copyright year (the end) to 2022
Franz Glasner <fzglas.hg@dom66.de>
parents: 296
diff changeset
3 # :Copyright: (c) 2018-2022, Franz Glasner. All rights reserved.
296
eed16a1ec8f3 Use SPDX license identifiers (either full or short) all over the package
Franz Glasner <fzglas.hg@dom66.de>
parents: 250
diff changeset
4 # :License: BSD-3-Clause. See LICENSE.txt for details.
208
bbe8513ea649 Handle flake8 E265 "block comment should start with '# ': use '# :-' instead of '#-' to mark copyright and license comments
Franz Glasner <fzglas.hg@dom66.de>
parents: 207
diff changeset
5 # :-
122
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
6 """Read JSON-style configuration files.
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
7
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
8 """
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
9
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
10 from __future__ import division, absolute_import, print_function
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
11
250
ff964825a75a Style: placement of "__all__"
Franz Glasner <fzglas.hg@dom66.de>
parents: 237
diff changeset
12
ff964825a75a Style: placement of "__all__"
Franz Glasner <fzglas.hg@dom66.de>
parents: 237
diff changeset
13 __all__ = ["load"]
ff964825a75a Style: placement of "__all__"
Franz Glasner <fzglas.hg@dom66.de>
parents: 237
diff changeset
14
ff964825a75a Style: placement of "__all__"
Franz Glasner <fzglas.hg@dom66.de>
parents: 237
diff changeset
15
122
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
16 import io
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
17 import json.decoder
127
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
18 try:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
19 from collections import OrderedDict as DictImpl
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
20 except ImportError:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
21 try:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
22 from ordereddict import OrderedDict as DictImpl
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
23 except ImportError:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
24 DictImpl = dict
122
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
25
207
b3b5ed34d180 Handle most flake8 errors and warnings.
Franz Glasner <fzglas.hg@dom66.de>
parents: 166
diff changeset
26 from .compat import u2fs
166
b5ce9a8461bf Use the filesystem encoding explicitely where appropriate.
Franz Glasner <fzglas.hg@dom66.de>
parents: 156
diff changeset
27
122
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
28
127
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
29 #
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
30 # Determine whether the JSONDecoder has the "object_pairs_hook"
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
31 # parameter once
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
32 #
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
33 try:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
34 json.decoder.JSONDecoder(object_pairs_hook=DictImpl)
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
35 except TypeError:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
36 _with_object_pairs_hook = False
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
37 else:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
38 _with_object_pairs_hook = True
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
39
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
40
122
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
41 def load(filename, encoding="utf-8"):
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
42 """Load a single JSON file with name `filename` and encoding `encoding`.
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
43
21d92ff8cf31 Begin the handling of JSON-style configuration files
Franz Glasner <hg@dom66.de>
parents:
diff changeset
44 """
166
b5ce9a8461bf Use the filesystem encoding explicitely where appropriate.
Franz Glasner <fzglas.hg@dom66.de>
parents: 156
diff changeset
45 with io.open(u2fs(filename), mode="rt", encoding=encoding) as jsfp:
129
df60417d7665 The JSON scanner allows only decimal integers
Franz Glasner <hg@dom66.de>
parents: 128
diff changeset
46 #
df60417d7665 The JSON scanner allows only decimal integers
Franz Glasner <hg@dom66.de>
parents: 128
diff changeset
47 # The scanner (not to be changed yet) does only recognize decimal
df60417d7665 The JSON scanner allows only decimal integers
Franz Glasner <hg@dom66.de>
parents: 128
diff changeset
48 # integers yet.
df60417d7665 The JSON scanner allows only decimal integers
Franz Glasner <hg@dom66.de>
parents: 128
diff changeset
49 #
127
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
50 kwds = {
128
95ad65c69561 FIX: todo comment: allow **numbers** -- not strings
Franz Glasner <hg@dom66.de>
parents: 127
diff changeset
51 "parse_int": lambda s: int(s, 0),
127
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
52 "strict": False
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
53 }
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
54 if _with_object_pairs_hook:
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
55 kwds["object_pairs_hook"] = DictImpl
5b62d2c0e5a8 Use the available "OrderedDict" class as dict for the JSON parser
Franz Glasner <hg@dom66.de>
parents: 124
diff changeset
56 decoder = json.decoder.JSONDecoder(**kwds)
134
2f2e819e8d17 Check the return type of the JSON and YAML loading functions: they must be a dict alike
Franz Glasner <hg@dom66.de>
parents: 129
diff changeset
57 data = decoder.decode(jsfp.read())
2f2e819e8d17 Check the return type of the JSON and YAML loading functions: they must be a dict alike
Franz Glasner <hg@dom66.de>
parents: 129
diff changeset
58 if not isinstance(data, DictImpl):
137
e84870359e1a Enhance docu
Franz Glasner <hg@dom66.de>
parents: 134
diff changeset
59 raise TypeError("JSON root must be an object (i.e. dict)")
134
2f2e819e8d17 Check the return type of the JSON and YAML loading functions: they must be a dict alike
Franz Glasner <hg@dom66.de>
parents: 129
diff changeset
60 return data