CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-aenum

Advanced Enumerations (compatible with Python's stdlib Enum), NamedTuples, and NamedConstants

76

1.20x
Overview
Eval results
Files

namedtuple.mddocs/

NamedTuple

Enhanced tuple implementation with named fields, default values, docstrings, and methods for creating structured data containers. The aenum NamedTuple provides more features than the standard library version.

Capabilities

NamedTuple Creation

Factory function for creating NamedTuple classes with named fields and optional features.

def NamedTuple(typename, fields, *, 
               rename=False, module=None, defaults=None, 
               size=TupleSize.fixed, kwds=False, **kwargs):
    """
    Create a new NamedTuple class.
    
    Args:
        typename (str): Name of the new class
        fields (str | list | dict): Field names or field definitions
        rename (bool): Rename invalid field names automatically
        module (str): Module name for the new class
        defaults (list): Default values for fields
        size (TupleSize): Size constraint (fixed, minimum, variable)
        kwds (bool): Allow keyword-only arguments
        **kwargs: Additional options
    
    Returns:
        type: New NamedTuple class with named fields
    """

Basic Usage

from aenum import NamedTuple

# Simple field names
Point = NamedTuple('Point', 'x y')
p = Point(10, 20)
print(p.x, p.y)  # 10 20

# List of field names
Person = NamedTuple('Person', ['name', 'age', 'city'])
person = Person('Alice', 30, 'New York')
print(person.name)  # Alice

# Field names from string
Book = NamedTuple('Book', 'title author isbn year')
book = Book('1984', 'George Orwell', '978-0451524935', 1949)

With Default Values

from aenum import NamedTuple

# Using defaults parameter
Student = NamedTuple('Student', 'name grade school', 
                    defaults=['A', 'Unknown School'])
s1 = Student('John')
print(s1.name, s1.grade, s1.school)  # John A Unknown School

s2 = Student('Jane', 'B+', 'MIT')
print(s2.name, s2.grade, s2.school)  # Jane B+ MIT

# Dictionary-style with defaults and docstrings
Employee = NamedTuple('Employee', {
    'name': 'Employee full name',
    'department': ('Engineering', 'Department name'),  # (default, docstring)
    'salary': (50000, 'Annual salary in USD'),
    'remote': (False, 'Works remotely')
})

emp = Employee('Bob Smith')
print(emp.department)  # Engineering
print(emp.salary)      # 50000

Class-Based NamedTuple

Define NamedTuple using class syntax with field definitions, methods, and properties.

class NamedTuple:
    """Base class for creating class-based NamedTuples."""
    
    def _asdict(self):
        """Return contents as a dictionary."""
    
    def _replace(self, **kwargs):
        """Return new instance with specified fields replaced."""
    
    @classmethod
    def _make(cls, iterable):
        """Create instance from iterable."""
    
    @property
    def _fields(self):
        """Tuple of field names."""

Usage Example

from aenum import NamedTuple

class Point3D(NamedTuple):
    x = 0, 'x coordinate', 0  # index, docstring, default
    y = 1, 'y coordinate', 0
    z = 2, 'z coordinate', 0
    
    def distance_from_origin(self):
        return (self.x**2 + self.y**2 + self.z**2)**0.5
    
    def __str__(self):
        return f'Point3D({self.x}, {self.y}, {self.z})'

# Usage
p1 = Point3D(3, 4, 5)
print(p1.distance_from_origin())  # 7.0710678118654755
print(p1)  # Point3D(3, 4, 5)

# Default values
p2 = Point3D()
print(p2)  # Point3D(0, 0, 0)

# Standard methods
print(p1._asdict())  # {'x': 3, 'y': 4, 'z': 5}
p3 = p1._replace(z=0)
print(p3)  # Point3D(3, 4, 0)

TupleSize

Enumeration defining size constraints for NamedTuples.

class TupleSize(Enum):
    fixed = 'fixed'        # Exact number of fields required
    minimum = 'minimum'    # At least this many fields required
    variable = 'variable'  # Variable number of fields allowed

Usage Example

from aenum import NamedTuple, TupleSize

# Fixed size (default)
Point = NamedTuple('Point', 'x y', size=TupleSize.fixed)
# p = Point(1, 2, 3)  # Would raise TypeError

# Minimum size
Args = NamedTuple('Args', 'command', size=TupleSize.minimum)
cmd1 = Args('ls')
cmd2 = Args('cp', 'file1', 'file2')  # Extra args allowed

# Variable size
Data = NamedTuple('Data', 'header', size=TupleSize.variable)
data1 = Data('header')
data2 = Data('header', 'value1', 'value2', 'value3')

Advanced NamedTuple Features

Field Documentation and Introspection

from aenum import NamedTuple

# Detailed field definitions
User = NamedTuple('User', {
    'username': (0, 'Unique username for login', None),
    'email': (1, 'User email address', None),
    'created_at': (2, 'Account creation timestamp', None),
    'is_active': (3, 'Account active status', True),
    'roles': (4, 'List of user roles', lambda: [])
})

# Access field information
print(User._field_defaults)  # {'is_active': True, 'roles': <lambda>}
print(User._field_types)     # {} (if no type hints)

# Create with partial information
user = User('alice', 'alice@example.com', '2023-01-01')
print(user.is_active)  # True
print(user.roles)      # []

Inheritance and Extension

from aenum import NamedTuple

# Base tuple
Person = NamedTuple('Person', 'name age')

# Extend with additional fields
Employee = NamedTuple('Employee', Person._fields + ('department', 'salary'))

emp = Employee('John Doe', 30, 'Engineering', 75000)
print(emp.name)        # John Doe
print(emp.department)  # Engineering

# Class-based inheritance
class BaseRecord(NamedTuple):
    id = 0, 'Record ID', None
    created = 1, 'Creation timestamp', None

class UserRecord(BaseRecord):
    username = 2, 'Username', None
    email = 3, 'Email address', None
    
    def __str__(self):
        return f'User({self.username})'

user = UserRecord(1, '2023-01-01', 'alice', 'alice@example.com')
print(user)  # User(alice)

Custom Methods and Properties

from aenum import NamedTuple

class Rectangle(NamedTuple):
    width = 0, 'Rectangle width', 0
    height = 1, 'Rectangle height', 0
    
    @property
    def area(self):
        return self.width * self.height
    
    @property  
    def perimeter(self):
        return 2 * (self.width + self.height)
    
    def scale(self, factor):
        return Rectangle(self.width * factor, self.height * factor)
    
    def is_square(self):
        return self.width == self.height

rect = Rectangle(10, 5)
print(rect.area)        # 50
print(rect.perimeter)   # 30
print(rect.is_square()) # False

scaled = rect.scale(2)
print(scaled)  # Rectangle(width=20, height=10)

Practical Patterns

Configuration Objects

from aenum import NamedTuple

# Database configuration
DatabaseConfig = NamedTuple('DatabaseConfig', {
    'host': ('localhost', 'Database host'),
    'port': (5432, 'Database port'),
    'database': (None, 'Database name'),
    'username': (None, 'Database username'),
    'password': (None, 'Database password'),
    'pool_size': (10, 'Connection pool size'),
    'timeout': (30, 'Connection timeout in seconds')
})

# Create configuration with defaults
db_config = DatabaseConfig(
    database='myapp',
    username='user',
    password='secret'
)
print(db_config.host)      # localhost
print(db_config.pool_size) # 10

Data Transfer Objects

from aenum import NamedTuple

class APIResponse(NamedTuple):
    status_code = 0, 'HTTP status code', 200
    data = 1, 'Response data', None
    headers = 2, 'Response headers', lambda: {}
    timestamp = 3, 'Response timestamp', None
    
    @property
    def is_success(self):
        return 200 <= self.status_code < 300
    
    @property
    def is_error(self):
        return self.status_code >= 400
    
    def get_header(self, name):
        return self.headers.get(name.lower())

# Usage
response = APIResponse(
    status_code=200,
    data={'users': [{'id': 1, 'name': 'Alice'}]},
    headers={'content-type': 'application/json'},
    timestamp='2023-01-01T10:00:00Z'
)

print(response.is_success)  # True
print(response.get_header('Content-Type'))  # application/json

Immutable Data Records

from aenum import NamedTuple

class LogEntry(NamedTuple):
    timestamp = 0, 'Log timestamp', None
    level = 1, 'Log level', 'INFO'
    message = 2, 'Log message', ''
    module = 3, 'Source module', None
    line_number = 4, 'Source line number', None
    
    def __str__(self):
        return f'[{self.timestamp}] {self.level}: {self.message}'
    
    def with_context(self, **context):
        """Return new log entry with additional context."""
        updated_message = f"{self.message} | Context: {context}"
        return self._replace(message=updated_message)

# Create log entries
log1 = LogEntry('2023-01-01 10:00:00', 'ERROR', 'Database connection failed')
log2 = log1.with_context(database='postgres', host='localhost')

print(log1)  # [2023-01-01 10:00:00] ERROR: Database connection failed
print(log2.message)  # Database connection failed | Context: {'database': 'postgres', 'host': 'localhost'}

Integration with Type Hints

from aenum import NamedTuple
from typing import Optional, List
from datetime import datetime

# Using with type hints (Python 3.6+)
class UserProfile(NamedTuple):
    username: str = 0, 'Unique username', None
    email: str = 1, 'Email address', None
    full_name: Optional[str] = 2, 'Full display name', None
    tags: List[str] = 3, 'User tags', lambda: []
    created_at: datetime = 4, 'Creation timestamp', None
    
    def display_name(self) -> str:
        return self.full_name or self.username

# Usage maintains type safety
profile = UserProfile(
    username='alice',
    email='alice@example.com',
    full_name='Alice Smith',
    tags=['developer', 'python'],
    created_at=datetime.now()
)

print(profile.display_name())  # Alice Smith

Standard NamedTuple Methods

All NamedTuple instances provide these standard methods:

# Convert to dictionary
person_dict = person._asdict()

# Create new instance with some fields changed  
updated_person = person._replace(age=31)

# Create from iterable
Person = NamedTuple('Person', 'name age city')
person_from_list = Person._make(['Bob', 25, 'Boston'])

# Field names and defaults
print(Person._fields)          # ('name', 'age', 'city')
print(Person._field_defaults)  # {}

Install with Tessl CLI

npx tessl i tessl/pypi-aenum

docs

advanced-enums.md

core-enums.md

flags.md

index.md

namedtuple.md

utilities.md

tile.json