Main classes and functions¶
objectory ¶
Contain the main features of the objectory package.
objectory.AbstractFactory ¶
Bases: ABCMeta
Implement the abstract factory metaclass to create factories automatically.
Please read the documentation about this abstract factory to learn how it works and how to use it.
To avoid potential conflicts with the other classes, all the
non-public attributes or functions starts with
_abstractfactory_**** where **** is the name of the
attribute or the function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The class name. This becomes the |
required |
bases
|
tuple[type, ...]
|
A tuple of the base classes from which the class
inherits. This becomes the |
required |
dct
|
dict[str, Any]
|
A namespace dictionary containing definitions for the
class body. This becomes the |
required |
Note
Mutating operations (e.g. register_object, unregister)
are synchronized with an internal lock shared by a factory
hierarchy, so classes using this metaclass can safely be
registered from multiple threads.
Example
>>> from objectory import AbstractFactory
>>> class BaseClass(metaclass=AbstractFactory):
... pass
...
>>> class MyClass(BaseClass):
... pass
...
>>> obj = BaseClass.factory("MyClass")
>>> obj
<....MyClass object at 0x...>
objectory.AbstractFactory.inheritors
property
¶
inheritors: dict[str, Any]
Get the inheritors.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
The inheritors. |
Example
>>> from objectory import AbstractFactory
>>> class BaseClass(metaclass=AbstractFactory):
... pass
...
>>> class MyClass(BaseClass):
... pass
...
>>> BaseClass.inheritors
{'....BaseClass': <class '....BaseClass'>, '....MyClass': <class '....MyClass'>}
objectory.AbstractFactory.factory ¶
factory(
_target_: str,
*args: Any,
_init_: str = "__init__",
**kwargs: Any
) -> Any
Instantiate dynamically an object given its configuration.
This method creates an instance of a registered class or calls a registered function. The target can be specified using either the short name (e.g., "MyClass") or the fully qualified name (e.g., "mymodule.MyClass"). If the target is not yet registered, it will attempt to import and register it automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
_target_
|
str
|
The name of the object (class or function) to instantiate. It can be the class name or the full class name. Supports name resolution for registered objects. |
required |
*args
|
Any
|
Positional arguments to pass to the class constructor or function. |
()
|
_init_
|
str
|
The function or method to use to create the object.
If |
'__init__'
|
**kwargs
|
Any
|
Keyword arguments to pass to the class constructor or function. |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
The instantiated object with the given parameters. |
Raises:
| Type | Description |
|---|---|
AbstractClassFactoryError
|
when an abstract class is instantiated. |
UnregisteredObjectFactoryError
|
when the target is not found. |
Example
>>> from objectory import AbstractFactory
>>> class BaseClass(metaclass=AbstractFactory):
... pass
...
>>> class MyClass(BaseClass):
... pass
...
>>> obj = BaseClass.factory("MyClass")
>>> obj
<....MyClass object at 0x...>
objectory.AbstractFactory.register_object ¶
register_object(obj: type | Callable) -> None
Register a class or function to the factory.
This method manually registers a class or function with the factory, making it available for instantiation. This is particularly useful when working with third-party libraries where you cannot modify the source code to inherit from the factory. The object is registered using its fully qualified name. If an object with the same name already exists, it will be replaced with a warning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
type | Callable
|
The class or function to register to the factory. Must be a valid class or function object (not a lambda function). |
required |
Raises:
| Type | Description |
|---|---|
IncorrectObjectAbstractFactoryError
|
if the object is not a class or function, or if it is a lambda function. |
Example
>>> from objectory import AbstractFactory
>>> class BaseClass(metaclass=AbstractFactory):
... pass
...
>>> class MyClass:
... pass
...
>>> BaseClass.register_object(MyClass)
>>> BaseClass.inheritors
{...}
objectory.AbstractFactory.unregister ¶
unregister(name: str) -> None
Remove a registered object from the factory.
This method removes a class or function from the factory's registry. The object will no longer be available for instantiation through the factory. This is an experimental function and may change in the future.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the object to remove. Can be either the short name (e.g., "MyClass") or the fully qualified name (e.g., "mymodule.MyClass"). This function uses the name resolution mechanism to find the full name if only the short name is given. |
required |
Example
>>> from objectory import AbstractFactory
>>> class BaseClass(metaclass=AbstractFactory):
... pass
...
>>> class MyClass:
... pass
...
>>> BaseClass.register_object(MyClass)
>>> BaseClass.unregister("MyClass")
>>> BaseClass.inheritors
{'....BaseClass': <class '....BaseClass'>}
objectory.Registry ¶
Implement the registry class.
This class can be used to register some objects and instantiate an object from its configuration.
Example
>>> from objectory import Registry
>>> from collections import Counter
>>> registry = Registry()
>>> registry.register_object(Counter)
>>> registry.factory("collections.Counter")
Counter()
Note
Accessing an unknown attribute (e.g. registry.other) is not a
read-only operation by default: it implicitly creates and stores a
new sub-registry under that name, even for a typo or a mere
hasattr check. This behavior is deprecated and emits a
FutureWarning. Use :meth:get_or_create to make this creation
explicit, or pass strict=True to disable auto-creation and
raise AttributeError for unknown attributes instead (this will
become the default behavior in a future release).
Note
Mutating operations (e.g. register_object, unregister,
clear) are synchronized with an internal lock, so a single
Registry instance can safely be shared across threads.
objectory.Registry.__getattr__ ¶
__getattr__(key: str) -> Registry | type
Get the registry associated to a key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The key. |
required |
Returns:
| Type | Description |
|---|---|
Registry | type
|
The registry associated to the key. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
if the registry was created with
|
InvalidAttributeRegistryError
|
if the associated attribute is not a registry. |
Example
>>> from collections import Counter
>>> registry = Registry()
>>> registry.other.register_object(Counter)
objectory.Registry.__len__ ¶
__len__() -> int
Return the number of registered objects.
Returns:
| Type | Description |
|---|---|
int
|
The number of registered objects. |
Example
>>> from objectory import Registry
>>> from collections import Counter
>>> registry = Registry()
>>> registry.register_object(Counter)
>>> len(registry)
1
objectory.Registry.clear ¶
clear(nested: bool = False) -> None
Clear the registry.
This functions removes all the registered objects in the registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nested
|
bool
|
Indicates if the sub-registries should be cleared or not. |
False
|
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> # Clear the main registry.
>>> registry.clear()
>>> # Clear only the sub-registry other.
>>> registry.other.clear()
>>> # Clear the main registry and its sub-registries.
>>> registry.clear(nested=True)
objectory.Registry.clear_filters ¶
clear_filters(nested: bool = False) -> None
Clear all the filters of the registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nested
|
bool
|
Indicates if the filters of all the sub-registries should be cleared or not. |
False
|
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> # Clear the filters of the main registry.
>>> registry.clear_filters()
>>> # Clear the filters of the sub-registry other.
>>> registry.other.clear_filters()
>>> # Clear the filters of the main registry and all its sub-registries.
>>> registry.clear_filters(nested=True)
objectory.Registry.factory ¶
factory(
_target_: str,
*args: Any,
_init_: str = "__init__",
**kwargs: Any
) -> Any
Instantiate dynamically an object given its configuration.
This method creates an instance of a registered class or calls a registered function. The target can be specified using either the short name or the fully qualified name. If the target is not yet registered, it will attempt to import and register it automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
_target_
|
str
|
The name of the object (class or function) to instantiate. It can be the class name or the full class name. Supports name resolution for registered objects. |
required |
*args
|
Any
|
Positional arguments to pass to the class constructor or function. |
()
|
_init_
|
str
|
The function or method to use to create the object.
If |
'__init__'
|
**kwargs
|
Any
|
Keyword arguments to pass to the class constructor or function. |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
The instantiated object with the given parameters. |
Raises:
| Type | Description |
|---|---|
AbstractClassFactoryError
|
when an abstract class is instantiated. |
UnregisteredObjectFactoryError
|
if the target name is not found. |
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> @registry.register()
... class MyClass:
... pass
...
>>> registry.factory("MyClass")
<....MyClass object at 0x...>
objectory.Registry.get_or_create ¶
get_or_create(key: str) -> Registry
Get the sub-registry associated to a key, creating it first if needed.
Unlike attribute access, this method makes the auto-creation of
sub-registries explicit, regardless of the strict setting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The key. |
required |
Returns:
| Type | Description |
|---|---|
Registry
|
The sub-registry associated to the key. |
Raises:
| Type | Description |
|---|---|
InvalidAttributeRegistryError
|
if the associated attribute is not a registry. |
Example
>>> from collections import Counter
>>> registry = Registry()
>>> registry.get_or_create("other").register_object(Counter)
objectory.Registry.register ¶
register(
name: str | None = None,
) -> Callable[[Registerable], Registerable]
Define a decorator to add a class or a function to the registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
The name to use to register the object.
If |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[Registerable], Registerable]
|
The decorated object. |
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> @registry.register()
... class ClassToRegister:
... pass
...
>>> registry.registered_names()
{'....ClassToRegister'}
>>> @registry.register()
... def function_to_register(*args, **kwargs):
... pass
...
>>> registry.registered_names()
{...}
objectory.Registry.register_child_classes ¶
register_child_classes(
cls: type, ignore_abstract_class: bool = True
) -> None
Register a given class and its child classes.
This function registers all the child classes including the child classes of the child classes, etc. If you use this function, you cannot choose the names used to register the objects. It will use the fully qualified name of each object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type
|
The class to register along with its child classes. |
required |
ignore_abstract_class
|
bool
|
Indicate if the abstract classes should be ignored or not. By default, the abstract classes are not registered because they cannot be instantiated. |
True
|
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> registry.register_child_classes(dict)
>>> registry.registered_names()
{...}
objectory.Registry.register_object ¶
register_object(
obj: type | Callable, name: str | None = None
) -> None
Register an object.
This method adds a class or function to the registry, making it available for instantiation through the factory method. You can optionally specify a custom name for the object; otherwise, its fully qualified name will be used. If a class filter is set, the object must be a subclass of the filter class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
type | Callable
|
The object to register. The object must be a class or a function (not a lambda function). |
required |
name
|
str | None
|
The name to use to register the object. If |
None
|
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> class ClassToRegister:
... pass
...
>>> registry.register_object(ClassToRegister)
>>> registry.registered_names()
{'....ClassToRegister'}
>>> def function_to_register(*args, **kwargs):
... pass
...
>>> registry.register_object(function_to_register)
>>> registry.registered_names()
{...}
objectory.Registry.registered_names ¶
registered_names(include_registry: bool = True) -> set[str]
Get the names of all the registered objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_registry
|
bool
|
Indicates if the other (sub-)registries should be included in the set. By default, the other (sub-)registries are included. |
True
|
Returns:
| Type | Description |
|---|---|
set[str]
|
The names of the registered objects. |
Example
>>> from objectory import Registry
>>> registry = Registry()
>>> registry.registered_names()
>>> # Show name of all the registered objects except the sub-registries.
>>> registry.registered_names(include_registry=False)
objectory.Registry.set_class_filter ¶
set_class_filter(cls: type | None) -> None
Set the class filter so only the child classes of this class can be registered.
If you set this filter, you cannot register functions.
To unset this filter, you can use set_class_filter(None).
The filter is only enforced at registration time: it does
not retroactively validate objects that were already
registered before the filter was set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type | None
|
The class to use as filter. Only the child classes of this class can be registered. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
if the input is not a class or |
Example
>>> from collections import Counter, OrderedDict
>>> from objectory import Registry
>>> registry = Registry()
>>> registry.mapping.set_class_filter(dict)
>>> registry.mapping.register_object(OrderedDict)
>>> registry.mapping.registered_names()
{'collections.OrderedDict'}
objectory.Registry.unregister ¶
unregister(name: str) -> None
Remove a registered object.
This method removes a class or function from the registry. The object will no longer be available for instantiation through the factory method.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The name of the object to remove. Can be either the short name or the fully qualified name. This function uses the name resolution mechanism to find the full name if only the short name is given. |
required |
Raises:
| Type | Description |
|---|---|
UnregisteredObjectFactoryError
|
if the name does not exist in the registry. |
Example
>>> from objectory import Registry
>>> from collections import Counter
>>> registry = Registry()
>>> registry.register_object(Counter)
>>> registry.unregister("collections.Counter")
objectory.factory ¶
factory(
_target_: str,
*args: Any,
_init_: str = "__init__",
**kwargs: Any
) -> Any
Instantiate dynamically an object given its configuration.
This function provides a universal factory that can instantiate any class or call any function by its fully qualified name. Unlike the AbstractFactory or Registry approaches, this function does not require prior registration of classes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
_target_
|
str
|
The fully qualified name of the object (class or function) to instantiate, e.g., "collections.Counter" or "math.isclose". |
required |
*args
|
Any
|
Positional arguments to pass to the class constructor or function. |
()
|
_init_
|
str
|
The function or method to use to create the object.
If |
'__init__'
|
**kwargs
|
Any
|
Keyword arguments to pass to the class constructor or function. |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
The instantiated object with the given parameters. |
Raises:
| Type | Description |
|---|---|
UnregisteredObjectFactoryError
|
if the target cannot be found. |
TypeError
|
if |
Example
>>> from objectory import factory
>>> factory("collections.Counter", [1, 2, 1, 3])
Counter({1: 2, 2: 1, 3: 1})
objectory.resolve_object ¶
resolve_object(
obj: T | dict[str, Any], cls: type[T] = object
) -> T
Resolve an instance of cls from an existing object or a
configuration dictionary.
If obj is already an instance of cls it is returned
as-is. If it is a :class:dict, it is treated as an
objectory factory configuration and instantiated via
:func:objectory.factory.
Note
Any :class:dict (including instances of dict
subclasses, e.g. Counter or OrderedDict) is always
treated as a factory configuration, even when it is already
a valid instance of cls. Do not use this function to
resolve objects whose expected type is itself a dict
subclass.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
T | dict[str, Any]
|
Either a fully configured instance of |
required |
cls
|
type[T]
|
The expected type. Used to validate the resolved object,
whether |
object
|
Returns:
| Type | Description |
|---|---|
T
|
A configured instance of |
Raises:
| Type | Description |
|---|---|
IncorrectTypeFactoryError
|
If |
Example
>>> from datetime import date
>>> from objectory import resolve_object
>>> # From an existing instance:
>>> d = resolve_object(date(2020, 1, 1), cls=date)
>>> # From a configuration dictionary:
>>> d = resolve_object(
... {"_target_": "datetime.date", "year": 2020, "month": 1, "day": 1}, cls=date
... )