A Python library for creating and managing new types with enhanced type safety and flexibility.
Project description
python-newtype
Documentation
Compatibility and Version
CI/CD
License and Issues
Development and Quality
A powerful Python library for extending existing types with additional functionality while preserving their original behavior, type information and subtype invariances.
Features
- Type Wrapping: Seamlessly wrap existing Python types with new functionality and preservation of subtype invariances when using methods of supertype
- Custom Initialization: Control object initialization with special handling
- Attribute Preservation: Maintains both
__dict__
and__slots__
attributes - Memory Efficient: Uses weak references for caching
- Debug Support: Built-in debug printing capabilities for development
- Async Support: Full support for asynchronous methods and operations
Quick Start
Installation
pip install python-newtype
Basic Usage
import pytest
import re
from newtype import NewType, newtype_exclude
class EmailStr(NewType(str)):
# you can define `__slots__` to save space
__slots__ = (
'_local_part',
'_domain_part',
)
def __init__(self, value: str):
super().__init__()
if "@" not in value:
raise TypeError("`EmailStr` requires a '@' symbol within")
self._local_part, self._domain_part = value.split("@")
@newtype_exclude
def __str__(self):
return f"<Email - Local Part: {self.local_part}; Domain Part: {self.domain_part}>"
@property
def local_part(self):
"""Return the local part of the email address."""
return self._local_part
@property
def domain_part(self):
"""Return the domain part of the email address."""
return self._domain_part
@property
def full_email(self):
"""Return the full email address."""
return str(self)
@classmethod
def from_string(cls, email: str):
"""Create an EmailStr instance from a string."""
return cls(email)
@staticmethod
def is_valid_email(email: str) -> bool:
"""Check if the provided string is a valid email format."""
email_regex = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
return re.match(email_regex, email) is not None
def test_emailstr_replace():
"""`EmailStr` uses `str.replace(..)` as its own method, returning an instance of `EmailStr`
if the resultant `str` instance is a value `EmailStr`.
"""
peter_email = EmailStr("peter@gmail.com")
smith_email = EmailStr("smith@gmail.com")
with pytest.raises(Exception):
# this raises because `peter_email` is no longer an instance of `EmailStr`
peter_email = peter_email.replace("peter@gmail.com", "petergmail.com")
# this works because the entire email can be 'replaced'
james_email = smith_email.replace("smith@gmail.com", "james@gmail.com")
# comparison with `str` is built-in
assert james_email == "james@gmail.com"
# `james_email` is still an `EmailStr`
assert isinstance(james_email, EmailStr)
# this works because the local part can be 'replaced'
jane_email = james_email.replace("james", "jane")
# `jane_email` is still an `EmailStr`
assert isinstance(jane_email, EmailStr)
assert jane_email == "jane@gmail.com"
def test_emailstr_properties_methods():
"""Test the property, class method, and static method of EmailStr."""
# Test property
email = EmailStr("test@example.com")
# `property` is not coerced to `EmailStr`
assert email.full_email == "<Email - Local Part: test; Domain Part: example.com>"
assert isinstance(email.full_email, str)
# `property` is not coerced to `EmailStr`
assert not isinstance(email.full_email, EmailStr)
assert email.local_part == "test"
assert email.domain_part == "example.com"
# Test class method
email_from_string = EmailStr.from_string("classmethod@example.com")
# `property` is not coerced to `EmailStr`
assert (
email_from_string.full_email
== "<Email - Local Part: classmethod; Domain Part: example.com>"
)
assert email_from_string.local_part == "classmethod"
assert email_from_string.domain_part == "example.com"
# Test static method
assert EmailStr.is_valid_email("valid.email@example.com") is True
assert EmailStr.is_valid_email("invalid-email.com") is False
def test_email_str__slots__():
email = EmailStr("test@example.com")
with pytest.raises(AttributeError):
email.hi = "bye"
assert email.hi == "bye"
Documentation
For detailed documentation, visit py-nt.asyncmove.com.
Key Topics:
Development
Prerequisites
- Python 3.8 or higher
- C compiler (for building extensions)
- Development packages:
make install-dev-deps
Building from Source
git clone https://github.com/jymchng/python-newtype-dev.git
cd python-newtype-dev
make build
Install from Source
git clone https://github.com/jymchng/python-newtype-dev.git
cd python-newtype-dev
make install
Running Tests
# Run all tests
make test
# Run with debug output
make test-debug
# Run specific test suite
make test-custom
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Special thanks to all contributors who have helped shape this project.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file python_newtype-0.1.6.tar.gz
.
File metadata
- Download URL: python_newtype-0.1.6.tar.gz
- Upload date:
- Size: 24.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
718e71da617ce03eb444b6e91ec57754eda937c4e4c2574f3914badde3ef610d
|
|
MD5 |
770e43519d95d3ee45062e4fd1bffece
|
|
BLAKE2b-256 |
6fdd6f498d68dc811a603b951c5a2edb9f0ee8cc6b8bca185a72fd6c60f80007
|
File details
Details for the file python_newtype-0.1.6-cp312-cp312-win_amd64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 36.0 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
fee3809d85f67b42adbe248526398e031512c189d9a2ffb371c0121076bcfa94
|
|
MD5 |
c1934dcf2d7671e0d12b75f05905af22
|
|
BLAKE2b-256 |
8166c1aab886dc1e1b82e413c91d96973d7aa69a8e2b8e06b2e35bf788f5fa04
|
File details
Details for the file python_newtype-0.1.6-cp312-cp312-manylinux_2_39_x86_64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp312-cp312-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 58.1 kB
- Tags: CPython 3.12, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
506742d216a48f1920ad5b9a5b5fc29928a7998d6e470f70ddec2076b605c974
|
|
MD5 |
20cb5dd3894a121520fd06270a49a5d8
|
|
BLAKE2b-256 |
8f3bcc9b56b98e4d6beed08aba636edec2ce9282af8f11535fe8ebbe11df880d
|
File details
Details for the file python_newtype-0.1.6-cp312-cp312-macosx_14_0_arm64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp312-cp312-macosx_14_0_arm64.whl
- Upload date:
- Size: 36.8 kB
- Tags: CPython 3.12, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
b0e245ee236900392b4b7c18aac1cfc8fcb833ca6c9ac7550168e494eeb01d80
|
|
MD5 |
d9ba93f7ec2335cd2732040c84fe45c8
|
|
BLAKE2b-256 |
4b94b52177c918b67d4a13bc84b67771e0c8a1ccb785211dcffd32b7bf3b5e3b
|
File details
Details for the file python_newtype-0.1.6-cp311-cp311-win_amd64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 35.8 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
80160d431ba1562a0e5034f48c647ebe08613102555be879afb6d3696266efc0
|
|
MD5 |
fd2973a650892cc07446de2efc1ef784
|
|
BLAKE2b-256 |
1816661ca9fdb132f0ebaf9eca6448cdcce2e2463009a439250eedb52cd2c021
|
File details
Details for the file python_newtype-0.1.6-cp311-cp311-manylinux_2_39_x86_64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp311-cp311-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 55.2 kB
- Tags: CPython 3.11, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
00784ebd3eee89ea9903af7bfa46ebb195c301174cc5645b32c968562e94df81
|
|
MD5 |
33f879f7d1624c166e3cece77f4a056c
|
|
BLAKE2b-256 |
13724d26df4357dbd52ae747812555f51246dc8215fb3a1b9ab23732410d0297
|
File details
Details for the file python_newtype-0.1.6-cp311-cp311-macosx_14_0_arm64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp311-cp311-macosx_14_0_arm64.whl
- Upload date:
- Size: 36.6 kB
- Tags: CPython 3.11, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
e7bbe331611d7b540cea8ca9c87c46c0a38206ead96d7a2034e5dad95cd3a085
|
|
MD5 |
f5531227b78cb807ee45d9f93b9b66ed
|
|
BLAKE2b-256 |
d232d5b385b55b5fd9524bc8227dfacab4f31952da5b7ae45422c72a979be95d
|
File details
Details for the file python_newtype-0.1.6-cp310-cp310-win_amd64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 35.8 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
a91111a744420e27eed7070e108dd0951de99ad9176d3ac5d3a067d83bfa13d0
|
|
MD5 |
9826dc24983a0383038b9e409617ccf8
|
|
BLAKE2b-256 |
1e7e3512197616583e6e940f6c282cbd4b9c49c39cd606564e566fc3299c72df
|
File details
Details for the file python_newtype-0.1.6-cp310-cp310-manylinux_2_39_x86_64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp310-cp310-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 54.6 kB
- Tags: CPython 3.10, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
81460fb11f02abe3c4bc5a1ea6b5c55a1eb785063caa9cfc170468efacfe479d
|
|
MD5 |
130ead7bb05281eb2fa96aeed0a53404
|
|
BLAKE2b-256 |
38c6051f3a6b01497492bd271d46dad3ef990646ffc7edc43d7250717be63b25
|
File details
Details for the file python_newtype-0.1.6-cp310-cp310-macosx_14_0_arm64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp310-cp310-macosx_14_0_arm64.whl
- Upload date:
- Size: 36.6 kB
- Tags: CPython 3.10, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
30c035a309b16ca77a1e30e0a2465023fef34c7e1eadbcc369f50930c17ad0e5
|
|
MD5 |
cecc78cacccc026c321801c1d65804c6
|
|
BLAKE2b-256 |
14ff963a870166ad86e8f35563e26bb734e8a213ecee0e5775bd7dbc3c561796
|
File details
Details for the file python_newtype-0.1.6-cp39-cp39-win_amd64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 35.8 kB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
461face6ce8c455b89fb66580eb9d7118c5ff74f060663cf635b9abed03e5fc0
|
|
MD5 |
4b2770e649bee98bc63f6f4c698f37cc
|
|
BLAKE2b-256 |
99a0a68d6373b49277f6baf3f73d69918fdac9cbc09aeff4df08dd8521fcd48f
|
File details
Details for the file python_newtype-0.1.6-cp39-cp39-manylinux_2_39_x86_64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp39-cp39-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 54.2 kB
- Tags: CPython 3.9, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
18bb0973f91e7807a6d4ea6dc742884902c4b12036dce29d30697fa347bbb4f8
|
|
MD5 |
cd29caf6e06e8d6a93ed89966d5e860a
|
|
BLAKE2b-256 |
757f65e08a6c2b938c722fd27984e661d6eaa1bde44a589e7bf5876425dbcc46
|
File details
Details for the file python_newtype-0.1.6-cp39-cp39-macosx_14_0_arm64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp39-cp39-macosx_14_0_arm64.whl
- Upload date:
- Size: 36.6 kB
- Tags: CPython 3.9, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
c625ae907301e2db392bffef36c657f144802476fca1b3860e292af451bd0552
|
|
MD5 |
6f9ac47a72e338cb09b993703e9189ca
|
|
BLAKE2b-256 |
6e812ffcdeab645ee522fede774304f39f2037e449af1923d506cc42236cbde4
|
File details
Details for the file python_newtype-0.1.6-cp38-cp38-win_amd64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp38-cp38-win_amd64.whl
- Upload date:
- Size: 35.8 kB
- Tags: CPython 3.8, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
332da8a80c2bad3fd1d68577259f93d7436a8c47c33028e51ad0242aed32c58f
|
|
MD5 |
915e380e05b63e13efede8de8b3b74e6
|
|
BLAKE2b-256 |
b8d5df883963777baef4fab297d9ad3a5897f29dfe82ed8bc92af936114da55f
|
File details
Details for the file python_newtype-0.1.6-cp38-cp38-manylinux_2_39_x86_64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp38-cp38-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 56.6 kB
- Tags: CPython 3.8, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
4f7eb9991c77211ada1bdbff3478c36e3b813f2a02c024fc433cdbb95f9e9ed2
|
|
MD5 |
a27f34651a043e22126b0e031358d982
|
|
BLAKE2b-256 |
ded98fd64b740ed9bf2adae98e1de5e4117fe98c4a4acbebe790c8bc3c192da9
|
File details
Details for the file python_newtype-0.1.6-cp38-cp38-macosx_14_0_arm64.whl
.
File metadata
- Download URL: python_newtype-0.1.6-cp38-cp38-macosx_14_0_arm64.whl
- Upload date:
- Size: 36.8 kB
- Tags: CPython 3.8, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
9b4635bda0a81fb5cce3d100ed29ee3f7208cbe01cad7b95dd8f91a24ca7e1f5
|
|
MD5 |
716e539cd03bdf0d9325106ce3f90e5d
|
|
BLAKE2b-256 |
ae881a00a8e5dbad21a864a117a2bfaafd7dd8cd147a689c43b807d58d9267f4
|