Taph creates objects that are guaranteed to be unchangeable, enabling predictable, pure functional programming patterns in Python.
Project description
Taph: Zero-Overhead Immutability for Python
Taph is a minimalist Python package for enforcing deep, zero-overhead immutability. Taph creates objects that are guaranteed to be unchangeable, enabling predictable, pure functional programming patterns in Python.
Taph's core value proposition: Fast & Reliable Immutability.
Key Features
- Zero-Overhead: Achieves immutability using Python's Method Resolution Order (MRO) and metaclass injection.
- Memory Efficiency: Enforces
__slots__usage, eliminating the memory footprint of__dict__for every instance. - Deep Immutability: Recursively transforms nested mutable structures (like
list,dict) into immutable counterparts (tuple,MappingProxyType) during class creation. - Zero Dependencies: A single-file core module built using the Python Standard Library.
Installation
pip install taph
Usage
Taph provides two classes of immutable objects:
Immutablefor instantiable data objectsNamespacefor static constants.
1. The Immutable Base Class
Use Immutable for creating value objects (data structures) whose state must never change after initialization.
Contract: Subclasses must define __slots__.
from taph import Immutable, ImmutableError
class Point(Immutable):
__slots__ = ('x', 'y')
def __init__(self, x: int, y: int):
# IMPORTANT: Use super().__setattr__ for initialization!
super().__setattr__('x', x)
super().__setattr__('y', y)
p = Point(10, 20)
# Fails (ImmutableError)
try:
p.x = 30
except ImmutableError as e:
print(f"Success: {e}")
# Fails (ImmutableError)
try:
del p.y
except ImmutableError as e:
print(f"Success: {e}")
2. The Namespace Static Container
Use Namespace for static configuration, constants, or utility groups. Namespace classes are non-instantiable and their class attributes are ** frozen** at creation time.
from taph import Namespace, ImmutableError
class AppConfig(Namespace):
__slots__ = () # Required, must be empty
VERSION = "1.0.0"
HOSTS = ["server-a", "server-b"] # Deeply frozen into a tuple
# Access attributes directly
print(f"Version: {AppConfig.VERSION}")
print(f"Hosts Type: {type(AppConfig.HOSTS)}") # <class 'tuple'>
# Fails (ImmutableError) - Cannot modify class attributes
try:
AppConfig.TIMEOUT = 60
except ImmutableError as e:
print(f"Success: {e}")
# Fails (ImmutableError) - Cannot instantiate
try:
_ = AppConfig()
except ImmutableError as e:
print(f"Success: {e}")
Deep Freezing
Taph's freeze utility ensures deep immutability by recursively converting mutable collections during class construction:
| Mutable Type | Taph Equivalent |
|---|---|
list |
tuple |
set |
frozenset |
dict |
types.MappingProxyType |
Custom objects must inherit from Immutable or Namespace, or freeze will raise an ImmutableError at class definition time.
Functional Style
Taph provides a solid foundation for functional programming in Python:
1. Pure Functions:
Pass Taph Immutable objects into functions with confidence that no side effects can occur.
from taph import Immutable
class User(Immutable):
__slots__ = ('user_id', 'name', 'is_active')
def __init__(self, user_id: int, name: str, is_active: bool = True):
super().__setattr__('user_id', user_id)
super().__setattr__('name', name)
super().__setattr__('is_active', is_active)
# PURE FUNCTION: No side effects. Takes a User, returns a NEW User.
def deactivate_user(user: User) -> User:
# This is the "copy-on-write" pattern.
return User(
user_id=user.user_id,
name=user.name,
is_active=False
)
# --- Caller ---
user1 = User(101, 'Alice')
user2 = deactivate_user(user1)
# The original object is completely untouched. The system is predictable.
print(user1.is_active) # -> True
print(user2.is_active) # -> False
assert user1 is not user2
2. Stateless Systems:
Use Namespace to provide verifiably safe, global constants that cannot be accidentally mutated by any function.
from taph import Namespace
class Config(Namespace):
__slots__ = ()
TIMEOUT_SECONDS = 30
SUPPORTED_METHODS = ('GET', 'POST')
def is_request_valid(request_duration: int, method: str) -> bool:
# This function is predictable. Its behavior depends on its inputs and
# constants that are guaranteed to be immutable.
if method not in Config.SUPPORTED_METHODS:
return False
return request_duration < Config.TIMEOUT_SECONDS
# Config.TIMEOUT_SECONDS = 1 # Raises ImmutableError, protecting the function.
License
Taph is licensed under the Apache License 2.0. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file taph-0.1.2.tar.gz.
File metadata
- Download URL: taph-0.1.2.tar.gz
- Upload date:
- Size: 12.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b82e767f9a4751bbf005b6b5f64093d554146b5bf8274113a8b003da691b1277
|
|
| MD5 |
2105888aaf74a6e51172f77facdedd5a
|
|
| BLAKE2b-256 |
21b2f3194bb5d46c2669820b5f7d15293178a5e41c58994268088da43809aa75
|
File details
Details for the file taph-0.1.2-py3-none-any.whl.
File metadata
- Download URL: taph-0.1.2-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd52e6359d32f9fe907ae10efd5af50e5f4dadee3d47098ef6ca0233564e8513
|
|
| MD5 |
1fe2d10ae394105b1bc715e8f85882ba
|
|
| BLAKE2b-256 |
bba70ac54281d5088337e33dfd157b69f3502d8feaca7f176aafa227a64d5270
|