python-jsonstore 1.3.3__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jsonstore.py +62 -40
- python_jsonstore-2.0.0.dist-info/METADATA +124 -0
- python_jsonstore-2.0.0.dist-info/RECORD +6 -0
- {python_jsonstore-1.3.3.dist-info → python_jsonstore-2.0.0.dist-info}/WHEEL +1 -1
- python_jsonstore-1.3.3.dist-info/METADATA +0 -152
- python_jsonstore-1.3.3.dist-info/RECORD +0 -6
- {python_jsonstore-1.3.3.dist-info → python_jsonstore-2.0.0.dist-info}/licenses/LICENCE.md +0 -0
- {python_jsonstore-1.3.3.dist-info → python_jsonstore-2.0.0.dist-info}/top_level.txt +0 -0
jsonstore.py
CHANGED
|
@@ -5,19 +5,16 @@ Provides a Python class that maps values to/from a JSON file
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import absolute_import
|
|
7
7
|
import json
|
|
8
|
-
import os
|
|
9
|
-
import
|
|
8
|
+
import os
|
|
9
|
+
import stat
|
|
10
10
|
from collections import OrderedDict
|
|
11
11
|
from copy import deepcopy
|
|
12
|
+
from tempfile import mkstemp
|
|
12
13
|
|
|
13
14
|
__all__ = ["JsonStore"]
|
|
14
15
|
|
|
15
16
|
STRING_TYPES = (str,)
|
|
16
|
-
|
|
17
|
-
if sys.version_info < (3,):
|
|
18
|
-
STRING_TYPES += (unicode,)
|
|
19
|
-
INT_TYPES += (long,)
|
|
20
|
-
VALUE_TYPES = (bool, int, float, type(None)) + INT_TYPES
|
|
17
|
+
VALUE_TYPES = (bool, int, float, type(None))
|
|
21
18
|
|
|
22
19
|
|
|
23
20
|
class JsonStore(object):
|
|
@@ -34,7 +31,11 @@ class JsonStore(object):
|
|
|
34
31
|
if any(args):
|
|
35
32
|
self.__dict__["_data"] = previous_state
|
|
36
33
|
elif not self.__dict__["_states"]:
|
|
37
|
-
|
|
34
|
+
try:
|
|
35
|
+
self._save()
|
|
36
|
+
except BaseException:
|
|
37
|
+
self.__dict__["_data"] = previous_state
|
|
38
|
+
raise
|
|
38
39
|
|
|
39
40
|
def _do_auto_commit(self):
|
|
40
41
|
if self._auto_commit and not self.__dict__["_states"]:
|
|
@@ -56,25 +57,39 @@ class JsonStore(object):
|
|
|
56
57
|
self.__dict__["_data"] = data
|
|
57
58
|
|
|
58
59
|
def _save(self):
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
output = json.dumps(self._data, indent=self._indent).encode("utf-8")
|
|
61
|
+
try:
|
|
62
|
+
mode = stat.S_IMODE(os.stat(self._path).st_mode)
|
|
63
|
+
except FileNotFoundError:
|
|
64
|
+
mode = None
|
|
65
|
+
descriptor, temp = mkstemp(
|
|
66
|
+
prefix="." + os.path.basename(self._path) + ".",
|
|
67
|
+
suffix=".tmp",
|
|
68
|
+
dir=os.path.dirname(os.path.abspath(self._path)),
|
|
69
|
+
)
|
|
70
|
+
try:
|
|
71
|
+
with os.fdopen(descriptor, "wb") as store:
|
|
72
|
+
store.write(output)
|
|
73
|
+
if mode is not None:
|
|
74
|
+
os.chmod(temp, mode)
|
|
65
75
|
os.replace(temp, self._path)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
finally:
|
|
77
|
+
try:
|
|
78
|
+
os.unlink(temp)
|
|
79
|
+
except FileNotFoundError:
|
|
80
|
+
pass
|
|
81
|
+
except PermissionError:
|
|
82
|
+
if os.name != "nt":
|
|
83
|
+
raise
|
|
84
|
+
os.chmod(temp, stat.S_IWRITE)
|
|
85
|
+
os.unlink(temp)
|
|
71
86
|
|
|
72
87
|
def __init__(self, path, indent=2, auto_commit=True):
|
|
73
88
|
self.__dict__.update(
|
|
74
89
|
{
|
|
75
90
|
"_auto_commit": auto_commit,
|
|
76
91
|
"_data": None,
|
|
77
|
-
"_path": path,
|
|
92
|
+
"_path": os.fsdecode(path),
|
|
78
93
|
"_indent": indent,
|
|
79
94
|
"_states": [],
|
|
80
95
|
}
|
|
@@ -93,25 +108,26 @@ class JsonStore(object):
|
|
|
93
108
|
Raise an exception if the object is not suitable for assignment.
|
|
94
109
|
|
|
95
110
|
"""
|
|
96
|
-
|
|
97
|
-
if isinstance(obj, (dict, list)):
|
|
111
|
+
if isinstance(obj, (dict, list, tuple)):
|
|
98
112
|
if parents is None:
|
|
99
|
-
parents =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
parents = set()
|
|
114
|
+
identity = id(obj)
|
|
115
|
+
if identity in parents:
|
|
116
|
+
raise ValueError("Cycle detected in list/dictionary/tuple")
|
|
117
|
+
parents.add(identity)
|
|
118
|
+
try:
|
|
119
|
+
if isinstance(obj, dict):
|
|
120
|
+
for key, value in obj.items():
|
|
121
|
+
if not cls._valid_string(key):
|
|
122
|
+
raise TypeError("a dict has non-string keys")
|
|
123
|
+
cls._verify_object(value, parents)
|
|
124
|
+
else:
|
|
125
|
+
for value in obj:
|
|
126
|
+
cls._verify_object(value, parents)
|
|
127
|
+
finally:
|
|
128
|
+
parents.remove(identity)
|
|
129
|
+
elif not cls._valid_value(obj):
|
|
130
|
+
raise TypeError("unsupported JSON value type: %s" % type(obj).__name__)
|
|
115
131
|
|
|
116
132
|
@classmethod
|
|
117
133
|
def _valid_value(cls, value):
|
|
@@ -143,11 +159,14 @@ class JsonStore(object):
|
|
|
143
159
|
|
|
144
160
|
def __setattr__(self, attr, value):
|
|
145
161
|
self._verify_object(value)
|
|
146
|
-
|
|
162
|
+
value = deepcopy(value)
|
|
163
|
+
self._verify_object(value)
|
|
164
|
+
self._data[attr] = value
|
|
147
165
|
self._do_auto_commit()
|
|
148
166
|
|
|
149
167
|
def __delattr__(self, attr):
|
|
150
168
|
del self._data[attr]
|
|
169
|
+
self._do_auto_commit()
|
|
151
170
|
|
|
152
171
|
def __get_obj(self, steps):
|
|
153
172
|
"""Returns the object which is under the given path."""
|
|
@@ -168,11 +187,13 @@ class JsonStore(object):
|
|
|
168
187
|
steps = self._canonical_key(key)
|
|
169
188
|
path, step = steps[:-1], steps[-1]
|
|
170
189
|
self._verify_object(value)
|
|
190
|
+
value = deepcopy(value)
|
|
191
|
+
self._verify_object(value)
|
|
171
192
|
container = self.__get_obj(path)
|
|
172
193
|
if isinstance(container, dict) and not self._valid_string(step):
|
|
173
194
|
raise TypeError("%s is a dict and %s is not a string" % (path, step))
|
|
174
195
|
try:
|
|
175
|
-
container[step] =
|
|
196
|
+
container[step] = value
|
|
176
197
|
except (IndexError, TypeError) as e:
|
|
177
198
|
raise type(e)("unable to set %s from %s: %s" % (step, path, e))
|
|
178
199
|
self._do_auto_commit()
|
|
@@ -190,6 +211,7 @@ class JsonStore(object):
|
|
|
190
211
|
del obj[step]
|
|
191
212
|
except (KeyError, IndexError, TypeError) as e:
|
|
192
213
|
raise type(e)("unable to delete %s from %s: %s" % (step, path, e))
|
|
214
|
+
self._do_auto_commit()
|
|
193
215
|
|
|
194
216
|
def __contains__(self, key):
|
|
195
217
|
steps = self._canonical_key(key)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-jsonstore
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Map JSON files onto Python attributes for simple configuration storage
|
|
5
|
+
Author-email: Oliver Bristow <github+pypi@oliverbristow.co.uk>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Code0x58/python-jsonstore/
|
|
8
|
+
Keywords: json,key,value,store
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
20
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
21
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
22
|
+
Classifier: Topic :: Database
|
|
23
|
+
Classifier: Topic :: Software Development
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/x-rst
|
|
26
|
+
License-File: LICENCE.md
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
|PyPI| |Build Status| |Coverage Report|
|
|
30
|
+
|
|
31
|
+
jsonstore
|
|
32
|
+
=========
|
|
33
|
+
|
|
34
|
+
``JsonStore`` maps a JSON object's keys to Python attributes. Use it to
|
|
35
|
+
load and save configuration containing nested dictionaries and lists.
|
|
36
|
+
|
|
37
|
+
Requires Python 3.9 or newer. Tests run on CPython 3.9–3.15 and PyPy 3.11.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
|
|
42
|
+
Install with ``pip install python-jsonstore``.
|
|
43
|
+
|
|
44
|
+
Basics
|
|
45
|
+
~~~~~~
|
|
46
|
+
|
|
47
|
+
.. code:: python
|
|
48
|
+
|
|
49
|
+
from jsonstore import JsonStore
|
|
50
|
+
|
|
51
|
+
# Assignments and deletions are saved automatically.
|
|
52
|
+
store = JsonStore("config.json")
|
|
53
|
+
store.message = "hello"
|
|
54
|
+
store.options = {"enabled": True, "greeting": "💐"}
|
|
55
|
+
store.numbers = [1, 2, 3]
|
|
56
|
+
assert "message" in store
|
|
57
|
+
del store.message
|
|
58
|
+
|
|
59
|
+
# Dot-separated keys traverse dictionaries.
|
|
60
|
+
store["options.enabled"] = False
|
|
61
|
+
assert store["options", "enabled"] is False
|
|
62
|
+
|
|
63
|
+
# Tuple or list paths also accept list indices and slices.
|
|
64
|
+
assert store["numbers", -1] == 3
|
|
65
|
+
assert store[["numbers", 1]] == 2
|
|
66
|
+
del store["numbers", :2]
|
|
67
|
+
assert store.numbers == [3]
|
|
68
|
+
|
|
69
|
+
# A one-element tuple addresses a literal key containing a dot.
|
|
70
|
+
store[("literal.key",)] = "value"
|
|
71
|
+
|
|
72
|
+
Reads and assignments use deep copies. To update a stored collection,
|
|
73
|
+
assign the modified value back; ``+=`` also does this:
|
|
74
|
+
|
|
75
|
+
.. code:: python
|
|
76
|
+
|
|
77
|
+
store.numbers.append(4)
|
|
78
|
+
assert store.numbers == [3]
|
|
79
|
+
store.numbers += [4, 5]
|
|
80
|
+
assert store.numbers == [3, 4, 5]
|
|
81
|
+
|
|
82
|
+
Use item access for keys that conflict with ``JsonStore`` attributes.
|
|
83
|
+
``indent`` controls JSON formatting and defaults to 2; use ``None`` for
|
|
84
|
+
compact output. ``auto_commit=False`` defers saving until a transaction
|
|
85
|
+
commits.
|
|
86
|
+
|
|
87
|
+
Transactions
|
|
88
|
+
~~~~~~~~~~~~
|
|
89
|
+
|
|
90
|
+
Use ``with store:`` to group changes into a transaction. Transactions may
|
|
91
|
+
be nested; only successful exit from the outermost transaction saves the
|
|
92
|
+
file. An exception in a transaction restores its previous state, including
|
|
93
|
+
when saving fails.
|
|
94
|
+
|
|
95
|
+
.. code:: python
|
|
96
|
+
|
|
97
|
+
from jsonstore import JsonStore
|
|
98
|
+
|
|
99
|
+
with JsonStore("config.json", indent=None, auto_commit=False) as store:
|
|
100
|
+
store.value = 1
|
|
101
|
+
assert JsonStore("config.json").value == 1
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
with store:
|
|
105
|
+
store.value = 2
|
|
106
|
+
with store:
|
|
107
|
+
store.value = 3
|
|
108
|
+
raise ValueError("cancel the transaction")
|
|
109
|
+
except ValueError:
|
|
110
|
+
pass
|
|
111
|
+
assert store.value == 1
|
|
112
|
+
assert JsonStore("config.json").value == 1
|
|
113
|
+
|
|
114
|
+
Transactions provide in-memory rollback, with no locking or coordination
|
|
115
|
+
between writers. Use one writer per file; separate stores do not reload
|
|
116
|
+
each other's changes. Atomic replacement does not guarantee durability
|
|
117
|
+
across a power failure.
|
|
118
|
+
|
|
119
|
+
.. |Build Status| image:: https://github.com/Code0x58/python-jsonstore/actions/workflows/ci.yml/badge.svg
|
|
120
|
+
:target: https://github.com/Code0x58/python-jsonstore/actions/workflows/ci.yml
|
|
121
|
+
.. |PyPI| image:: https://img.shields.io/pypi/v/python-jsonstore.svg
|
|
122
|
+
:target: https://pypi.org/project/python-jsonstore/
|
|
123
|
+
.. |Coverage Report| image:: https://codecov.io/gh/Code0x58/python-jsonstore/branch/master/graph/badge.svg
|
|
124
|
+
:target: https://codecov.io/gh/Code0x58/python-jsonstore
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
jsonstore.py,sha256=9P6hCPeB92dfnSgfdoO2PzcvzxlzBsf836D7bFNIk5c,7334
|
|
2
|
+
python_jsonstore-2.0.0.dist-info/licenses/LICENCE.md,sha256=CYFsxv7F0RTimJ83xSWkMtR8audySdDV_z9XzTr2EP0,1071
|
|
3
|
+
python_jsonstore-2.0.0.dist-info/METADATA,sha256=sc9XZ8fOju_A3_x0Abus8ywKuDj9_dpyCqEi01I-x5I,4290
|
|
4
|
+
python_jsonstore-2.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
5
|
+
python_jsonstore-2.0.0.dist-info/top_level.txt,sha256=5Lr-ZZ_07h17JRcT8M4FAt5aEkwAMHNGZuVHNC7yZ5w,10
|
|
6
|
+
python_jsonstore-2.0.0.dist-info/RECORD,,
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: python-jsonstore
|
|
3
|
-
Version: 1.3.3
|
|
4
|
-
Summary: Map JSON files onto Python attributes for simple configuration storage
|
|
5
|
-
Author-email: Oliver Bristow <github+pypi@oliverbristow.co.uk>
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/Code0x58/python-jsonstore/
|
|
8
|
-
Keywords: json,key,value,store
|
|
9
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
-
Classifier: Operating System :: OS Independent
|
|
13
|
-
Classifier: Programming Language :: Python :: 2
|
|
14
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.4
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
28
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
29
|
-
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
30
|
-
Classifier: Topic :: Database
|
|
31
|
-
Classifier: Topic :: Software Development
|
|
32
|
-
Requires-Python: >=2.7
|
|
33
|
-
Description-Content-Type: text/x-rst
|
|
34
|
-
License-File: LICENCE.md
|
|
35
|
-
Dynamic: license-file
|
|
36
|
-
|
|
37
|
-
|PyPI| |Build Status| |Coverage Report|
|
|
38
|
-
|
|
39
|
-
jsonstore
|
|
40
|
-
=========
|
|
41
|
-
|
|
42
|
-
This module provides a class that maps keys and values from a JSON file
|
|
43
|
-
onto its attributes.
|
|
44
|
-
|
|
45
|
-
The goal was to provide a convenient way of loading and saving
|
|
46
|
-
configuration in a familiar human readable format. This is a bit more
|
|
47
|
-
flexible than the
|
|
48
|
-
`configparser <https://docs.python.org/3/library/configparser.html>`__
|
|
49
|
-
module which is included with Python.
|
|
50
|
-
|
|
51
|
-
This works is tested and working on Python 2.7 and Python 3.6+. It will
|
|
52
|
-
not work on 2.6 or lower. The tests are also executed on PyPy.
|
|
53
|
-
|
|
54
|
-
Examples
|
|
55
|
-
--------
|
|
56
|
-
|
|
57
|
-
Basics
|
|
58
|
-
~~~~~~
|
|
59
|
-
|
|
60
|
-
.. code:: python
|
|
61
|
-
|
|
62
|
-
# by default JsonStore commits on every change unless in a transaction
|
|
63
|
-
store = JsonStore('config.json')
|
|
64
|
-
store.a_string = "something"
|
|
65
|
-
store.a_list = [1, 2, 3]
|
|
66
|
-
store.a_dictionary = {
|
|
67
|
-
'dict-list': [{}],
|
|
68
|
-
'ln(2)': 0.69314718056,
|
|
69
|
-
'for-you': u"💐",
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
# you can use […] to set/get/delete string keys
|
|
73
|
-
store['some_key'] = "a value"
|
|
74
|
-
# the key is split on '.'s and works on dictionaries
|
|
75
|
-
del store['a_dictionary.dict-list']
|
|
76
|
-
store['a_dictionary.new_value'] = "old value"
|
|
77
|
-
# you can also use the syntactic sugar for tuple keys (explicit lists work too)
|
|
78
|
-
assert store['a_dictionary', 'new_value'] == "old value"
|
|
79
|
-
# you can traverse lists too
|
|
80
|
-
assert store['a_list', -1] == 3
|
|
81
|
-
# you can use slices in lists
|
|
82
|
-
assert len(store['a_list', 1:]) == 2
|
|
83
|
-
del store['a_list', :2]
|
|
84
|
-
assert store.a_list == [3]
|
|
85
|
-
|
|
86
|
-
# deep copies are made when assigning values
|
|
87
|
-
my_list = ['fun']
|
|
88
|
-
store.a_list = my_list
|
|
89
|
-
assert store.a_list is not my_list
|
|
90
|
-
assert 'a_list' in store
|
|
91
|
-
|
|
92
|
-
# deep copies are also returned to avoid unsanitary changes being made
|
|
93
|
-
store.a_dictionary['new_value'] = "new value" # won't update the store!
|
|
94
|
-
assert store.a_dictionary['new_value'] == "old value"
|
|
95
|
-
assert store.a_dictionary is not store.a_dictionary
|
|
96
|
-
|
|
97
|
-
# Appending to, extending a list
|
|
98
|
-
>>> store.list = [1, 2, 3]
|
|
99
|
-
|
|
100
|
-
# Because of the fact that .append won't modify the list in the actual file,
|
|
101
|
-
# but only a copy...
|
|
102
|
-
>>> store.list.append(4)
|
|
103
|
-
>>> store.list
|
|
104
|
-
[1, 2, 3]
|
|
105
|
-
|
|
106
|
-
# ... we need to rather use the += operator to append to a list.
|
|
107
|
-
>>> store.list += [4]
|
|
108
|
-
>>> store.list
|
|
109
|
-
[1, 2, 3, 4]
|
|
110
|
-
|
|
111
|
-
# Similarly, we can extend the list
|
|
112
|
-
>>> store.list += [5, 6]
|
|
113
|
-
>>> store.list
|
|
114
|
-
[1, 2, 3, 4, 5, 6]
|
|
115
|
-
|
|
116
|
-
Transactions
|
|
117
|
-
~~~~~~~~~~~~
|
|
118
|
-
|
|
119
|
-
``JsonStore`` objects can be used as `context
|
|
120
|
-
managers <https://www.python.org/dev/peps/pep-0343/>`__ to provide
|
|
121
|
-
transactions which are rolled back in the event of an exception. The
|
|
122
|
-
transaction model is primitive; you can only nest transactions.
|
|
123
|
-
|
|
124
|
-
While a store is put into a transaction, it will not save changes to
|
|
125
|
-
file until all of the transactions have been closed.
|
|
126
|
-
|
|
127
|
-
.. code:: python
|
|
128
|
-
|
|
129
|
-
from jsonstore import JsonStore
|
|
130
|
-
|
|
131
|
-
# even with auto_commit=True, the file won't be saved until the last contexts has been closed
|
|
132
|
-
with JsonStore('config.json', indent=None, auto_commit=False) as store:
|
|
133
|
-
self.value = 1
|
|
134
|
-
|
|
135
|
-
# the context manager will roll back changes made if an exception is raised
|
|
136
|
-
store = JsonStore('config.json', indent=None)
|
|
137
|
-
try:
|
|
138
|
-
with store:
|
|
139
|
-
store.value = "new"
|
|
140
|
-
raise Exception
|
|
141
|
-
except Exception:
|
|
142
|
-
pass
|
|
143
|
-
# here we see the value that was saved previously
|
|
144
|
-
assert store.value == 1
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
.. |Build Status| image:: https://github.com/Code0x58/python-jsonstore/actions/workflows/ci.yml/badge.svg
|
|
148
|
-
:target: https://github.com/Code0x58/python-jsonstore/actions/workflows/ci.yml
|
|
149
|
-
.. |PyPI| image:: https://img.shields.io/pypi/v/python-jsonstore.svg
|
|
150
|
-
:target: https://pypi.org/project/python-jsonstore/
|
|
151
|
-
.. |Coverage Report| image:: https://codecov.io/gh/Code0x58/python-jsonstore/branch/master/graph/badge.svg
|
|
152
|
-
:target: https://codecov.io/gh/Code0x58/python-jsonstore
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
jsonstore.py,sha256=YGCPCsjTnklMHR_neqgbcV6ltQh5A5QKW4rbOQzzXJk,6511
|
|
2
|
-
python_jsonstore-1.3.3.dist-info/licenses/LICENCE.md,sha256=CYFsxv7F0RTimJ83xSWkMtR8audySdDV_z9XzTr2EP0,1071
|
|
3
|
-
python_jsonstore-1.3.3.dist-info/METADATA,sha256=yxS-sej7Mi05NMnx9Zrz3gkLVtIlA8uXpPVBD1Dpbpc,5434
|
|
4
|
-
python_jsonstore-1.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
-
python_jsonstore-1.3.3.dist-info/top_level.txt,sha256=5Lr-ZZ_07h17JRcT8M4FAt5aEkwAMHNGZuVHNC7yZ5w,10
|
|
6
|
-
python_jsonstore-1.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|