extension.dispatcher
Extension Dispatcher for AxisFuzzy.
This module defines the machinery for building dynamic “proxy” callables that resolve and invoke the correct extension implementation at runtime based on the mtype of involved fuzzy objects.
It works in concert with:
axisfuzzy.extension.registry: Stores registered implementations and metadata.
axisfuzzy.extension.injector: Attaches dispatcher-built proxies to classes or the top-level namespace.
Design
The dispatcher is stateless and thread-safe. It builds three kinds of proxies:
Instance method proxies (callable as
obj.fn(...)).Instance property proxies (accessed as
obj.prop).Top-level function proxies (callable as
axisfuzzy.fn(obj, ...)).
Each proxy performs a registry lookup by (name, mtype), falling back to a
default implementation when a specialized one is not available.
Notes
Top-level proxy resolves
mtypefrom one of: 1) explicit keyword argumentmtype=..., 2) the first positional argument if it is a Fuzznum/Fuzzarray instance, 3) the library default (from config) otherwise.Instance proxies read the mtype from the bound object.
Error messages include available specialized mtypes and whether a default implementation exists, aiding debugging.
Examples
Create and use a dispatched instance method:
from axisfuzzy.extension.dispatcher import get_extension_dispatcher
dispatcher = get_extension_dispatcher()
dist_method = dispatcher.create_instance_method('distance')
# Typically attached by the injector:
# Fuzznum.distance = dist_method
# x.distance(y) -> dispatches to ('distance', x.mtype)
Create and use a top-level function:
from axisfuzzy.extension.dispatcher import get_extension_dispatcher
dispatcher = get_extension_dispatcher()
dist_func = dispatcher.create_top_level_function('distance')
# Typically attached to `axisfuzzy` module:
# axisfuzzy.distance(x, y) -> dispatches using x.mtype, unless mtype='...' is passed.
Create and use a dispatched property:
score_prop = dispatcher.create_instance_property('score')
# Typically attached by injector:
# Fuzznum.score = score_prop
# x.score -> dispatches to ('score', x.mtype)
- class axisfuzzy.extension.dispatcher.ExtensionDispatcher[source]
Bases:
objectFactory for creating dispatching proxies for AxisFuzzy extensions.
The dispatcher generates closures and property descriptors that will resolve the correct extension implementation (specialized by
mtype) at call time.Notes
The dispatcher itself does not store function implementations; it exclusively queries the global
ExtensionRegistryviaget_registry_extension().- create_instance_method(func_name)[source]
Create an instance method proxy for an extension.
The returned function is intended to be bound as an instance method on
Fuzznum/Fuzzarray. When invoked, it readsobj.mtypeand resolves the implementation using the global extension registry.- Parameters:
func_name (str) – Logical extension name (e.g., ‘distance’, ‘score’).
- Returns:
A callable suitable for binding as an instance method.
- Return type:
Callable
- Raises:
AttributeError – If the bound object has no
mtypeattribute.NotImplementedError – If the registry does not have a specialized or default implementation.
Examples
from axisfuzzy.extension import get_extension_dispatcher dispatcher = get_extension_dispatcher() Fuzznum.distance = dispatcher.create_instance_method('distance') d = x.distance(y)
- create_instance_property(func_name)[source]
Create an instance property proxy for an extension.
The returned property, when accessed, reads
obj.mtypeand resolves a getter implementation from the global registry.- Parameters:
func_name (str) – Logical extension name for a read-only property (e.g., ‘score’).
- Returns:
A read-only property whose getter dispatches to the registered implementation.
- Return type:
property
- Raises:
AttributeError – If the bound object has no
mtypeattribute.NotImplementedError – If the registry does not have a specialized or default implementation.
Examples
from axisfuzzy.extension import get_extension_dispatcher dispatcher = get_extension_dispatcher() Fuzznum.score = dispatcher.create_instance_property('score') s = x.score
- create_top_level_function(func_name)[source]
Create a top-level function proxy for an extension.
The returned function expects a
Fuzznum/Fuzzarrayinstance as the first positional argument (or an explicitmtype=...in kwargs). It then resolves and invokes the implementation.- Parameters:
func_name (str) – Logical extension name (e.g., ‘distance’, ‘read_csv’).
- Returns:
A callable suitable for injection into the top-level module namespace.
- Return type:
Callable
- Raises:
ValueError – If an explicit
mtypeis invalid (not registered).NotImplementedError – If the registry does not have a specialized or default implementation.
Notes
mtyperesolution order: 1)kwargs['mtype']if present (and removed before the final call), 2)args[0].mtypeif the first argument is aFuzznum/Fuzzarray, 3)config.DEFAULT_MTYPEotherwise.Examples
from axisfuzzy.extension import get_extension_dispatcher dispatcher = get_extension_dispatcher() distance = dispatcher.create_top_level_function('distance') # axisfuzzy.distance(x, y) -> dispatches using x.mtype # axisfuzzy.distance(x, y, mtype='qrofn') -> forces 'qrofn'
- axisfuzzy.extension.dispatcher.get_extension_dispatcher()[source]
Get the global singleton
ExtensionDispatcher.- Returns:
The global dispatcher instance.
- Return type:
Examples
from axisfuzzy.extension.dispatcher import get_extension_dispatcher dispatcher = get_extension_dispatcher()