persidict 0.37.0__py3-none-any.whl → 0.37.1__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.

Potentially problematic release.


This version of persidict might be problematic. Click here for more details.

@@ -27,8 +27,7 @@ from .jokers import KEEP_CURRENT, DELETE_CURRENT, Joker
27
27
  from .safe_chars import replace_unsafe_chars
28
28
  from .safe_str_tuple import SafeStrTuple
29
29
  from .safe_str_tuple_signing import sign_safe_str_tuple, unsign_safe_str_tuple
30
- from .persi_dict import PersiDict, PersiDictKey
31
-
30
+ from .persi_dict import PersiDict, PersiDictKey, non_empty_persidict_key
32
31
 
33
32
  jsonpickle_numpy.register_handlers()
34
33
  jsonpickle_pandas.register_handlers()
@@ -457,7 +456,7 @@ class FileDirDict(PersiDict):
457
456
  Returns:
458
457
  bool: True if a file for the key exists; False otherwise.
459
458
  """
460
- key = SafeStrTuple(key)
459
+ key = non_empty_persidict_key(key)
461
460
  filename = self._build_full_path(key)
462
461
  return os.path.isfile(filename)
463
462
 
@@ -479,7 +478,7 @@ class FileDirDict(PersiDict):
479
478
  TypeError: If the deserialized value does not match base_class_for_values
480
479
  when it is set.
481
480
  """
482
- key = SafeStrTuple(key)
481
+ key = non_empty_persidict_key(key)
483
482
  filename = self._build_full_path(key)
484
483
  if not os.path.isfile(filename):
485
484
  raise KeyError(f"File {filename} does not exist")
@@ -510,7 +509,7 @@ class FileDirDict(PersiDict):
510
509
  base_class_for_values when it is set.
511
510
  """
512
511
 
513
- key = SafeStrTuple(key)
512
+ key = non_empty_persidict_key(key)
514
513
  PersiDict.__setitem__(self, key, value)
515
514
  if isinstance(value, Joker):
516
515
  # processed by base class
@@ -529,8 +528,7 @@ class FileDirDict(PersiDict):
529
528
  Raises:
530
529
  KeyError: If immutable_items is True or if the key does not exist.
531
530
  """
532
- key = SafeStrTuple(key)
533
- PersiDict.__delitem__(self, key)
531
+ key = non_empty_persidict_key(key)
534
532
  filename = self._build_full_path(key)
535
533
  if not os.path.isfile(filename):
536
534
  raise KeyError(f"File {filename} does not exist")
@@ -627,7 +625,7 @@ class FileDirDict(PersiDict):
627
625
  Raises:
628
626
  FileNotFoundError: If the key does not exist.
629
627
  """
630
- key = SafeStrTuple(key)
628
+ key = non_empty_persidict_key(key)
631
629
  filename = self._build_full_path(key)
632
630
  return os.path.getmtime(filename)
633
631
 
persidict/persi_dict.py CHANGED
@@ -36,6 +36,24 @@ If a string (or a sequence of strings) is passed to a PersiDict as a key,
36
36
  it will be automatically converted into SafeStrTuple.
37
37
  """
38
38
 
39
+
40
+ def non_empty_persidict_key(*args) -> SafeStrTuple:
41
+ """Create a non-empty SafeStrTuple from the given arguments.
42
+ This is a convenience function that ensures the resulting SafeStrTuple is
43
+ not empty, raising a KeyError if it is.
44
+ Args:
45
+ *args: Arguments to pass to SafeStrTuple constructor.
46
+ Returns:
47
+ SafeStrTuple: A non-empty SafeStrTuple instance.
48
+ Raises:
49
+ KeyError: If the resulting SafeStrTuple is empty.
50
+ """
51
+ result = SafeStrTuple(*args)
52
+ if len(result) == 0:
53
+ raise KeyError("Key cannot be empty")
54
+ return result
55
+
56
+
39
57
  class PersiDict(MutableMapping, ParameterizableClass):
40
58
  """Abstract dict-like interface for durable key-value stores.
41
59
 
@@ -209,8 +227,12 @@ class PersiDict(MutableMapping, ParameterizableClass):
209
227
  elif self.immutable_items:
210
228
  if key in self:
211
229
  raise KeyError("Can't modify an immutable key-value pair")
212
- elif value is DELETE_CURRENT:
230
+
231
+ key = non_empty_persidict_key(key)
232
+
233
+ if value is DELETE_CURRENT:
213
234
  self.delete_if_exists(key)
235
+ return
214
236
 
215
237
  if self.base_class_for_values is not None:
216
238
  if not isinstance(value, self.base_class_for_values):
@@ -237,7 +259,9 @@ class PersiDict(MutableMapping, ParameterizableClass):
237
259
  if type(self) is PersiDict:
238
260
  raise NotImplementedError("PersiDict is an abstract base class"
239
261
  " and cannot delete items directly")
240
- key = SafeStrTuple(key)
262
+
263
+ key = non_empty_persidict_key(key)
264
+
241
265
  if key not in self:
242
266
  raise KeyError(f"Key {key} not found")
243
267
 
@@ -457,7 +481,7 @@ class PersiDict(MutableMapping, ParameterizableClass):
457
481
  if self.immutable_items:
458
482
  raise KeyError("Can't delete an immutable key-value pair")
459
483
 
460
- key = SafeStrTuple(key)
484
+ key = non_empty_persidict_key(key)
461
485
 
462
486
  if key in self:
463
487
  try:
persidict/s3_dict.py CHANGED
@@ -16,7 +16,7 @@ from .safe_str_tuple import SafeStrTuple
16
16
  from .safe_str_tuple_signing import sign_safe_str_tuple, unsign_safe_str_tuple
17
17
  from .persi_dict import PersiDict
18
18
  from .jokers import KEEP_CURRENT, DELETE_CURRENT, Joker
19
- from .file_dir_dict import FileDirDict, PersiDictKey
19
+ from .file_dir_dict import FileDirDict, PersiDictKey, non_empty_persidict_key
20
20
  from .overlapping_multi_dict import OverlappingMultiDict
21
21
 
22
22
  S3DICT_DEFAULT_BASE_DIR = "__s3_dict__"
@@ -199,7 +199,7 @@ class S3Dict(PersiDict):
199
199
  str: The complete S3 object key including root_prefix and file_type
200
200
  extension, with digest-based collision prevention applied if enabled.
201
201
  """
202
- key = SafeStrTuple(key)
202
+ key = non_empty_persidict_key(key)
203
203
  key = sign_safe_str_tuple(key, self.digest_len)
204
204
  objectname = self.root_prefix + "/".join(key)+ "." + self.file_type
205
205
  return objectname
@@ -218,7 +218,7 @@ class S3Dict(PersiDict):
218
218
  bool: True if the key exists in S3 (or local cache for immutable
219
219
  items), False otherwise.
220
220
  """
221
- key = SafeStrTuple(key)
221
+ key = non_empty_persidict_key(key)
222
222
  if self.immutable_items and key in self.main_cache:
223
223
  return True
224
224
  try:
@@ -251,7 +251,7 @@ class S3Dict(PersiDict):
251
251
  KeyError: If the key does not exist in S3.
252
252
  """
253
253
 
254
- key = SafeStrTuple(key)
254
+ key = non_empty_persidict_key(key)
255
255
 
256
256
  if self.immutable_items and key in self.main_cache:
257
257
  return self.main_cache[key]
@@ -317,7 +317,7 @@ class S3Dict(PersiDict):
317
317
  the required base_class_for_values when specified.
318
318
  """
319
319
 
320
- key = SafeStrTuple(key)
320
+ key = non_empty_persidict_key(key)
321
321
  PersiDict.__setitem__(self, key, value)
322
322
  if isinstance(value, Joker):
323
323
  # Joker values (KEEP_CURRENT, DELETE_CURRENT) are handled by base class
@@ -351,7 +351,7 @@ class S3Dict(PersiDict):
351
351
  Raises:
352
352
  KeyError: If immutable_items is True, or if the key does not exist.
353
353
  """
354
- key = SafeStrTuple(key)
354
+ key = non_empty_persidict_key(key)
355
355
  PersiDict.__delitem__(self, key)
356
356
  obj_name = self._build_full_objectname(key)
357
357
  self.s3_client.delete_object(Bucket = self.bucket_name, Key = obj_name)
@@ -537,7 +537,7 @@ class S3Dict(PersiDict):
537
537
  Raises:
538
538
  KeyError: If the key does not exist in S3.
539
539
  """
540
- key = SafeStrTuple(key)
540
+ key = non_empty_persidict_key(key)
541
541
  obj_name = self._build_full_objectname(key)
542
542
  response = self.s3_client.head_object(Bucket=self.bucket_name, Key=obj_name)
543
543
  return response["LastModified"].timestamp()
@@ -98,8 +98,6 @@ class SafeStrTuple(Sequence, Hashable):
98
98
  candidate_strings.extend(SafeStrTuple(*a).strings)
99
99
  else:
100
100
  raise TypeError(f"Invalid argument type: {type(a)}")
101
- if len(candidate_strings) == 0:
102
- raise ValueError("At least one non-empty valid string is required")
103
101
  self.strings = tuple(candidate_strings)
104
102
 
105
103
  @property
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: persidict
3
- Version: 0.37.0
3
+ Version: 0.37.1
4
4
  Summary: Simple persistent key-value store for Python. Values are stored as files on a disk or as S3 objects on AWS cloud.
5
5
  Keywords: persistence,dicts,distributed,parallel
6
6
  Author: Vlad (Volodymyr) Pavlov
@@ -1,14 +1,14 @@
1
1
  persidict/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
2
2
  persidict/__init__.py,sha256=CDOSJGgCnyRTkGUTzaeg3Cqsxwx0-0EFieOtldXwAls,1380
3
- persidict/file_dir_dict.py,sha256=_ZGEQXmU5Sg4-PJOO4bYKhL0z6yYryVmce9lpML5OxQ,24766
3
+ persidict/file_dir_dict.py,sha256=2McFaDdr03g-PXlCIiG3fPb7h59LXW_3hDo0xLA17DE,24804
4
4
  persidict/jokers.py,sha256=gTu7g2l2MIgBc3-hjvUrcwcgWs6tcbLyxB0u57M3bfU,3012
5
5
  persidict/overlapping_multi_dict.py,sha256=UFyPEG2GbMmMHY48UmcaLHpsaxMqRH3bc_UA8S90yJo,5947
6
- persidict/persi_dict.py,sha256=q0Xvq5PO5Lmx3Nwe-fbU3Klgyx39T8PMKcXYR7xduzg,22506
7
- persidict/s3_dict.py,sha256=dYUTvGNqxIk3PpArn9uYbSv-4zzlRiPPYinYpTcJzSc,21363
6
+ persidict/persi_dict.py,sha256=CKVHy8YELLRVgLWgo0Akbd8RznCVxqt8JHszIjqA_sI,23176
7
+ persidict/s3_dict.py,sha256=F5N7DlpZBkEEUsDk7OQXiqACY-mJ2SOMNrh3AlHC9qo,21454
8
8
  persidict/safe_chars.py,sha256=H-cL9waCmDtwaRR5Y4b4oTzcBx09nc8wn8u61SVZDY0,1728
9
- persidict/safe_str_tuple.py,sha256=oibohVs0xah3mSVl5aN0pQWiQeaz4jjWtEdoBSn-jac,7322
9
+ persidict/safe_str_tuple.py,sha256=YBTcYjUKIffznOawXb9xKjz4HaKdklrgyVtegJFmr5w,7202
10
10
  persidict/safe_str_tuple_signing.py,sha256=mpOfx_xyprc0_c60XPB_EihI3vR1gOn6T03iCx1HwwQ,7494
11
11
  persidict/write_once_dict.py,sha256=nv5vx9uh6VZ5Qh3HJcBgUHLnDX9KY843FbHndcy-63E,11677
12
- persidict-0.37.0.dist-info/WHEEL,sha256=Pi5uDq5Fdo_Rr-HD5h9BiPn9Et29Y9Sh8NhcJNnFU1c,79
13
- persidict-0.37.0.dist-info/METADATA,sha256=vCPprij19SxfnU6qWI9MNz78n6iT9bTUpMZsUT901mY,12387
14
- persidict-0.37.0.dist-info/RECORD,,
12
+ persidict-0.37.1.dist-info/WHEEL,sha256=Pi5uDq5Fdo_Rr-HD5h9BiPn9Et29Y9Sh8NhcJNnFU1c,79
13
+ persidict-0.37.1.dist-info/METADATA,sha256=M2EVewTSqdjfqdMi-7VHkSUKHqlL-ohlXYrcVRj7ViA,12387
14
+ persidict-0.37.1.dist-info/RECORD,,