base-typed-string 0.1.0__tar.gz → 0.1.2__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.
- {base_typed_string-0.1.0/src/base_typed_string.egg-info → base_typed_string-0.1.2}/PKG-INFO +35 -2
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/README.md +33 -1
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/pyproject.toml +2 -1
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string/__init__.py +1 -1
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string/_base_typed_string.py +11 -4
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string/_exceptions.py +1 -1
- {base_typed_string-0.1.0 → base_typed_string-0.1.2/src/base_typed_string.egg-info}/PKG-INFO +35 -2
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string.egg-info/requires.txt +1 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/test_runtime_behavior.py +8 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/LICENSE +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/setup.cfg +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string/py.typed +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string.egg-info/SOURCES.txt +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string.egg-info/dependency_links.txt +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string.egg-info/top_level.txt +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/test_constructor.py +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/test_internal_invariants.py +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/test_pickle_support.py +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/test_pydantic_support.py +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/testing_assertions.py +0 -0
- {base_typed_string-0.1.0 → base_typed_string-0.1.2}/tests/testing_types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: base-typed-string
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Strict typed string base class with exact runtime subtype preservation and optional Pydantic v2 support.
|
|
5
5
|
Author-email: Eldeniz Guseinli <eldenizfamilyanskicode@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pydantic<3,>=2.6; extra == "pydantic"
|
|
|
26
26
|
Provides-Extra: test
|
|
27
27
|
Requires-Dist: pytest>=8.0; extra == "test"
|
|
28
28
|
Requires-Dist: pytest-cov>=5.0; extra == "test"
|
|
29
|
+
Requires-Dist: pydantic<3,>=2.6; extra == "test"
|
|
29
30
|
Provides-Extra: lint
|
|
30
31
|
Requires-Dist: ruff>=0.5; extra == "lint"
|
|
31
32
|
Provides-Extra: typecheck
|
|
@@ -101,7 +102,6 @@ domain-specific names in type annotations, while keeping real `str` behavior at
|
|
|
101
102
|
- no normalization
|
|
102
103
|
- no regex engine
|
|
103
104
|
- no domain-specific methods
|
|
104
|
-
- no custom JSON layer
|
|
105
105
|
|
|
106
106
|
This package is intentionally minimal.
|
|
107
107
|
|
|
@@ -446,6 +446,39 @@ assert type(restored_email) is EmailAddress
|
|
|
446
446
|
|
|
447
447
|
---
|
|
448
448
|
|
|
449
|
+
## JSON behavior
|
|
450
|
+
|
|
451
|
+
Since `BaseTypedString` inherits from `str`, standard JSON serialization naturally produces plain JSON strings.
|
|
452
|
+
|
|
453
|
+
```python
|
|
454
|
+
import json
|
|
455
|
+
|
|
456
|
+
from base_typed_string import BaseTypedString
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
class EmailAddress(BaseTypedString):
|
|
460
|
+
pass
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
value: EmailAddress = EmailAddress("hello@example.com")
|
|
464
|
+
serialized_value: str = json.dumps(value)
|
|
465
|
+
restored_value: object = json.loads(serialized_value)
|
|
466
|
+
|
|
467
|
+
assert serialized_value == '"hello@example.com"'
|
|
468
|
+
assert restored_value == "hello@example.com"
|
|
469
|
+
assert type(restored_value) is str
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
This behavior is intentional.
|
|
473
|
+
|
|
474
|
+
JSON is a plain data boundary.
|
|
475
|
+
|
|
476
|
+
The exact runtime subtype exists only inside Python objects.
|
|
477
|
+
After serialization, values become plain strings and do not carry subtype information.
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
|
|
449
482
|
## Public API
|
|
450
483
|
|
|
451
484
|
```python
|
|
@@ -54,7 +54,6 @@ domain-specific names in type annotations, while keeping real `str` behavior at
|
|
|
54
54
|
- no normalization
|
|
55
55
|
- no regex engine
|
|
56
56
|
- no domain-specific methods
|
|
57
|
-
- no custom JSON layer
|
|
58
57
|
|
|
59
58
|
This package is intentionally minimal.
|
|
60
59
|
|
|
@@ -399,6 +398,39 @@ assert type(restored_email) is EmailAddress
|
|
|
399
398
|
|
|
400
399
|
---
|
|
401
400
|
|
|
401
|
+
## JSON behavior
|
|
402
|
+
|
|
403
|
+
Since `BaseTypedString` inherits from `str`, standard JSON serialization naturally produces plain JSON strings.
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
import json
|
|
407
|
+
|
|
408
|
+
from base_typed_string import BaseTypedString
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
class EmailAddress(BaseTypedString):
|
|
412
|
+
pass
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
value: EmailAddress = EmailAddress("hello@example.com")
|
|
416
|
+
serialized_value: str = json.dumps(value)
|
|
417
|
+
restored_value: object = json.loads(serialized_value)
|
|
418
|
+
|
|
419
|
+
assert serialized_value == '"hello@example.com"'
|
|
420
|
+
assert restored_value == "hello@example.com"
|
|
421
|
+
assert type(restored_value) is str
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
This behavior is intentional.
|
|
425
|
+
|
|
426
|
+
JSON is a plain data boundary.
|
|
427
|
+
|
|
428
|
+
The exact runtime subtype exists only inside Python objects.
|
|
429
|
+
After serialization, values become plain strings and do not carry subtype information.
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
|
|
402
434
|
## Public API
|
|
403
435
|
|
|
404
436
|
```python
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "base-typed-string"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "Strict typed string base class with exact runtime subtype preservation and optional Pydantic v2 support."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -40,6 +40,7 @@ pydantic = [
|
|
|
40
40
|
test = [
|
|
41
41
|
"pytest>=8.0",
|
|
42
42
|
"pytest-cov>=5.0",
|
|
43
|
+
"pydantic>=2.6,<3",
|
|
43
44
|
]
|
|
44
45
|
lint = [
|
|
45
46
|
"ruff>=0.5",
|
{base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string/_base_typed_string.py
RENAMED
|
@@ -29,9 +29,9 @@ class BaseTypedString(str):
|
|
|
29
29
|
|
|
30
30
|
def __new__(
|
|
31
31
|
cls: type[BaseTypedStringType],
|
|
32
|
-
value:
|
|
32
|
+
value: str,
|
|
33
33
|
) -> BaseTypedStringType:
|
|
34
|
-
if not isinstance(value, str):
|
|
34
|
+
if not isinstance(value, str): # pyright: ignore[reportUnnecessaryIsInstance] runtime boundary guard
|
|
35
35
|
raise BaseTypedStringInvalidInputValueError(
|
|
36
36
|
"BaseTypedString must be initialized only with str. "
|
|
37
37
|
f"Got: {type(value).__name__}."
|
|
@@ -39,7 +39,6 @@ class BaseTypedString(str):
|
|
|
39
39
|
|
|
40
40
|
return str.__new__(cls, value)
|
|
41
41
|
|
|
42
|
-
|
|
43
42
|
@classmethod
|
|
44
43
|
def __get_pydantic_core_schema__(
|
|
45
44
|
cls,
|
|
@@ -56,8 +55,13 @@ class BaseTypedString(str):
|
|
|
56
55
|
Serialization:
|
|
57
56
|
- serializes as plain str
|
|
58
57
|
"""
|
|
58
|
+
del source_type
|
|
59
|
+
del handler
|
|
60
|
+
|
|
59
61
|
try:
|
|
60
|
-
from pydantic_core import
|
|
62
|
+
from pydantic_core import ( # pyright: ignore[reportMissingImports]
|
|
63
|
+
core_schema,
|
|
64
|
+
)
|
|
61
65
|
except ImportError as import_error:
|
|
62
66
|
raise BaseTypedStringInvariantViolationError(
|
|
63
67
|
"pydantic-core is required to build BaseTypedString schema."
|
|
@@ -82,3 +86,6 @@ class BaseTypedString(str):
|
|
|
82
86
|
self,
|
|
83
87
|
) -> tuple[type[BaseTypedString], tuple[str]]:
|
|
84
88
|
return (self.__class__, (str(self),))
|
|
89
|
+
|
|
90
|
+
def __repr__(self) -> str:
|
|
91
|
+
return f"{self.__class__.__name__}({str(self)!r})"
|
|
@@ -7,4 +7,4 @@ class BaseTypedStringInvalidInputValueError(BaseTypedStringError, TypeError):
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class BaseTypedStringInvariantViolationError(BaseTypedStringError):
|
|
10
|
-
"""Raised when an internal invariant or contract is violated."""
|
|
10
|
+
"""Raised when an internal invariant or contract is violated."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: base-typed-string
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Strict typed string base class with exact runtime subtype preservation and optional Pydantic v2 support.
|
|
5
5
|
Author-email: Eldeniz Guseinli <eldenizfamilyanskicode@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pydantic<3,>=2.6; extra == "pydantic"
|
|
|
26
26
|
Provides-Extra: test
|
|
27
27
|
Requires-Dist: pytest>=8.0; extra == "test"
|
|
28
28
|
Requires-Dist: pytest-cov>=5.0; extra == "test"
|
|
29
|
+
Requires-Dist: pydantic<3,>=2.6; extra == "test"
|
|
29
30
|
Provides-Extra: lint
|
|
30
31
|
Requires-Dist: ruff>=0.5; extra == "lint"
|
|
31
32
|
Provides-Extra: typecheck
|
|
@@ -101,7 +102,6 @@ domain-specific names in type annotations, while keeping real `str` behavior at
|
|
|
101
102
|
- no normalization
|
|
102
103
|
- no regex engine
|
|
103
104
|
- no domain-specific methods
|
|
104
|
-
- no custom JSON layer
|
|
105
105
|
|
|
106
106
|
This package is intentionally minimal.
|
|
107
107
|
|
|
@@ -446,6 +446,39 @@ assert type(restored_email) is EmailAddress
|
|
|
446
446
|
|
|
447
447
|
---
|
|
448
448
|
|
|
449
|
+
## JSON behavior
|
|
450
|
+
|
|
451
|
+
Since `BaseTypedString` inherits from `str`, standard JSON serialization naturally produces plain JSON strings.
|
|
452
|
+
|
|
453
|
+
```python
|
|
454
|
+
import json
|
|
455
|
+
|
|
456
|
+
from base_typed_string import BaseTypedString
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
class EmailAddress(BaseTypedString):
|
|
460
|
+
pass
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
value: EmailAddress = EmailAddress("hello@example.com")
|
|
464
|
+
serialized_value: str = json.dumps(value)
|
|
465
|
+
restored_value: object = json.loads(serialized_value)
|
|
466
|
+
|
|
467
|
+
assert serialized_value == '"hello@example.com"'
|
|
468
|
+
assert restored_value == "hello@example.com"
|
|
469
|
+
assert type(restored_value) is str
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
This behavior is intentional.
|
|
473
|
+
|
|
474
|
+
JSON is a plain data boundary.
|
|
475
|
+
|
|
476
|
+
The exact runtime subtype exists only inside Python objects.
|
|
477
|
+
After serialization, values become plain strings and do not carry subtype information.
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
|
|
449
482
|
## Public API
|
|
450
483
|
|
|
451
484
|
```python
|
|
@@ -120,6 +120,14 @@ def test_typed_string_has_same_hash_and_equality_as_plain_string() -> None:
|
|
|
120
120
|
assert hash(typed_value) == hash(plain_value)
|
|
121
121
|
|
|
122
122
|
|
|
123
|
+
def test_repr_uses_exact_runtime_subtype_name_and_plain_string_value() -> None:
|
|
124
|
+
typed_value: AdminUserName = AdminUserName("root")
|
|
125
|
+
|
|
126
|
+
rendered_value: str = repr(typed_value)
|
|
127
|
+
|
|
128
|
+
assert rendered_value == "AdminUserName('root')"
|
|
129
|
+
|
|
130
|
+
|
|
123
131
|
def test_plain_class_attribute_preserves_exact_runtime_subtype() -> None:
|
|
124
132
|
typed_value: UserName = UserName("alice")
|
|
125
133
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{base_typed_string-0.1.0 → base_typed_string-0.1.2}/src/base_typed_string.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|