core.registry

Central registry for fuzzy number types (mtype).

The registry module is a cornerstone of AxisFuzzy’s extensibility, allowing developers to register and integrate new types of fuzzy numbers seamlessly. This module provides the FuzznumRegistry`, a thread-safe singleton class that serves as the central directory for all fuzzy number implementations within AxisFuzzy. It maps a unique string identifier, the membership type or mtype, to its corresponding concrete implementation classes:

  • FuzznumStrategy: Define rules, constraints, and basic operations for fuzzy numbers.

  • FuzzarrayBackend: Manages the high-performance, Struct-of-Arrays (SoA) data storage for Fuzzarray.

The registry supports transactional registrations, an observer pattern for monitoring changes, and comprehensive introspection capabilities. A suite of factory functions and decorators is also provided for convenient interaction with the global registry instance.

class axisfuzzy.core.registry.FuzznumRegistry(*args, **kwargs)[source]

Bases: object

A thread-safe, singleton registry for fuzzy number implementations.

This class manages the association between a membership type string (mtype) and the corresponding FuzznumStrategy and FuzzarrayBackend classes that define its behavior and storage. As a singleton, it ensures that there is only one central source of truth for all fuzzy number types throughout the application’s lifecycle.

The registry is designed for robustness and extensibility, featuring:

  • Thread Safety: All registration and retrieval operations are protected by locks to prevent race conditions in multithreaded environments.

  • Transactional Operations: The transaction context manager allows for atomic batch registrations, ensuring that either all registrations in a batch succeed or none do, maintaining a consistent state.

  • Observer Pattern: External components can subscribe to registry events (e.g., registration, unregistration) to react dynamically to changes.

  • Introspection: Provides methods to query the registry’s state, such as listing all registered mtypes, checking their completeness, and retrieving performance statistics.

strategies

A dictionary mapping mtype strings to their registered FuzznumStrategy classes.

Type:

dict[str, type[FuzznumStrategy]]

backends

A dictionary mapping mtype strings to their registered FuzzarrayBackend classes.

Type:

dict[str, type[FuzzarrayBackend]]

Notes

This class should not be instantiated directly. Instead, the global singleton instance should be accessed via the get_registry_fuzztype() factory function.

Examples

Registering a new, complete fuzzy number type (mtype).

First, define a mock strategy and backend:

from axisfuzzy.core.base import FuzznumStrategy
from axisfuzzy.core.backend import FuzzarrayBackend
class MyNewStrategy(FuzznumStrategy):
    mtype = 'mynewtype'
    # ... implementation ...
class MyNewBackend(FuzzarrayBackend):
    mtype = 'mynewtype'
    # ... implementation ...

Now, get the global registry and register the new type:

from axisfuzzy.core.registry import get_registry_fuzztype
registry = get_registry_fuzztype()
result = registry.register(strategy=MyNewStrategy, backend=MyNewBackend)
print(result['mtype'])
# mynewtype
'mynewtype' in registry.get_registered_mtypes()
# True
add_observer(observer)[source]

Registers an observer to be notified of registry events.

The observer pattern allows external components to listen for changes within the registry, such as the registration or unregistration of a fuzzy number type. The observer must be a callable that accepts two arguments: an event type string and a dictionary containing event-specific data.

Parameters:

observer (callable) – A callable with the signature observer(event_type, event_data), where event_type is a string (e.g., ‘register_strategy’) and event_data is a dictionary with details about the event.

Return type:

None

batch_register(registrations)[source]

Registers multiple fuzzy number types from a list in a single transaction.

This method wraps the registration process in a transaction, ensuring that all types in the list are registered successfully. If any single registration fails, the entire batch is rolled back, leaving the registry in its original state.

Parameters:

registrations (list[dict]) – A list where each item is a dictionary, typically with ‘strategy’ and/or ‘backend’ keys pointing to the classes to be registered. Example: [{'strategy': QROFNStrategy, 'backend': QROFNBackend}, ...]

Returns:

A dictionary where keys are the mtypes of the successfully registered types and values are the detailed results from the register method.

Return type:

dict

Raises:
  • TypeError – If registrations is not a list or if an item in the list is not a dict.

  • ValueError, TypeError – If any individual registration fails its validation, the exception is re-raised after the transaction is rolled back.

get_backend(mtype)[source]

Retrieves the registered FuzzarrayBackend class for a given mtype.

Parameters:

mtype (str) – The mtype identifier.

Returns:

The registered FuzzarrayBackend subclass.

Return type:

type[FuzzarrayBackend]

Raises:

ValueError – If no backend is found for the specified mtype.

get_health_status()[source]

Performs a health check on the registry to find incomplete registrations.

An mtype is considered “incomplete” if it has a registered strategy but no backend, or vice versa. A healthy registry has no incomplete types.

Returns:

A dictionary containing health status information, including an is_healthy boolean flag, and lists of complete_types, incomplete_types, missing_strategies, and missing_backends.

Return type:

dict

get_registered_mtypes()[source]

Provides a comprehensive overview of all registered mtypes.

This introspection method returns a dictionary detailing the status of every mtype known to the registry, including whether it has a registered strategy and/or backend, and the names of the associated classes.

Returns:

A dictionary where keys are mtype strings. Each value is another dictionary containing boolean flags has_strategy, has_backend, is_complete, and the string names strategy_class and backend_class.

Return type:

dict

get_statistics()[source]

Retrieves quantitative statistics about the registry’s state and activity.

This method is useful for monitoring and debugging, providing insights into the number of registered components, registration failures, and active observers.

Returns:

A dictionary containing statistics such as total_strategies, total_backends, complete_types, registration_stats, and observer_count.

Return type:

dict

get_strategy(mtype)[source]

Retrieves the registered FuzznumStrategy class for a given mtype.

Parameters:

mtype (str) – The mtype identifier.

Returns:

The registered FuzznumStrategy subclass.

Return type:

type[FuzznumStrategy]

Raises:

ValueError – If no strategy is found for the specified mtype.

register(strategy=None, backend=None)[source]

Registers a strategy and a backend for a given fuzzy type mtype.

This is the primary method for registering the components of a fuzzy number type. It can register a strategy, a backend, or both in a single, thread-safe operation. It validates the inputs and ensures that if both are provided, their mtype attributes match.

Parameters:
  • strategy (FuzznumStrategy, optional) – The FuzznumStrategy subclass to register.

  • backend (FuzzarrayBackend, optional) – The FuzzarrayBackend subclass to register.

Returns:

A dictionary summarizing the registration bundle, containing the mtype and a list of details for each component registered.

Return type:

dict

Raises:
  • ValueError – If neither strategy nor backend is provided, or if their mtype attributes do not match.

  • TypeError – If the provided strategy or backend are not valid classes.

register_backend(backend)[source]

Registers a single FuzzarrayBackend subclass with the registry.

This method performs validation to ensure the provided class is a valid subclass of FuzzarrayBackend and has the required mtype attribute. It then adds the class to the internal backends mapping.

Parameters:

backend (FuzzarrayBackend) – The FuzzarrayBackend subclass to register.

Returns:

A dictionary containing details of the registration, including mtype, component (‘backend’), registered_class name, and whether an existing registration was overwrote_existing.

Return type:

dict

Raises:
  • TypeError – If backend is not a class or not a subclass of FuzzarrayBackend.

  • ValueError – If the backend class does not have an mtype attribute defined.

register_strategy(strategy)[source]

Registers a single FuzznumStrategy subclass with the registry.

This method performs validation to ensure the provided class is a valid subclass of FuzznumStrategy and has the required mtype attribute. It then adds the class to the internal strategies mapping.

Parameters:

strategy (FuzznumStrategy) – The FuzznumStrategy subclass to register.

Returns:

A dictionary containing details of the registration, including mtype, component (‘strategy’), registered_class name, and whether an existing registration was overwrote_existing.

Return type:

dict

Raises:
  • TypeError – If strategy is not a class or not a subclass of FuzznumStrategy.

  • ValueError – If the strategy class does not have an mtype attribute defined.

remove_observer(observer)[source]

Removes a previously registered observer.

If the specified observer is found in the list of registered observers, it will be removed and will no longer receive notifications of registry events.

Parameters:

observer (callable) – The observer callable to be removed.

Return type:

None

transaction()[source]

A context manager for performing atomic, transactional registrations.

This method ensures that a series of registration or unregistration operations are treated as a single, atomic unit. If any operation within the with block raises an exception, all changes made to the registry during the transaction are automatically rolled back to their original state. This is particularly useful for batch registrations where a consistent state must be maintained.

Yields:

None – This context manager does not yield a value.

Raises:

Exception – Any exception raised within the with block will be re-raised after the rollback is complete.

Examples

# Assume MyStrategy, MyBackend, BadStrategy are defined
registry = get_registry_fuzztype()
try:
    with registry.transaction():
        registry.register(strategy=MyStrategy, backend=MyBackend)
        # This next line will raise a ValueError
        registry.register(strategy=BadStrategy)
except ValueError:
    print("Transaction failed and rolled back.")

 # The first registration was also rolled back
'my_mtype' in registry.get_registered_mtypes()
# False
unregister(mtype, remove_strategy=True, remove_backend=True)[source]

Removes a strategy and/or backend for a given mtype from the registry.

This allows for the dynamic removal of fuzzy number types.

Parameters:
  • mtype (str) – The mtype identifier of the fuzzy number type to unregister.

  • remove_strategy (bool, default True) – If True, removes the associated FuzznumStrategy class.

  • remove_backend (bool, default True) – If True, removes the associated FuzzarrayBackend class.

Returns:

A dictionary detailing the result of the unregistration, including which components were removed.

Return type:

dict

Raises:

TypeError – If mtype is not a string.

axisfuzzy.core.registry.get_registry_fuzztype()[source]

Access the global singleton instance of FuzznumRegistry.

This is the standard factory function for obtaining the registry. It ensures that only one instance of the registry exists across the entire application, providing a consistent and centralized management point for all fuzzy number types.

Returns:

The global singleton registry instance.

Return type:

FuzznumRegistry

axisfuzzy.core.registry.register_backend(cls)[source]

A class decorator for automatically registering a FuzzarrayBackend.

This decorator provides a convenient way to register a backend class with the global registry at the time of its definition.

Parameters:

cls (type[FuzzarrayBackend]) – The FuzzarrayBackend subclass to be decorated and registered.

Returns:

The original class, unchanged.

Return type:

type[FuzzarrayBackend]

Examples

from axisfuzzy.core.registry import register_backend

@register_backend
class MyNewBackend(FuzzarrayBackend):
    mtype = 'decorated_backend'
    # ... implementation ...
axisfuzzy.core.registry.register_fuzztype(strategy=None, backend=None)[source]

A convenience function to register a strategy and/or backend with the global registry.

This method provides a convenient way to register both strategies and backends simultaneously; however, it is generally recommended to use the @register_strategy and @register_backend decorators for registration.

Parameters:
  • strategy (type[FuzznumStrategy], optional) – The FuzznumStrategy subclass to register.

  • backend (type[FuzzarrayBackend], optional) – The FuzzarrayBackend subclass to register.

Returns:

The result dictionary from the underlying register call.

Return type:

dict

Examples

 # Assuming MyStrategy and MyBackend classes are defined
from axisfuzzy.core.registry import register_fuzztype
register_fuzztype(strategy=MyStrategy, backend=MyBackend)
axisfuzzy.core.registry.register_strategy(cls)[source]

A class decorator for automatically registering a FuzznumStrategy.

This decorator provides a convenient way to register a strategy class with the global registry at the time of its definition.

Parameters:

cls (FuzznumStrategy) – The FuzznumStrategy subclass to be decorated and registered.

Returns:

The original class, unchanged.

Return type:

FuzznumStrategy

Examples

from axisfuzzy.core.registry import register_strategy
@register_strategy
class MyNewStrategy(FuzznumStrategy):
    mtype = 'decorated_strategy'
    # ... implementation ...