osbot-utils 2.83.0__py3-none-any.whl → 2.85.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.
- osbot_utils/testing/__.py +76 -0
- osbot_utils/type_safe/primitives/safe_str/Safe_Str.py +9 -9
- osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__Hash.py +4 -4
- osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__SHA1.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__SHA1__Short.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Safe_Str__NaCl__Private_Key.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Safe_Str__NaCl__Public_Key.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/filesystem/Safe_Str__File__Name.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Ref.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Ref_Base.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Version.py +1 -1
- osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo.py +8 -4
- osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo_Name.py +3 -3
- osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo_Owner.py +4 -4
- osbot_utils/type_safe/primitives/safe_str/http/Safe_Str__Http__Content_Type.py +1 -1
- osbot_utils/utils/Objects.py +2 -6
- osbot_utils/version +1 -1
- {osbot_utils-2.83.0.dist-info → osbot_utils-2.85.0.dist-info}/METADATA +2 -2
- {osbot_utils-2.83.0.dist-info → osbot_utils-2.85.0.dist-info}/RECORD +21 -20
- {osbot_utils-2.83.0.dist-info → osbot_utils-2.85.0.dist-info}/LICENSE +0 -0
- {osbot_utils-2.83.0.dist-info → osbot_utils-2.85.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
from types import SimpleNamespace
|
2
|
+
|
3
|
+
__SKIP__ = object()
|
4
|
+
__MISSING__ = object()
|
5
|
+
|
6
|
+
class __(SimpleNamespace):
|
7
|
+
def __enter__(self) : return self
|
8
|
+
def __exit__(self, exc_type, exc_val, exc_tb): return False
|
9
|
+
|
10
|
+
def __contains__(self, item): # Allow 'subset in superset' syntax
|
11
|
+
return self.contains(item)
|
12
|
+
|
13
|
+
def __eq__(self, other): # Enhanced equality that handles SKIP markers for dynamic values
|
14
|
+
if not isinstance(other, __):
|
15
|
+
return super().__eq__(other)
|
16
|
+
|
17
|
+
for key in set(self.__dict__.keys()) | set(other.__dict__.keys()):
|
18
|
+
self_val = getattr(self, key, None)
|
19
|
+
other_val = getattr(other, key, None)
|
20
|
+
|
21
|
+
if self_val is __SKIP__ or other_val is __SKIP__: # Skip comparison if either value is a skip marker
|
22
|
+
continue
|
23
|
+
|
24
|
+
if isinstance(self_val, __) and isinstance(other_val, __): # Handle nested __ objects recursively
|
25
|
+
if self_val.__eq__(other_val) is False: # Explicit recursive comparison
|
26
|
+
return False
|
27
|
+
elif self_val != other_val:
|
28
|
+
return False
|
29
|
+
return True
|
30
|
+
|
31
|
+
def contains(self, other):
|
32
|
+
other_dict = getattr(other, '__dict__', other) if hasattr(other, '__dict__') else other if isinstance(other, dict) else None
|
33
|
+
if other_dict is None:
|
34
|
+
return False
|
35
|
+
|
36
|
+
for key, expected_value in other_dict.items():
|
37
|
+
if expected_value is __SKIP__: # Skip this field
|
38
|
+
continue
|
39
|
+
if not hasattr(self, key):
|
40
|
+
return False
|
41
|
+
actual_value = getattr(self, key)
|
42
|
+
|
43
|
+
if isinstance(expected_value, __) and isinstance(actual_value, __):
|
44
|
+
if not actual_value.contains(expected_value):
|
45
|
+
return False
|
46
|
+
elif actual_value != expected_value:
|
47
|
+
return False
|
48
|
+
return True
|
49
|
+
|
50
|
+
def diff(self, other): # Return differences between objects for better test failure messages
|
51
|
+
differences = {}
|
52
|
+
all_keys = set(self.__dict__.keys()) | set(other.__dict__.keys() if hasattr(other, '__dict__') else other.keys() if isinstance(other, dict) else [])
|
53
|
+
|
54
|
+
for key in all_keys:
|
55
|
+
self_val = getattr(self, key, __MISSING__)
|
56
|
+
other_val = getattr(other, key, __MISSING__) if hasattr(other, '__dict__') else other.get(key, __MISSING__) if isinstance(other, dict) else __MISSING__
|
57
|
+
|
58
|
+
if self_val != other_val:
|
59
|
+
differences[key] = {'actual': self_val, 'expected': other_val}
|
60
|
+
|
61
|
+
return differences if differences else None
|
62
|
+
|
63
|
+
def excluding(self, *fields): # Return copy without specified fields for comparison"
|
64
|
+
result = __(**self.__dict__)
|
65
|
+
for field in fields:
|
66
|
+
delattr(result, field) if hasattr(result, field) else None
|
67
|
+
return result
|
68
|
+
|
69
|
+
def merge(self, **updates): # Create new instance with updates, handling nested __ objects
|
70
|
+
result = __(**self.__dict__)
|
71
|
+
for key, value in updates.items():
|
72
|
+
if isinstance(value, __) and hasattr(result, key) and isinstance(getattr(result, key), __):
|
73
|
+
setattr(result, key, getattr(result, key).merge(**value.__dict__))
|
74
|
+
else:
|
75
|
+
setattr(result, key, value)
|
76
|
+
return result
|
@@ -12,7 +12,7 @@ class Safe_Str(Type_Safe__Primitive, str):
|
|
12
12
|
regex : re.Pattern = TYPE_SAFE__STR__REGEX__SAFE_STR
|
13
13
|
regex_mode : Enum__Safe_Str__Regex_Mode = Enum__Safe_Str__Regex_Mode.REPLACE
|
14
14
|
replacement_char : str = '_'
|
15
|
-
allow_empty : bool = True
|
15
|
+
allow_empty : bool = True # note: making this False does cause some side effects on .json() on cases like auto serialization in environments like FastAPI (like it requires more explict value setting), so all have now been converted into a value of True
|
16
16
|
trim_whitespace : bool = False
|
17
17
|
allow_all_replacement_char: bool = True
|
18
18
|
strict_validation : bool = False # If True, don't replace invalid chars, raise an error instead
|
@@ -34,12 +34,12 @@ class Safe_Str(Type_Safe__Primitive, str):
|
|
34
34
|
value = value.strip()
|
35
35
|
|
36
36
|
if not cls.allow_empty and (value is None or value == ""): # Check for empty string if not allowed
|
37
|
-
raise ValueError("
|
37
|
+
raise ValueError(f"in {cls.__name__}, value cannot be empty when allow_empty is False")
|
38
38
|
|
39
|
-
if cls.exact_length and len(value) != cls.max_length:
|
40
|
-
raise ValueError(f"
|
39
|
+
if cls.exact_length and len(value) and len(value) != cls.max_length:
|
40
|
+
raise ValueError(f"in {cls.__name__}, value must be exactly {cls.max_length} characters long (was {len(value)})")
|
41
41
|
elif not cls.exact_length and len(value) > cls.max_length: # Check max length
|
42
|
-
raise ValueError(f"
|
42
|
+
raise ValueError(f"in {cls.__name__}, value exceeds maximum length of {cls.max_length} characters (was {len(value)})")
|
43
43
|
|
44
44
|
if cls.allow_empty and value =='':
|
45
45
|
return str.__new__(cls, '')
|
@@ -54,22 +54,22 @@ class Safe_Str(Type_Safe__Primitive, str):
|
|
54
54
|
if cls.strict_validation:
|
55
55
|
if cls.regex_mode == Enum__Safe_Str__Regex_Mode.MATCH: # For 'match' mode, regex defines the valid pattern (like version numbers)
|
56
56
|
if not cls.regex.match(value):
|
57
|
-
raise ValueError(f"
|
57
|
+
raise ValueError(f"in {cls.__name__}, value does not match required pattern: {cls.regex.pattern}")
|
58
58
|
return value
|
59
59
|
elif cls.regex_mode == Enum__Safe_Str__Regex_Mode.REPLACE: # For 'replace' mode, regex defines invalid characters to replace
|
60
60
|
if cls.regex.search(value) is not None:
|
61
|
-
raise ValueError(f"
|
61
|
+
raise ValueError(f"in {cls.__name__}, value contains invalid characters (must not match pattern: {cls.regex.pattern})")
|
62
62
|
return value
|
63
63
|
else:
|
64
64
|
raise ValueError(f"in {cls.__name__}, regex_mode value cannot be None when strict_validation is True")
|
65
65
|
else:
|
66
66
|
if cls.regex_mode == Enum__Safe_Str__Regex_Mode.MATCH: # Cannot do replacement when regex defines valid pattern
|
67
|
-
raise ValueError(f"
|
67
|
+
raise ValueError(f"in {cls.__name__}, cannot use regex_mode='match' without strict_validation=True")
|
68
68
|
else: # assume the default Enum__Safe_Str__Regex_Mode.MATCH
|
69
69
|
sanitized_value = cls.regex.sub(cls.replacement_char, value)
|
70
70
|
|
71
71
|
if not cls.allow_all_replacement_char and set(sanitized_value) == {
|
72
72
|
cls.replacement_char} and sanitized_value:
|
73
|
-
raise ValueError(f"
|
73
|
+
raise ValueError(f"in {cls.__name__}, sanitized value consists entirely of '{cls.replacement_char}' characters")
|
74
74
|
|
75
75
|
return sanitized_value
|
@@ -10,10 +10,10 @@ TYPE_SAFE_STR__HASH__REGEX = re.compile(r'[^a-fA-F0-9]') # Only a
|
|
10
10
|
class Safe_Str__Hash(Safe_Str):
|
11
11
|
regex = TYPE_SAFE_STR__HASH__REGEX
|
12
12
|
max_length = SIZE__VALUE_HASH
|
13
|
-
allow_empty =
|
14
|
-
trim_whitespace = True
|
15
|
-
strict_validation = True
|
16
|
-
exact_length = True
|
13
|
+
allow_empty = True # Don't allow empty hash values
|
14
|
+
trim_whitespace = True # Trim any whitespace
|
15
|
+
strict_validation = True # Enable strict validation - new attribute
|
16
|
+
exact_length = True # Require exact length match - new attribute
|
17
17
|
|
18
18
|
def safe_str_hash(value: Any) -> Safe_Str__Hash:
|
19
19
|
if isinstance(value, str):
|
@@ -19,6 +19,6 @@ class Safe_Str__SHA1__Short(Safe_Str):
|
|
19
19
|
regex_mode = Enum__Safe_Str__Regex_Mode.MATCH
|
20
20
|
max_length = TYPE_SAFE_STR__GITHUB__SHA_SHORT__LENGTH
|
21
21
|
exact_length = True
|
22
|
-
allow_empty =
|
22
|
+
allow_empty = True
|
23
23
|
trim_whitespace = True
|
24
24
|
strict_validation = True
|
@@ -22,6 +22,6 @@ class Safe_Str__NaCl__Private_Key(Safe_Str):
|
|
22
22
|
regex_mode = Enum__Safe_Str__Regex_Mode.MATCH
|
23
23
|
max_length = TYPE_SAFE_STR__NACL__PRIVATE_KEY__LENGTH
|
24
24
|
exact_length = True
|
25
|
-
allow_empty =
|
25
|
+
allow_empty = True
|
26
26
|
trim_whitespace = True
|
27
27
|
strict_validation = True
|
@@ -23,6 +23,6 @@ class Safe_Str__NaCl__Public_Key(Safe_Str):
|
|
23
23
|
regex_mode = Enum__Safe_Str__Regex_Mode.MATCH
|
24
24
|
max_length = TYPE_SAFE_STR__NACL__PUBLIC_KEY__LENGTH
|
25
25
|
exact_length = True
|
26
|
-
allow_empty =
|
26
|
+
allow_empty = True
|
27
27
|
trim_whitespace = True
|
28
28
|
strict_validation = True
|
@@ -9,7 +9,7 @@ class Safe_Str__Version(Safe_Str):
|
|
9
9
|
regex = TYPE_SAFE_STR__VERSION__REGEX
|
10
10
|
regex_mode = Enum__Safe_Str__Regex_Mode.MATCH # in this case we need an exact match of the version regex
|
11
11
|
max_length = TYPE_SAFE_STR__VERSION__MAX_LENGTH
|
12
|
-
allow_empty =
|
12
|
+
allow_empty = True
|
13
13
|
trim_whitespace = True
|
14
14
|
strict_validation = True # Ensure the value exactly matches the regex
|
15
15
|
|
@@ -20,7 +20,7 @@ class Safe_Str__GitHub__Repo(Safe_Str):
|
|
20
20
|
"""
|
21
21
|
regex = TYPE_SAFE_STR__GITHUB__REPO__REGEX
|
22
22
|
max_length = TYPE_SAFE_STR__GITHUB__REPO__MAX_LENGTH
|
23
|
-
allow_empty =
|
23
|
+
allow_empty = True
|
24
24
|
trim_whitespace = True
|
25
25
|
allow_all_replacement_char = False
|
26
26
|
repo_owner : Safe_Str__GitHub__Repo_Owner = None # note: due to the str override these will not show in the Pycharm code hints (but they will work)
|
@@ -31,16 +31,20 @@ class Safe_Str__GitHub__Repo(Safe_Str):
|
|
31
31
|
|
32
32
|
if result:
|
33
33
|
if '/' not in result: # Check for the required forward slash
|
34
|
-
raise ValueError(f"
|
34
|
+
raise ValueError(f"in {cls.__name__}, gitHub repository must be in 'owner/repo' format: {result}")
|
35
35
|
|
36
36
|
|
37
37
|
parts = result.split('/') # Split and validate components using the dedicated classes
|
38
38
|
if len(parts) != 2:
|
39
|
-
raise ValueError(f"
|
39
|
+
raise ValueError(f"in {cls.__name__}, gitHub repository must be in 'owner/repo' format: {result}")
|
40
40
|
|
41
41
|
owner_part, repo_part = parts
|
42
42
|
|
43
43
|
result.repo_owner = Safe_Str__GitHub__Repo_Owner(owner_part) # Validate using the dedicated classes (and store the references)
|
44
|
-
result.repo_name = Safe_Str__GitHub__Repo_Name(repo_part )
|
44
|
+
result.repo_name = Safe_Str__GitHub__Repo_Name(repo_part )
|
45
|
+
if not result.repo_owner:
|
46
|
+
raise ValueError(f"in {cls.__name__}, missing owner, gitHub repository must be in 'owner/repo' format: {result}")
|
47
|
+
if not result.repo_name:
|
48
|
+
raise ValueError(f"in {cls.__name__}, missing name, gitHub repository must be in 'owner/repo' format: {result}")
|
45
49
|
|
46
50
|
return result
|
@@ -15,7 +15,7 @@ class Safe_Str__GitHub__Repo_Name(Safe_Str):
|
|
15
15
|
"""
|
16
16
|
regex = TYPE_SAFE_STR__GITHUB__REPO_NAME__REGEX
|
17
17
|
max_length = TYPE_SAFE_STR__GITHUB__REPO_NAME__MAX_LENGTH
|
18
|
-
allow_empty =
|
18
|
+
allow_empty = True
|
19
19
|
trim_whitespace = True
|
20
20
|
allow_all_replacement_char = False
|
21
21
|
|
@@ -26,10 +26,10 @@ class Safe_Str__GitHub__Repo_Name(Safe_Str):
|
|
26
26
|
if result:
|
27
27
|
# Check if it's just periods (reserved names)
|
28
28
|
if result in ['.', '..']:
|
29
|
-
raise ValueError(f"
|
29
|
+
raise ValueError(f"in {cls.__name__}, invalid repository name: {result}")
|
30
30
|
|
31
31
|
# Check for all replacement characters
|
32
32
|
if set(result) == {'_'} and len(result) > 0:
|
33
|
-
raise ValueError(f"
|
33
|
+
raise ValueError(f"in {cls.__name__}, invalid repository name: {result}")
|
34
34
|
|
35
35
|
return result
|
@@ -16,7 +16,7 @@ class Safe_Str__GitHub__Repo_Owner(Safe_Str):
|
|
16
16
|
"""
|
17
17
|
regex = TYPE_SAFE_STR__GITHUB__REPO_OWNER__REGEX
|
18
18
|
max_length = TYPE_SAFE_STR__GITHUB__REPO_OWNER__MAX_LENGTH
|
19
|
-
allow_empty =
|
19
|
+
allow_empty = True
|
20
20
|
trim_whitespace = True
|
21
21
|
allow_all_replacement_char = False
|
22
22
|
|
@@ -26,13 +26,13 @@ class Safe_Str__GitHub__Repo_Owner(Safe_Str):
|
|
26
26
|
|
27
27
|
if result: # Additional GitHub-specific validation
|
28
28
|
if result.startswith('-') or result.endswith('-'): # Check for leading/trailing hyphens
|
29
|
-
raise ValueError(f"
|
29
|
+
raise ValueError(f"in {cls.__name__}, gitHub owner name cannot start or end with a hyphen: {result}")
|
30
30
|
|
31
31
|
if '--' in result: # Check for consecutive hyphens
|
32
|
-
raise ValueError(f"
|
32
|
+
raise ValueError(f"in {cls.__name__}, gitHub owner name cannot contain consecutive hyphens: {result}")
|
33
33
|
|
34
34
|
if result.replace('_', '') == '': # Check for all underscores (sanitized invalid input)
|
35
|
-
raise ValueError(f"
|
35
|
+
raise ValueError(f"in {cls.__name__}, invalid GitHub owner name: {result}")
|
36
36
|
|
37
37
|
return result
|
38
38
|
|
@@ -7,6 +7,6 @@ TYPE_SAFE_STR__HTTP__CONTENT_TYPE__MAX_LENGTH = 256
|
|
7
7
|
class Safe_Str__Http__Content_Type(Safe_Str):
|
8
8
|
regex = TYPE_SAFE_STR__HTTP__CONTENT_TYPE__REGEX
|
9
9
|
max_length = TYPE_SAFE_STR__HTTP__CONTENT_TYPE__MAX_LENGTH
|
10
|
-
allow_empty =
|
10
|
+
allow_empty = True
|
11
11
|
trim_whitespace = True
|
12
12
|
allow_all_replacement_char = False
|
osbot_utils/utils/Objects.py
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
|
2
|
-
from types import SimpleNamespace
|
1
|
+
from types import SimpleNamespace
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
def __enter__(self) : return self
|
7
|
-
def __exit__(self, exc_type, exc_val, exc_tb): return False
|
3
|
+
from osbot_utils.testing.__ import __
|
8
4
|
|
9
5
|
def base_classes(cls):
|
10
6
|
if type(cls) is type:
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v2.
|
1
|
+
v2.85.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.85.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
5
|
License: MIT
|
6
6
|
Author: Dinis Cruz
|
@@ -21,7 +21,7 @@ Description-Content-Type: text/markdown
|
|
21
21
|
|
22
22
|
# OSBot-Utils
|
23
23
|
|
24
|
-

|
25
25
|

|
26
26
|

|
27
27
|

|
@@ -340,6 +340,7 @@ osbot_utils/testing/Temp_Zip.py,sha256=gppbJchk4tw_bu-7Vt6iJS9mGxeCvNNMMDzeVKHqR
|
|
340
340
|
osbot_utils/testing/Temp_Zip_In_Memory.py,sha256=ibDIWt3K4CX558PbkLbX3InHyWYZcwQwajFm1kAPW5U,3284
|
341
341
|
osbot_utils/testing/Unit_Test.py,sha256=MReR_wDGbbXFDPz7cmuGflcTxRB6TBnO9mYqRpSq8Pk,1304
|
342
342
|
osbot_utils/testing/Unzip_File.py,sha256=V5H97XO9rlvG5EYOSzAH4kTtAH1ohZ8R8ImvJh46ZNg,1177
|
343
|
+
osbot_utils/testing/__.py,sha256=7eKP4vgV7pPbk5bSSufdvAEXy2eYh5bq36Ez8eC2SoQ,3579
|
343
344
|
osbot_utils/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
344
345
|
osbot_utils/testing/performance/Performance_Measure__Session.py,sha256=CWce0vJAZH_PDbIgK5bNcNFr1qsB37FQJKd05K-63kk,9108
|
345
346
|
osbot_utils/testing/performance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -362,31 +363,31 @@ osbot_utils/type_safe/primitives/safe_int/Safe_Int.py,sha256=IB_ZVtuQlAfRWZH1teZ
|
|
362
363
|
osbot_utils/type_safe/primitives/safe_int/Timestamp_Now.py,sha256=OZwSwmYA1pZAnVglpx2lBL5t8Pu_HxzmYdNEJnmTqKI,536
|
363
364
|
osbot_utils/type_safe/primitives/safe_int/__init__.py,sha256=Prle-pyYi8l4hjbzGACVxX89Uc5aAhYjGRojywWysQM,323
|
364
365
|
osbot_utils/type_safe/primitives/safe_str/Enum__Safe_Str__Regex_Mode.py,sha256=15y_afYIf_LsweutaVVdIJ0qClbVITJGWNEqfRKapNI,120
|
365
|
-
osbot_utils/type_safe/primitives/safe_str/Safe_Str.py,sha256=
|
366
|
+
osbot_utils/type_safe/primitives/safe_str/Safe_Str.py,sha256=u6AWM9CCVBxo2s_QmjgC-91m3N9mA3FJzmXcwneTwPg,5022
|
366
367
|
osbot_utils/type_safe/primitives/safe_str/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
367
368
|
osbot_utils/type_safe/primitives/safe_str/cryptography/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
368
|
-
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__Hash.py,sha256=
|
369
|
-
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__SHA1.py,sha256=
|
370
|
-
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__SHA1__Short.py,sha256=
|
369
|
+
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__Hash.py,sha256=zmARKnR6k0d7zg2DESPSZU8Qj91nx-qrnNrXln6UcYk,1287
|
370
|
+
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__SHA1.py,sha256=4GspFCkrBM9I-9Myb7I4dYUQ726LahwepWfuasFhD_M,899
|
371
|
+
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/Safe_Str__SHA1__Short.py,sha256=UISofo58uSm3iAMA-css_inp1EKBqJrGMoS5m8ik7b4,824
|
371
372
|
osbot_utils/type_safe/primitives/safe_str/cryptography/hashes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
372
|
-
osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Safe_Str__NaCl__Private_Key.py,sha256=
|
373
|
-
osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Safe_Str__NaCl__Public_Key.py,sha256=
|
373
|
+
osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Safe_Str__NaCl__Private_Key.py,sha256=4h3kPDP0hwQkn-USHZYPJZB2QeHPOkK-CD7fOc_Pddg,1204
|
374
|
+
osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Safe_Str__NaCl__Public_Key.py,sha256=OGmdTsuvwLl61omKNcgX3fe8rRXmlPL6g5Xy0HSBjPY,1306
|
374
375
|
osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/Schema__NaCl__Keys.py,sha256=jYFBpUHZ94ouW0yHsEO3mUKnmSif9jB71kNNH1oA-2I,507
|
375
376
|
osbot_utils/type_safe/primitives/safe_str/cryptography/nacl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
376
|
-
osbot_utils/type_safe/primitives/safe_str/filesystem/Safe_Str__File__Name.py,sha256=
|
377
|
+
osbot_utils/type_safe/primitives/safe_str/filesystem/Safe_Str__File__Name.py,sha256=xQWoqqs-ZXU6o2iROOvd62P15B5EulDMiAlYCQg2tOY,370
|
377
378
|
osbot_utils/type_safe/primitives/safe_str/filesystem/Safe_Str__File__Path.py,sha256=bOihPzsLce2mv-g6BpsfhfLaQ3UEoYXaK8FbdpMGuYs,563
|
378
379
|
osbot_utils/type_safe/primitives/safe_str/filesystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
379
380
|
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Branch.py,sha256=npoKUzforQCLqblCWfx2H_hZtq0CCybg5O_3RpZkOXE,870
|
380
|
-
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Ref.py,sha256=
|
381
|
-
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Ref_Base.py,sha256=
|
381
|
+
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Ref.py,sha256=MmBHnwLyS-typs9ObzqHU05aoDx6jUBK7BpijcFibws,3132
|
382
|
+
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Ref_Base.py,sha256=MZYYk4_Tn7BlyvXFVPIOCCAdYlzPszxxTvltUB_37AQ,3274
|
382
383
|
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Git__Tag.py,sha256=imUY7CkrJ_aBJ0tIuV5OSD6eqF7aSzPERfEhdaWejbY,440
|
383
|
-
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Version.py,sha256=
|
384
|
+
osbot_utils/type_safe/primitives/safe_str/git/Safe_Str__Version.py,sha256=fuhNy7Q0cc_LD53Cyu8Q8emMXDT42if3YQqn2PpNJBY,1396
|
384
385
|
osbot_utils/type_safe/primitives/safe_str/git/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
385
|
-
osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo.py,sha256=
|
386
|
-
osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo_Name.py,sha256=
|
387
|
-
osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo_Owner.py,sha256=
|
386
|
+
osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo.py,sha256=Ww_wfV_VJSC9go3ZUxt9wXaOFAc-uYlq3oUbjn6QfAo,2754
|
387
|
+
osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo_Name.py,sha256=kOzDDVBsgiL6itQzxqGmFLs_a9GY9nENsF37TdV4m4s,1305
|
388
|
+
osbot_utils/type_safe/primitives/safe_str/github/Safe_Str__GitHub__Repo_Owner.py,sha256=x69rNmVrjg_RCjUcZAOL0_Hv84-zGyy27kwp1pRx4Zc,1840
|
388
389
|
osbot_utils/type_safe/primitives/safe_str/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
389
|
-
osbot_utils/type_safe/primitives/safe_str/http/Safe_Str__Http__Content_Type.py,sha256=
|
390
|
+
osbot_utils/type_safe/primitives/safe_str/http/Safe_Str__Http__Content_Type.py,sha256=pdgTuzmd8vqr0h1J99GRl8LUDQOpB68iEtuG1_9s_gE,528
|
390
391
|
osbot_utils/type_safe/primitives/safe_str/http/Safe_Str__Http__ETag.py,sha256=9dOX5mGCBaKmrgIp6uXFCpVyyhel42mUQgbLyN5cKMk,490
|
391
392
|
osbot_utils/type_safe/primitives/safe_str/http/Safe_Str__Http__Last_Modified.py,sha256=LfA6ayIXaSjwVGrZUO4HIV1gbFXKc54omDJAZ_ZPtjI,451
|
392
393
|
osbot_utils/type_safe/primitives/safe_str/http/Safe_Str__Http__Text.py,sha256=miVh53YT6VJla5XiZjzsgVSoMWiYXy-tml3a8HG8yM8,1801
|
@@ -457,7 +458,7 @@ osbot_utils/utils/Json.py,sha256=TvfDoXwOkWzWH-9KMnme5C7iFsMZOleAeue92qmkH6g,883
|
|
457
458
|
osbot_utils/utils/Json_Cache.py,sha256=mLPkkDZN-3ZVJiDvV1KBJXILtKkTZ4OepzOsDoBPhWg,2006
|
458
459
|
osbot_utils/utils/Lists.py,sha256=tPz5x5s3sRO97WZ_nsxREBPC5cwaHrhgaYBhsrffTT8,5599
|
459
460
|
osbot_utils/utils/Misc.py,sha256=H_xexJgiTxB3jDeDiW8efGQbO0Zuy8MM0iQ7qXC92JI,17363
|
460
|
-
osbot_utils/utils/Objects.py,sha256=
|
461
|
+
osbot_utils/utils/Objects.py,sha256=ZgAwAI8DM8MhFe37WAr2Di5f9-ig3hgayMEinLCF5tc,13571
|
461
462
|
osbot_utils/utils/Png.py,sha256=V1juGp6wkpPigMJ8HcxrPDIP4bSwu51oNkLI8YqP76Y,1172
|
462
463
|
osbot_utils/utils/Process.py,sha256=lr3CTiEkN3EiBx3ZmzYmTKlQoPdkgZBRjPulMxG-zdo,2357
|
463
464
|
osbot_utils/utils/Python_Logger.py,sha256=M9Oi62LxfnRSlCN8GhaiwiBINvcSdGy39FCWjyDD-Xg,12792
|
@@ -469,8 +470,8 @@ osbot_utils/utils/Toml.py,sha256=grjWkVPIMVkawJ499FVIJKxQp8FJ2wcsd0Z3YIR4drM,114
|
|
469
470
|
osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
|
470
471
|
osbot_utils/utils/Zip.py,sha256=mG42lgTY0tnm14T3P1-DSAIZKkTiYoO3odZ1aOUdc1I,14394
|
471
472
|
osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
472
|
-
osbot_utils/version,sha256=
|
473
|
-
osbot_utils-2.
|
474
|
-
osbot_utils-2.
|
475
|
-
osbot_utils-2.
|
476
|
-
osbot_utils-2.
|
473
|
+
osbot_utils/version,sha256=Fzq3NVCIMMQXS5Ax5-ZrDEOOQhtNlHqqT--cg6GdXic,8
|
474
|
+
osbot_utils-2.85.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
475
|
+
osbot_utils-2.85.0.dist-info/METADATA,sha256=bQaAW7ALWwWNyVCPZRbHVdPZJjch-N7pvoxbl5nEqTI,7918
|
476
|
+
osbot_utils-2.85.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
477
|
+
osbot_utils-2.85.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|