json-database 1.0.2a1__tar.gz → 1.0.3a1__tar.gz

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.
Files changed (27) hide show
  1. {json_database-1.0.2a1 → json_database-1.0.3a1}/PKG-INFO +1 -1
  2. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/__init__.py +12 -4
  3. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/version.py +1 -1
  4. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database.egg-info/PKG-INFO +1 -1
  5. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_storage.py +21 -0
  6. {json_database-1.0.2a1 → json_database-1.0.3a1}/LICENSE +0 -0
  7. {json_database-1.0.2a1 → json_database-1.0.3a1}/README.md +0 -0
  8. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/crypto.py +0 -0
  9. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/exceptions.py +0 -0
  10. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/search.py +0 -0
  11. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/utils.py +0 -0
  12. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database/xdg_utils.py +0 -0
  13. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database.egg-info/SOURCES.txt +0 -0
  14. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database.egg-info/dependency_links.txt +0 -0
  15. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database.egg-info/requires.txt +0 -0
  16. {json_database-1.0.2a1 → json_database-1.0.3a1}/json_database.egg-info/top_level.txt +0 -0
  17. {json_database-1.0.2a1 → json_database-1.0.3a1}/pyproject.toml +0 -0
  18. {json_database-1.0.2a1 → json_database-1.0.3a1}/setup.cfg +0 -0
  19. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_crypto.py +0 -0
  20. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_database.py +0 -0
  21. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_e2e_user_database.py +0 -0
  22. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_encrypted_storage.py +0 -0
  23. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_exceptions.py +0 -0
  24. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_query.py +0 -0
  25. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_search.py +0 -0
  26. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_xdg.py +0 -0
  27. {json_database-1.0.2a1 → json_database-1.0.3a1}/test/test_xdg_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: json_database
3
- Version: 1.0.2a1
3
+ Version: 1.0.3a1
4
4
  Summary: searchable json database with persistence
5
5
  Author-email: jarbasAI <jarbasai@mailfence.com>
6
6
  License: MIT
@@ -93,15 +93,23 @@ class JsonStorage(dict):
93
93
  with self.lock:
94
94
  path = expanduser(path)
95
95
  if exists(path) and isfile(path):
96
- self.clear()
96
+ # Parse into a scratch dict first. Only replace the current
97
+ # in-memory contents once parsing succeeds: a concurrent
98
+ # writer can leave the file transiently truncated/invalid
99
+ # (a "torn read"), and clearing self before the parse is
100
+ # known to succeed would permanently discard previously
101
+ # loaded settings for a purely transient error, with no
102
+ # way to recover them on a later, successful reload.
97
103
  try:
98
104
  config = load_commented_json(path)
99
- for key in config:
100
- self[key] = config[key]
101
- LOG.debug("Json {} loaded".format(path))
102
105
  except Exception as e:
103
106
  LOG.error("Error loading json '{}'".format(path))
104
107
  LOG.error(repr(e))
108
+ return
109
+ self.clear()
110
+ for key in config:
111
+ self[key] = config[key]
112
+ LOG.debug("Json {} loaded".format(path))
105
113
  else:
106
114
  LOG.debug("Json '{}' not defined, skipping".format(path))
107
115
 
@@ -1,7 +1,7 @@
1
1
  # START_VERSION_BLOCK
2
2
  VERSION_MAJOR = 1
3
3
  VERSION_MINOR = 0
4
- VERSION_BUILD = 2
4
+ VERSION_BUILD = 3
5
5
  VERSION_ALPHA = 1
6
6
  # END_VERSION_BLOCK
7
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: json_database
3
- Version: 1.0.2a1
3
+ Version: 1.0.3a1
4
4
  Summary: searchable json database with persistence
5
5
  Author-email: jarbasAI <jarbasai@mailfence.com>
6
6
  License: MIT
@@ -34,6 +34,27 @@ class TestJsonStorageErrorHandling:
34
34
  with pytest.raises(DatabaseNotCommitted):
35
35
  storage.reload()
36
36
 
37
+ def test_reload_survives_torn_write_then_recovers(self, tmp_path):
38
+ """A reload() hitting a transient torn/corrupted write (e.g. an
39
+ external editor caught mid-save) must not wipe out the last known
40
+ good settings, and a later valid write must be picked up normally.
41
+ """
42
+ db_file = tmp_path / "settings.json"
43
+ db_file.write_text(json.dumps({"volume": 5}))
44
+ storage = JsonStorage(str(db_file), disable_lock=True)
45
+ assert storage["volume"] == 5
46
+
47
+ # Simulate a torn read: file caught mid-write, content is invalid.
48
+ db_file.write_text('{"volume": 9, "unit"')
49
+ storage.reload()
50
+ # Previously loaded settings must survive a failed parse.
51
+ assert storage["volume"] == 5
52
+
53
+ # A later, valid write must be reflected normally.
54
+ db_file.write_text(json.dumps({"volume": 9}))
55
+ storage.reload()
56
+ assert storage["volume"] == 9
57
+
37
58
  def test_store_without_path(self, tmp_path):
38
59
  """Test store with no path set."""
39
60
  storage = JsonStorage("", disable_lock=True)
File without changes