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.
Release files for python-newtype 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| python_newtype-0.1.6.tar.gz | 24.3 kB | Details |
Built distributions (wheels)
Total release size: 665.7 kB
Release files / python_newtype-0.1.6.tar.gz
| Download URL | python_newtype-0.1.6.tar.gz |
|---|---|
| Size | 24.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
718e71da617ce03eb444b6e91ec57754eda937c4e4c2574f3914badde3ef610d
|
|
BLAKE2b-256 checksum How to use checksums |
6fdd6f498d68dc811a603b951c5a2edb9f0ee8cc6b8bca185a72fd6c60f80007
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp312-cp312-win_amd64.whl
| Download URL | python_newtype-0.1.6-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 36.0 kB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
fee3809d85f67b42adbe248526398e031512c189d9a2ffb371c0121076bcfa94
|
|
BLAKE2b-256 checksum How to use checksums |
8166c1aab886dc1e1b82e413c91d96973d7aa69a8e2b8e06b2e35bf788f5fa04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp312-cp312-manylinux_2_39_x86_64.whl
| Download URL | python_newtype-0.1.6-cp312-cp312-manylinux_2_39_x86_64.whl |
|---|---|
| Size | 58.1 kB |
| Tags | CPython 3.12 Linux glibc 2.39+ x86-64 |
|
SHA-256 checksum How to use checksums |
506742d216a48f1920ad5b9a5b5fc29928a7998d6e470f70ddec2076b605c974
|
|
BLAKE2b-256 checksum How to use checksums |
8f3bcc9b56b98e4d6beed08aba636edec2ce9282af8f11535fe8ebbe11df880d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp312-cp312-macosx_14_0_arm64.whl
| Download URL | python_newtype-0.1.6-cp312-cp312-macosx_14_0_arm64.whl |
|---|---|
| Size | 36.8 kB |
| Tags | CPython 3.12 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b0e245ee236900392b4b7c18aac1cfc8fcb833ca6c9ac7550168e494eeb01d80
|
|
BLAKE2b-256 checksum How to use checksums |
4b94b52177c918b67d4a13bc84b67771e0c8a1ccb785211dcffd32b7bf3b5e3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp311-cp311-win_amd64.whl
| Download URL | python_newtype-0.1.6-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 35.8 kB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
80160d431ba1562a0e5034f48c647ebe08613102555be879afb6d3696266efc0
|
|
BLAKE2b-256 checksum How to use checksums |
1816661ca9fdb132f0ebaf9eca6448cdcce2e2463009a439250eedb52cd2c021
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp311-cp311-manylinux_2_39_x86_64.whl
| Download URL | python_newtype-0.1.6-cp311-cp311-manylinux_2_39_x86_64.whl |
|---|---|
| Size | 55.2 kB |
| Tags | CPython 3.11 Linux glibc 2.39+ x86-64 |
|
SHA-256 checksum How to use checksums |
00784ebd3eee89ea9903af7bfa46ebb195c301174cc5645b32c968562e94df81
|
|
BLAKE2b-256 checksum How to use checksums |
13724d26df4357dbd52ae747812555f51246dc8215fb3a1b9ab23732410d0297
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp311-cp311-macosx_14_0_arm64.whl
| Download URL | python_newtype-0.1.6-cp311-cp311-macosx_14_0_arm64.whl |
|---|---|
| Size | 36.6 kB |
| Tags | CPython 3.11 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e7bbe331611d7b540cea8ca9c87c46c0a38206ead96d7a2034e5dad95cd3a085
|
|
BLAKE2b-256 checksum How to use checksums |
d232d5b385b55b5fd9524bc8227dfacab4f31952da5b7ae45422c72a979be95d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp310-cp310-win_amd64.whl
| Download URL | python_newtype-0.1.6-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 35.8 kB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
a91111a744420e27eed7070e108dd0951de99ad9176d3ac5d3a067d83bfa13d0
|
|
BLAKE2b-256 checksum How to use checksums |
1e7e3512197616583e6e940f6c282cbd4b9c49c39cd606564e566fc3299c72df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp310-cp310-manylinux_2_39_x86_64.whl
| Download URL | python_newtype-0.1.6-cp310-cp310-manylinux_2_39_x86_64.whl |
|---|---|
| Size | 54.6 kB |
| Tags | CPython 3.10 Linux glibc 2.39+ x86-64 |
|
SHA-256 checksum How to use checksums |
81460fb11f02abe3c4bc5a1ea6b5c55a1eb785063caa9cfc170468efacfe479d
|
|
BLAKE2b-256 checksum How to use checksums |
38c6051f3a6b01497492bd271d46dad3ef990646ffc7edc43d7250717be63b25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp310-cp310-macosx_14_0_arm64.whl
| Download URL | python_newtype-0.1.6-cp310-cp310-macosx_14_0_arm64.whl |
|---|---|
| Size | 36.6 kB |
| Tags | CPython 3.10 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
30c035a309b16ca77a1e30e0a2465023fef34c7e1eadbcc369f50930c17ad0e5
|
|
BLAKE2b-256 checksum How to use checksums |
14ff963a870166ad86e8f35563e26bb734e8a213ecee0e5775bd7dbc3c561796
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp39-cp39-win_amd64.whl
| Download URL | python_newtype-0.1.6-cp39-cp39-win_amd64.whl |
|---|---|
| Size | 35.8 kB |
| Tags | CPython 3.9 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
461face6ce8c455b89fb66580eb9d7118c5ff74f060663cf635b9abed03e5fc0
|
|
BLAKE2b-256 checksum How to use checksums |
99a0a68d6373b49277f6baf3f73d69918fdac9cbc09aeff4df08dd8521fcd48f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp39-cp39-manylinux_2_39_x86_64.whl
| Download URL | python_newtype-0.1.6-cp39-cp39-manylinux_2_39_x86_64.whl |
|---|---|
| Size | 54.2 kB |
| Tags | CPython 3.9 Linux glibc 2.39+ x86-64 |
|
SHA-256 checksum How to use checksums |
18bb0973f91e7807a6d4ea6dc742884902c4b12036dce29d30697fa347bbb4f8
|
|
BLAKE2b-256 checksum How to use checksums |
757f65e08a6c2b938c722fd27984e661d6eaa1bde44a589e7bf5876425dbcc46
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp39-cp39-macosx_14_0_arm64.whl
| Download URL | python_newtype-0.1.6-cp39-cp39-macosx_14_0_arm64.whl |
|---|---|
| Size | 36.6 kB |
| Tags | CPython 3.9 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c625ae907301e2db392bffef36c657f144802476fca1b3860e292af451bd0552
|
|
BLAKE2b-256 checksum How to use checksums |
6e812ffcdeab645ee522fede774304f39f2037e449af1923d506cc42236cbde4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp38-cp38-win_amd64.whl
| Download URL | python_newtype-0.1.6-cp38-cp38-win_amd64.whl |
|---|---|
| Size | 35.8 kB |
| Tags | CPython 3.8 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
332da8a80c2bad3fd1d68577259f93d7436a8c47c33028e51ad0242aed32c58f
|
|
BLAKE2b-256 checksum How to use checksums |
b8d5df883963777baef4fab297d9ad3a5897f29dfe82ed8bc92af936114da55f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp38-cp38-manylinux_2_39_x86_64.whl
| Download URL | python_newtype-0.1.6-cp38-cp38-manylinux_2_39_x86_64.whl |
|---|---|
| Size | 56.6 kB |
| Tags | CPython 3.8 Linux glibc 2.39+ x86-64 |
|
SHA-256 checksum How to use checksums |
4f7eb9991c77211ada1bdbff3478c36e3b813f2a02c024fc433cdbb95f9e9ed2
|
|
BLAKE2b-256 checksum How to use checksums |
ded98fd64b740ed9bf2adae98e1de5e4117fe98c4a4acbebe790c8bc3c192da9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Release files / python_newtype-0.1.6-cp38-cp38-macosx_14_0_arm64.whl
| Download URL | python_newtype-0.1.6-cp38-cp38-macosx_14_0_arm64.whl |
|---|---|
| Size | 36.8 kB |
| Tags | CPython 3.8 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
9b4635bda0a81fb5cce3d100ed29ee3f7208cbe01cad7b95dd8f91a24ca7e1f5
|
|
BLAKE2b-256 checksum How to use checksums |
ae881a00a8e5dbad21a864a117a2bfaafd7dd8cd147a689c43b807d58d9267f4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|