hbutils.model.clazz

Class modeling utilities for declarative Python objects.

This module provides decorators and helper functions that simplify the creation of lightweight data-centric classes. It focuses on generating commonly needed behaviors such as automatic field access, visual representations, constructor generation, hash/equality support, and property accessors, all while supporting name-mangled private attributes.

The module contains the following main public components:

  • get_field() - Retrieve attributes with support for private name mangling

  • asitems() - Declare class-level field names

  • visual() - Generate a human-friendly __repr__ implementation

  • constructor() - Generate an __init__ constructor from field specs

  • hasheq() - Generate __hash__, __eq__, and __ne__ methods

  • accessor() - Generate property accessors for private fields

Example:

>>> @accessor(readonly=True)
>>> @visual()
>>> @constructor(['x', ('y', 2)])
>>> class Point:
...     pass
>>> p = Point(1)
>>> p
<Point x: 1, y: 2>
>>> p.x
1

Note

These decorators are designed to cooperate. For example, using asitems() enables automatic field discovery by constructor(), visual(), and hasheq().

__all__

hbutils.model.clazz.__all__ = ['get_field', 'asitems', 'visual', 'constructor', 'hasheq', 'accessor']

Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

CLASS_WRAPPER_UPDATES

hbutils.model.clazz.CLASS_WRAPPER_UPDATES = ()

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable’s items.

If the argument is a tuple, the return value is the same object.

get_field

hbutils.model.clazz.get_field(obj: ~typing.Any, name: str, default: ~typing.Any = <SingletonMark 'no_default_value'>) Any[source]

Get field from object with support for private attributes.

This function resolves name-mangled private attributes and uses getattr to fetch the field. When a default is provided, it will be returned instead of raising AttributeError.

Parameters:
  • obj (object) – The given object.

  • name (str) – Field to be retrieved.

  • default (Any, optional) – Default value to return if the field does not exist. If not provided, the absence of the field raises AttributeError.

Returns:

Field value for the requested field.

Return type:

Any

Raises:

AttributeError – If the field does not exist and no default is provided.

Example:

>>> class MyClass:
...     def __init__(self):
...         self.__private_field = 42
>>> obj = MyClass()
>>> get_field(obj, '__private_field')
42
>>> get_field(obj, 'nonexistent', default='default_value')
'default_value'

asitems

hbutils.model.clazz.asitems(items: Iterable[str]) Callable[[Type[Any]], Type[Any]][source]

Define fields in the class level.

This decorator assigns the provided field names to __items__, which can be consumed by other decorators such as constructor(), visual(), hasheq(), and accessor().

Parameters:

items (Iterable[str]) – Field name items.

Returns:

Decorator to decorate the given class.

Return type:

Callable

Example:

>>> @visual()
>>> @constructor(doc='''
...     Overview:
...         This is the constructor of class :class:`T`.
... ''')
>>> @asitems(['x', 'y'])
>>> class T:
...     @property
...     def x(self):
...         return self.__first
...
...     @property
...     def y(self):
...         return self.__second

Note

This decorator sets __items__ on the class, which is used by other decorators to determine which fields to process.

visual

hbutils.model.clazz.visual(items: Iterable[str | Tuple[str, Callable[[Any], str]]] | None = None, show_id: bool = False) Callable[[Type[Any]], Type[Any]][source]

Decorate class to be visible by repr.

Parameters:
  • items (Optional[Iterable[Union[str, Tuple[str, Callable[[Any], str]]]]]) – Items to be displayed. Default is None, which means automatically find the private fields and display them. Items can be strings (field names) or (name, repr_func) pairs.

  • show_id (bool) – Show hex id in representation string or not. Defaults to False.

Returns:

Decorator to decorate the given class.

Return type:

Callable

Example:

>>> @visual()
>>> class T:
...     def __init__(self, x, y):
...         self.__first = x
...         self.__second = y
>>> repr(T(1, 2))
'<T first: 1, second: 2>'

>>> @visual(show_id=True)
>>> class T2:
...     def __init__(self, x):
...         self.__x = x
>>> repr(T2(42))
'<T2 0x... x: 42>'

Note

This decorator generates a __repr__ method that displays the specified fields or all private fields if none are specified.

constructor

hbutils.model.clazz.constructor(params: Iterable[str | Tuple[str, Any]] | None = None, doc: str | None = None) Callable[[Type[Any]], Type[Any]][source]

Decorate class to create an init function.

Parameters:
  • params (Optional[Iterable[Union[str, Tuple[str, Any]]]]) – Parameters of constructor. Each item should be a string (argument name) or a tuple of (name, default_value). Default is None, which means no arguments (unless __items__ is defined on the class).

  • doc (Optional[str]) – Documentation of constructor function. Defaults to None.

Returns:

Decorator to decorate the given class.

Return type:

Callable

Example:

>>> @constructor(['x', ('y', 2)], '''
...     Overview:
...         This is the constructor of class :class:`T`.
... ''')
>>> class T:
...     # the same as:
...     # def __init__(self, x, y=2):
...     #     self.__x = x
...     #     self.__y = y
...
...     @property
...     def x(self):
...         return self.__x
...
...     @property
...     def y(self):
...         return self.__y
>>> t = T(1)
>>> t.x, t.y
(1, 2)

Note

This decorator generates an __init__ method that stores argument values into private attributes using name mangling.

hasheq

hbutils.model.clazz.hasheq(items: Iterable[str] | None = None) Callable[[Type[Any]], Type[Any]][source]

Decorate class to support hashing and equality comparison.

Parameters:

items (Optional[Iterable[str]]) – Items to be hashed and compared. Default is None, which means automatically find the private fields and use them.

Returns:

Decorator to decorate the given class.

Return type:

Callable

Example:

>>> @hasheq(['x', 'y'])
>>> class T:
...     def __init__(self, x, y):
...         self.__first = x
...         self.__second = y
>>> t1 = T(1, 2)
>>> t2 = T(1, 2)
>>> t1 == t2
True
>>> hash(t1) == hash(t2)
True

Using with :func:`asitems`::

>>> @hasheq()
>>> @constructor()
>>> @asitems(['x', 'y'])
>>> class T1:
...     pass
>>> t1 = T1(1, 2)
>>> t2 = T1(1, 2)
>>> t1 == t2
True

Note

This decorator generates __hash__, __eq__, and __ne__ methods for the class based on the specified fields.

accessor

hbutils.model.clazz.accessor(items: Iterable[str | Tuple[str, str]] | None = None, readonly: bool = False) Callable[[Type[Any]], Type[Any]][source]

Decorate class to be accessible by property accessors.

Parameters:
  • items (Optional[Iterable[Union[str, Tuple[str, str]]]]) – Items to be accessed. Default is None, which means automatically find the private fields and create accessors for them. Each item can be a string (field name) or a (name, access_mode) tuple.

  • readonly (bool) – Default readonly or not. Default is False, which means make the accessor writable when rw option is not given.

Returns:

Decorator to decorate the given class.

Return type:

Callable

Example:

>>> @accessor(readonly=True)
>>> @asitems(['x', 'y'])
>>> class T:
...     def __init__(self, x, y):
...         self.__x = x
...         self.__y = y
>>> t = T(2, 100)
>>> t.x  # 2
2
>>> t.y  # 100
100

With writable access::

>>> @accessor(readonly=False)
>>> @asitems(['x', 'y'])
>>> class T2:
...     def __init__(self, x, y):
...         self.__x = x
...         self.__y = y
>>> t = T2(2, 100)
>>> t.x = 42
>>> t.x
42

With mixed access control::

>>> @accessor([('x', 'ro'), ('y', 'rw')])
>>> class T3:
...     def __init__(self, x, y):
...         self.__x = x
...         self.__y = y
>>> t = T3(1, 2)
>>> t.y = 42  # OK
>>> # t.x = 10  # This would raise AttributeError

Note

This decorator automatically generates property accessors for the specified fields. Access modes: 'r'/'ro'/'readonly' for read-only, 'w'/'rw'/'writable' for read-write.