extension.registry
Extension Registry for AxisFuzzy.
This module implements the extension registry that records and resolves
“extensions” (external functions) by fuzzy-number type (mtype). It is the
book-keeping backbone of the AxisFuzzy extension system and works together with:
axisfuzzy.extension.__init__ (activation entrypoint,
apply_extensions)axisfuzzy.extension.decorator (declarative registration via
@extension,@batch_extension)axisfuzzy.extension.dispatcher (runtime dispatch proxies: instance methods, properties, top-level)
axisfuzzy.extension.injector (binds proxies to Fuzznum/Fuzzarray classes and module namespace)
For a high-level overview of the extension architecture (Registration → Dispatch → Injection),
Notes
The registry is thread-safe and supports both specialized (mtype-specific) and default implementations for the same function name.
Implementations can specify how they should be exposed via
injection_type: ‘instance_method’, ‘instance_property’, ‘top_level_function’, or ‘both’.Priority values are used to prevent overwriting an existing implementation with an equal or lower priority.
Examples
Register a specialized instance method for ‘qrofn’:
from axisfuzzy.extension import extension
from axisfuzzy.core import Fuzznum
@extension(name='distance', mtype='qrofn', target_classes=['Fuzznum'])
def qrofn_distance(x: Fuzznum, y: Fuzznum, p: int = 2) -> float:
q = x.q
return (((abs(x.md**q - y.md**q))**p + (abs(x.nmd**q - y.nmd**q))**p) / 2) ** (1/p)
Register a dispatched read-only property:
@extension(name='score', mtype='qrofn',
target_classes=['Fuzznum', 'Fuzzarray'],
injection_type='instance_property')
def qrofn_score(obj):
return obj.md ** obj.q - obj.nmd ** obj.q
Register a default fallback exposed also as a top-level function:
@extension(name='normalize', is_default=True, target_classes=['Fuzznum'],
injection_type='both')
def default_normalize(x):
# generic fallback
return x
- class axisfuzzy.extension.registry.ExtensionRegistry[source]
Bases:
objectThread-safe registry for AxisFuzzy extension functions.
The registry stores multiple implementations per logical extension name: - at most one default (fallback) implementation - zero or more specialized implementations keyed by
mtypeIt provides: - A decorator factory (
register()) to register implementations - Lookup by (name, mtype) with default fallback (get_function()) - Introspection helpers for documentation and injectionNotes
The registry does not perform injection itself. Injection happens later via
axisfuzzy.extension.injector, which reads the metadata here and attaches dispatcher proxies created byaxisfuzzy.extension.dispatcher.See also
axisfuzzy.extension.decoratorUser-facing decorators that call this registry.
axisfuzzy.extension.injectorAttaches proxies to classes or module.
axisfuzzy.extension.dispatcherBuilds dispatched proxies used at runtime.
- get_function(name, mtype)[source]
Retrieve a function implementation for
(name, mtype)with fallback.The lookup algorithm is: 1) Try specialized implementation registered for this
mtype. 2) If not found, return the default implementation forname(if any). 3) Otherwise returnNone.- Parameters:
name (str) – Extension name to look up.
mtype (str) – Fuzzy-number type for which to retrieve the specialized implementation.
- Returns:
The resolved implementation function or
Noneif not found.- Return type:
callable or None
Examples
reg = get_registry_extension() fn = reg.get_function('distance', 'qrofn') # specialized if fn is None: raise RuntimeError('No distance registered')
- get_metadata(name, mtype=None)[source]
Retrieve metadata for a registered function.
- Parameters:
name (str) – Extension name to inspect.
mtype (str or None, optional) – If provided, returns specialized metadata for that
mtype. Otherwise, returns default metadata when available.
- Returns:
Stored metadata object or
Noneif not present.- Return type:
FunctionMetadata or None
Examples
reg = get_registry_extension() meta = reg.get_metadata('distance', 'qrofn') if meta: print(meta.injection_type, meta.target_classes)
- get_top_level_function_names()[source]
List function names that should be injected as top-level functions.
This scans both specialized and default registrations and collects any name whose
injection_typeis ‘top_level_function’ or ‘both’.- Returns:
Sorted unique function names requiring top-level injection.
- Return type:
list of str
Examples
reg = get_registry_extension() for fn_name in reg.get_top_level_function_names(): print('top-level:', fn_name)
- list_functions()[source]
List all registered names with their implementation summaries.
The result is a structured summary that groups specialized and default registrations per logical name. This is primarily intended for documentation, debugging, and injection planning.
- Returns:
A dictionary with the following structure:
{ "distance": { "implementations": { "qrofn": { "priority": 0, "target_classes": ["Fuzznum", "Fuzzarray"], "injection_type": "both", } }, "default": { "priority": 0, "target_classes": ["Fuzznum"], "injection_type": "instance_method", }, }, "_random": { "implementations": { "qrofn": { "priority": 0, "target_classes": ["Fuzznum"], "injection_type": "top_level_function", } }, "default": None, }, }- Return type:
dict
Examples
reg = get_registry_extension() summary = reg.list_functions() for name, info in summary.items(): print(name, '=>', info)
- register(name, mtype=None, target_classes=None, injection_type='both', is_default=False, priority=0, **kwargs)[source]
Decorator factory to register an extension function.
This method is used by
axisfuzzy.extension.decorator.extension()(oraxisfuzzy.extension.decorator.batch_extension()) to declare a function as a dispatched extension. It records the function and itsFunctionMetadatain a thread-safe manner.- Parameters:
name (str) – Extension name under which the function is registered.
mtype (str or None, optional) – Specialized fuzzy-number type. If
None, registers as default implementation forname.target_classes (str or list of str, optional) – Injection targets. If
None, defaults to [‘Fuzznum’, ‘Fuzzarray’].injection_type (Literal['instance_method', 'instance_property', 'top_level_function', 'both'], optional) – Exposure mode (method/property/top-level/both). Default is ‘both’.
is_default (bool, optional) – Register as default implementation. Default is False.
priority (int, optional) – Priority for conflict prevention. Existing entries with higher or equal priority block re-registration. Default is 0.
**kwargs – Additional metadata stored into
FunctionMetadata.
- Returns:
A decorator that takes the implementation function and registers it.
- Return type:
callable
- Raises:
ValueError – If attempting to re-register a default or specialized implementation when an existing one with higher or equal priority is already present.
Examples
Specialized method:
from axisfuzzy.extension import extension from axisfuzzy.core import Fuzznum @extension(name='distance', mtype='qrofn', target_classes=['Fuzznum']) def qrofn_distance(x: Fuzznum, y: Fuzznum) -> float: q = x.q return ((abs(x.md**q - y.md**q)**2 + abs(x.nmd**q - y.nmd**q)**2)/2) ** 0.5
Default top-level + instance:
@extension(name='normalize', is_default=True, target_classes=['Fuzznum'], injection_type='both') def normalize_default(x): return x
Dispatched read-only property:
@extension(name='score', mtype='qrofn', target_classes=['Fuzznum','Fuzzarray'], injection_type='instance_property') def qrofn_score(obj): return obj.md**obj.q - obj.nmd**obj.q
- class axisfuzzy.extension.registry.FunctionMetadata(name, mtype, target_classes, injection_type, is_default=False, priority=0, description='')[source]
Bases:
objectMetadata describing a registered extension function.
- name
Logical extension name (e.g., ‘distance’, ‘score’, ‘_random’).
- Type:
str
- mtype
Target fuzzy-number type for the specialized implementation (e.g., ‘qrofn’).
Noneindicates a default (fallback) implementation.- Type:
str or None
- target_classes
Class names to inject into when exposed as instance members, typically a subset of [‘Fuzznum’, ‘Fuzzarray’].
- Type:
list of str
- injection_type
Exposure mode: - ‘instance_method’: dispatched bound method on target classes - ‘instance_property’: dispatched read-only property on target classes - ‘top_level_function’: function injected into the top-level module namespace - ‘both’: both instance method and top-level function
- Type:
{‘instance_method’, ’instance_property’, ’top_level_function’, ’both’}
- is_default
Whether this is a default (fallback) implementation for
name. Defaults to False.- Type:
bool, optional
- priority
Registration priority. Higher values take precedence when preventing re-registration with lower or equal priority. Defaults to 0.
- Type:
int, optional
- description
Short human-readable description for documentation. Defaults to “”.
- Type:
str, optional
Notes
This metadata is consumed by the injector and dispatcher to determine how and where an extension should be exposed after registration.
-
description:
str= ''
-
injection_type:
Literal['instance_method','instance_property','top_level_function','both']
-
is_default:
bool= False
-
mtype:
Optional[str]
-
name:
str
-
priority:
int= 0
-
target_classes:
List[str]
- axisfuzzy.extension.registry.get_registry_extension()[source]
Get the global singleton
ExtensionRegistry.Implements double-checked locking to initialize the singleton in a thread-safe manner on first use.
- Returns:
The global registry instance.
- Return type:
ExtensionRegistry
Examples
reg = get_registry_extension() # Use reg.register(...) via decorators in axisfuzzy.extension.decorator # or call reg.get_function(...) during dispatch.