persidict 0.36.9__tar.gz → 0.36.11__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.
Potentially problematic release.
This version of persidict might be problematic. Click here for more details.
- {persidict-0.36.9 → persidict-0.36.11}/PKG-INFO +1 -1
- {persidict-0.36.9 → persidict-0.36.11}/pyproject.toml +1 -1
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/file_dir_dict.py +6 -1
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/s3_dict.py +25 -4
- {persidict-0.36.9 → persidict-0.36.11}/README.md +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/.DS_Store +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/__init__.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/jokers.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/overlapping_multi_dict.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/persi_dict.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/safe_chars.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/safe_str_tuple.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/safe_str_tuple_signing.py +0 -0
- {persidict-0.36.9 → persidict-0.36.11}/src/persidict/write_once_dict.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: persidict
|
|
3
|
-
Version: 0.36.
|
|
3
|
+
Version: 0.36.11
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "persidict"
|
|
7
|
-
version = "0.36.
|
|
7
|
+
version = "0.36.11"
|
|
8
8
|
description = "Simple persistent key-value store for Python. Values are stored as files on a disk or as S3 objects on AWS cloud."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -190,7 +190,12 @@ class FileDirDict(PersiDict):
|
|
|
190
190
|
os.remove(os.path.join(subdir_name, f))
|
|
191
191
|
if (subdir_name != self._base_dir) and (
|
|
192
192
|
len(os.listdir(subdir_name)) == 0 ):
|
|
193
|
-
|
|
193
|
+
try:
|
|
194
|
+
os.rmdir(subdir_name)
|
|
195
|
+
except OSError:
|
|
196
|
+
# Directory is not empty, likely due to a race condition.
|
|
197
|
+
# Continue without raising an error.
|
|
198
|
+
pass
|
|
194
199
|
|
|
195
200
|
|
|
196
201
|
def _build_full_path(self
|
|
@@ -103,9 +103,28 @@ class S3Dict(PersiDict):
|
|
|
103
103
|
self.s3_client = boto3.client('s3', region_name=region)
|
|
104
104
|
|
|
105
105
|
try:
|
|
106
|
-
self.s3_client.
|
|
107
|
-
except:
|
|
108
|
-
|
|
106
|
+
self.s3_client.head_bucket(Bucket=bucket_name)
|
|
107
|
+
except ClientError as e:
|
|
108
|
+
error_code = e.response['Error']['Code']
|
|
109
|
+
if error_code == '404' or error_code == 'NotFound':
|
|
110
|
+
# The bucket does not exist, so attempt to create it.
|
|
111
|
+
try:
|
|
112
|
+
self.s3_client.create_bucket(Bucket=bucket_name)
|
|
113
|
+
except ClientError as create_e:
|
|
114
|
+
create_error_code = create_e.response['Error']['Code']
|
|
115
|
+
# Handles the race condition and the bucket-is-taken error
|
|
116
|
+
if ( create_error_code == 'BucketAlreadyOwnedByYou'
|
|
117
|
+
or create_error_code == 'BucketAlreadyExists'):
|
|
118
|
+
pass
|
|
119
|
+
else:
|
|
120
|
+
raise create_e # Re-raise other unexpected creation errors.
|
|
121
|
+
elif error_code == '403' or error_code == 'Forbidden':
|
|
122
|
+
# The bucket exists, but access is forbidden.
|
|
123
|
+
# This is likely a cross-account bucket with a policy that grants
|
|
124
|
+
# access to you. Subsequent calls will fail if permissions are not granted.
|
|
125
|
+
pass
|
|
126
|
+
else:
|
|
127
|
+
raise e # Re-raise other unexpected ClientErrors on head_bucket.
|
|
109
128
|
|
|
110
129
|
self.bucket_name = bucket_name
|
|
111
130
|
|
|
@@ -246,7 +265,6 @@ class S3Dict(PersiDict):
|
|
|
246
265
|
self.etag_cache[key] = s3_etag
|
|
247
266
|
|
|
248
267
|
except ClientError as e:
|
|
249
|
-
error_code = e.response.get("Error", {}).get("Code")
|
|
250
268
|
if e.response['ResponseMetadata']['HTTPStatusCode'] == 304:
|
|
251
269
|
# 304 Not Modified: our cached version is up-to-date.
|
|
252
270
|
# The value will be read from cache at the end of the function.
|
|
@@ -336,6 +354,9 @@ class S3Dict(PersiDict):
|
|
|
336
354
|
if self.immutable_items:
|
|
337
355
|
raise KeyError("Can't delete an immutable item")
|
|
338
356
|
|
|
357
|
+
if key not in self:
|
|
358
|
+
raise KeyError(f"Key {key} not found in S3 bucket {self.bucket_name}")
|
|
359
|
+
|
|
339
360
|
obj_name = self._build_full_objectname(key)
|
|
340
361
|
|
|
341
362
|
self.s3_client.delete_object(Bucket = self.bucket_name, Key = obj_name)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|