Announcements

class domprob.announcements.decorators._Announcement(instrument, required=False)[source]

Bases: Generic[_MethodCls, _Instrument, _P, _R]

Decorator class for associating metadata and validating methods.

This class enables the decoration of methods with metadata describing their required instruments. It enforces runtime validation to ensure that the method is called with the correct parameters and that the instrument argument satisfies the specified requirements.

The @announcement decorator can be stacked.

Warning

It is strongly recommended that instrument classes defined in stacked decorators inherit from the same base class or implement the same typing protocol.

Parameters:
  • instrument (type[_Instrument]) – The instrument class required by the decorated method.

  • required (bool) – Whether the instrument is required. Defaults to False.

Examples

Simple implementation:

>>> class PrintInstrument:
...
...     @staticmethod
...     def stdout(msg: str) -> None:
...         print(msg)
...
...     def __repr__(self) -> str:
...         return f"{self.__class__.__name__}()"
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(PrintInstrument)
...     def bar(self, instrument: PrintInstrument) -> None:
...         instrument.stdout(f"Executing with {instrument!r}")
...
>>> foo = Foo()
>>> instru = PrintInstrument()
>>>
>>> foo.bar(instru)
Executing with PrintInstrument()

Supporting the same announcement implementation with multiple instruments:

>>> import logging
>>> from abc import ABC, abstractmethod
>>>
>>> # Define instruments
>>> class AbstractStdOutInstrument(ABC):
...     @abstractmethod
...     def stdout(self, cls_name: str) -> None:
...         raise NotImplementedError
...
...     def __repr__(self) -> str:
...         return f"{self.__class__.__name__}()"
...
>>> class PrintInstrument(AbstractStdOutInstrument):
...     def stdout(self, cls_name: str) -> None:
...         print(f"Observing '{cls_name}' with '{self!r}'")
...
>>> class LogInstrument(AbstractStdOutInstrument):
...
...     def __init__(self):
...         self.logger = logging.getLogger()
...         self.logger.setLevel(logging.INFO)
...
...     def stdout(self, cls_name: str) -> None:
...         logger = logging.getLogger()
...         logger.setLevel(logging.INFO)
...         logger.info(f"Observing '{cls_name}' with '{self!r}'")
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(PrintInstrument)
...     @announcement(LogInstrument)
...     def bar(self, instrument: AbstractStdOutInstrument) -> None:
...         instrument.stdout(self.__class__.__name__)
...
>>> foo = Foo()
>>> instru = PrintInstrument()
>>>
>>> foo.bar(instru)
Observing 'Foo' with 'PrintInstrument()'
__call__(method)[source]

Wraps a method to associate metadata and enforce runtime validation.

This method is invoked when the @announcement decorator is used on a method. It attaches metadata, including the instrument class and requirement status, to the method and enforces validation when the method is called at runtime.

Parameters:

method (Callable[P, R]) – The method to decorate.

Returns:

A wrapped version of the input method with metadata and validation applied.

Return type:

Callable[P, R]

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         print(f"Executing with {instrument!r}")
...
>>> foo = Foo()
>>> instru = SomeInstrument()
>>>
>>> foo.bar(instru)
Executing with <...SomeInstrument object at 0x...>
__repr__()[source]

Returns a string representation of the Announcement instance.

This method provides a concise, informative string representation of the Announcement instance, including its instrument class and requirement status.

Returns:

A string representation of the Announcement instance.

Return type:

str

Examples

>>> class SomeInstrument:
...     pass
...
>>> announcement = _Announcement(SomeInstrument)
>>> repr(announcement)
"_Announcement(instrument=<class '...SomeInstrument'>)"
domprob.announcements.decorators.announcement

alias of _Announcement

class domprob.announcements.instruments.Instruments(metadata)[source]

Bases: Generic[_InstruCls]

Manages and provides access to instrument classes for a decorated method’s metadata.

Parameters:

metadata (AnnouncementMetadata) – The metadata object managing the associated method’s metadata.

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta = metadata.AnnouncementMetadata(Foo.bar)
>>>
>>> # Access metadata instruments
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments(meta)
>>>
>>> instruments
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
__eq__(other)[source]

Checks equality between the current Instruments instance and another object.

This method determines whether the provided object is an instance of Instruments and whether their associated metadata are equal. Two Instruments instances ar considered equal if they manage the same AnnouncementMetadata.

Parameters:

other (Any) – The object to compare with the current Instruments instance.

Returns:

True if the provided object is an Instruments

instance and their metadata are equal.

Return type:

bool

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create Instruments instances for the same method
>>> from domprob.announcements.instruments import Instruments
>>> instruments1 = Instruments.from_method(Foo.bar)
>>> instruments2 = Instruments.from_method(Foo.bar)
>>>
>>> instruments1 == instruments2
True
>>> # Create Instruments instance for a different method
>>> class Baz:
...     def qux(self):
...         pass
...
>>> instruments3 = Instruments.from_method(Baz.qux)
>>> instruments1 == instruments3
False
>>> # Compare with an unrelated object
>>> instruments1 == "Not an Instruments instance"
False
__iter__()[source]

Iterates over all instruments.

Yields:

_InstrumentTupleClsGen

Instrument classes associated with

the method’s metadata.

Return type:

Generator[tuple[TypeVar(_InstruCls, bound= type[Any]), bool], None, None]

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create instruments handler for method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>>
>>> # Define an instrument
>>> class SomeInstrument:
...     pass
...
>>> instruments.record(SomeInstrument, True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> list(instruments)
[(<class 'domprob.announcements.instruments.SomeInstrument'>, True)]
__len__()[source]

Returns the number of instrument entries associated with the method’s metadata.

This method provides the total count of all instrument classes recorded in the metadata for the associated method.

Returns:

The total number of instrument classes recorded.

Return type:

int

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create instruments handler for method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>> # Initially, no instruments are recorded
>>> len(instruments)
0
>>> # Define an instrument
>>> class SomeInstrument:
...     pass
...
>>> # Record the instrument
>>> instruments.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> len(instruments)
1
__repr__()[source]

Returns a string representation of the Instruments instance.

Returns:

The string representation of the Instruments object.

Return type:

str

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create instruments handler for method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>> repr(instruments)
'Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))'
classmethod from_method(method)[source]

Creates an Instruments instance from a method.

Provides a convenient way to initialise an Instruments object directly from a method without explicitly creating an AnnoMetadata instance.

Parameters:

method (Callable[…, Any]) – The method for which the instruments should be managed.

Returns:

An Instruments instance for managing the

method’s metadata.

Return type:

Instruments

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create an Instruments instance directly from the method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>> instruments
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
is_required(instrument_cls)[source]

Checks if any recorded instrument of the same instrument type given is required.

Parameters:

instrument_cls (TInstruCls) – The instrument type to check against the method’s metadata.

Returns:

True if any instrument of the given type is marked

as required, otherwise False.

Return type:

bool

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create instruments handler for method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>>
>>> # Define an instrument class
>>> class SomeInstrument:
...     pass
...
>>> instruments.is_required(SomeInstrument)
False
>>> instruments.record(SomeInstrument, False)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> instruments.record(SomeInstrument, True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> instruments.is_required(SomeInstrument)
True
property non_req_instrums: Generator[_InstruCls, None, None]

Generator yielding supported instrument classes marked as not required in the method’s metadata.

Yields:

TInstrumentClsGen – Non-required instrument classes.

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create an Instruments instance directly from the method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>>
>>> # Define an instrument class
>>> class SomeInstrument:
...     pass
...
>>> # Add a required instrument
>>> instruments.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>>
>>> list(instruments.non_req_instrums)
[]
>>> instruments.record(SomeInstrument, required=False)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> list(instruments.non_req_instrums)
[<class '...SomeInstrument'>]
record(instrument, required)[source]

Adds an instrument entry to the method’s metadata.

Parameters:
  • instrument (type[BaseInstrument]) – The instrument class to add to the method’s metadata.

  • required (bool) – Whether the instrument is required.

Returns:

The updated Instruments instance.

Return type:

Instruments

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create instruments handler for the method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>>
>>> # Define an instrument class
>>> class SomeInstrument:
...     pass
...
>>> # Add a required instrument
>>> instruments.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> # Add a non-required instrument
>>> instruments.record(SomeInstrument, required=False)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
property req_instrums: Generator[_InstruCls, None, None]

Generator yielding supported instrument classes marked as required in the method’s metadata.

Yields:

TInstrumentClsGen – Required instrument classes.

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create an Instruments instance directly from the method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>>
>>> # Define an instrument class
>>> class SomeInstrument:
...     pass
...
>>> instruments.record(SomeInstrument, required=False)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> list(instruments.req_instrums)
[]
>>> instruments.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> list(instruments.req_instrums)
[<class '...SomeInstrument'>]
supported(required=None)[source]

Yields supported instrument classes filtered by requirement.

Parameters:

required (bool, optional) – If True, yields only required instruments. If False, yields only non-required instruments. If None, yields all instruments. Defaults to None.

Yields:

TInstrumentClsGen

Instrument classes that match the

filter criteria.

Return type:

Generator[TypeVar(_InstruCls, bound= type[Any]), None, None]

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create instruments handler for method
>>> from domprob.announcements.instruments import Instruments
>>> instruments = Instruments.from_method(Foo.bar)
>>>
>>> # Define an instrument class
>>> class SomeInstrument:
...     pass
...
>>> # Add instruments
>>> instruments.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>>
>>> # Filter instruments based on their requirement status
>>> list(instruments.supported(True))
[<class '...SomeInstrument'>]
>>> list(instruments.supported(False))
[]
>>> instruments.record(SomeInstrument, required=False)
Instruments(metadata=AnnouncementMetadata(method=<function Foo.bar at 0x...>))
>>> list(instruments.supported())
[<class '...SomeInstrument'>, <class '...SomeInstrument'>]
class domprob.announcements.metadata.AnnouncementMetadata(method)[source]

Bases: object

Stores and manages metadata for an instance method.

Parameters:

method (Callable[…, Any]) – The method for which the metadata is to be managed.

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta = metadata.AnnouncementMetadata(Foo.bar)
>>>
>>> meta
AnnouncementMetadata(method=<function Foo.bar at 0x...>)
METADATA_ATTR: str = '__announcement_metadata__'
__eq__(other)[source]

Equality operator to check if two AnnouncementMetadata instances are equivalent.

Parameters:

other (Any) – The object to compare with the current AnnouncementMetadata instance. Typically expected to be another AnnouncementMetadata object.

Returns:

Returns True if both operands reference the

metadata of the same instance method

Return type:

bool

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta_1 = metadata.AnnouncementMetadata(Foo.bar)
>>> meta_1 == "string"
False
>>> meta_2 = metadata.AnnouncementMetadata(Foo.bar)
>>> meta_1 == meta_2
True
>>>
>>> # Define an instrument
>>> class SomeInstrument:
...     pass
...
>>> meta_1.add(SomeInstrument, True)
AnnouncementMetadata(method=<function Foo.bar at 0x...>)
>>> meta_1 == meta_2  # Both reference the same method
True
__iter__()[source]

Iterates over all metadata entries recorded for the method.

Yields:

AnnoMetadataItem

Metadata items associated with the

method.

Return type:

Generator[AnnouncementMetadataEntry, None, None]

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta = metadata.AnnouncementMetadata(Foo.bar)
>>>
>>> # Define an instrument
>>> class SomeInstrument:
...     pass
...
>>> # Add entries to the metadata
>>> meta.add(SomeInstrument, True).add(SomeInstrument, False)
AnnouncementMetadata(method=<function Foo.bar at 0x...>)
>>>
>>> meta_iter = iter(meta)
>>> next(meta_iter)
AnnouncementMetadataEntry(instrument_cls=<class '...SomeInstrument'>, required=True)
>>> next(meta_iter)
AnnouncementMetadataEntry(instrument_cls=<class '...SomeInstrument'>, required=False)
__len__()[source]

Returns the number of metadata entries.

Returns:

The number of metadata entries recorded for the

method.

Return type:

int

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta = metadata.AnnouncementMetadata(Foo.bar)
>>>
>>> len(meta)
0
>>> # Define an instrument
>>> class SomeInstrument:
...     pass
...
>>> meta.add(SomeInstrument, required=True)
AnnouncementMetadata(method=<function Foo.bar at 0x...>)
>>> len(meta)
1
__repr__()[source]

Returns a string representation of the metadata instance.

Returns:

The string representation.

Return type:

str

Examples

>>> # Define a class with a method to decorate
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta = metadata.AnnouncementMetadata(Foo.bar)
>>> repr(meta)
'AnnouncementMetadata(method=<function Foo.bar at 0x...>)'
add(instrument, required)[source]

Adds an announcements metadata entry to the method.

Parameters:
  • instrument (type[BaseInstrument]) – The instrument class to add to the method’s metadata.

  • required (bool) – Whether the instrument is required.

Returns:

The updated metadata instance.

Return type:

AnnouncementMetadata

Examples

>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> meta = metadata.AnnouncementMetadata(Foo.bar)
>>>
>>> len(meta)
0
>>> # Define an instrument
>>> class SomeInstrument:
...     pass
...
>>> meta.add(SomeInstrument, required=True)
AnnouncementMetadata(method=<function Foo.bar at 0x...>)
>>> len(meta)
1
class domprob.announcements.metadata.AnnouncementMetadataEntry(instrument_cls, required)[source]

Bases: object

Represents metadata entry for an announcement’s method. Includes the instrument class and its requirement status.

Parameters:
  • instrument_cls (type[BaseInstrument]) – The type of instrument for which the announcements should be executed.

  • required (bool) – Whether the instrument instance at runtime is required or optional for the announcements. Defaults to True if not provided during instantiation.

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a method
>>> class Foo:
...     def bar(self):
...         pass
...
>>> # Create metadata for the method
>>> from domprob.announcements import metadata
>>> entry = metadata.AnnouncementMetadataEntry(SomeInstrument, required=False)
>>> entry
AnnouncementMetadataEntry(instrument_cls=<class '...SomeInstrument'>, required=False)
>>> entry.instrument_cls
<class '...SomeInstrument'>
>>> entry.required
False
__eq__(other)

Return self==value.

__repr__()

Return repr(self).

instrument_cls: type[Any]
required: bool
class domprob.announcements.method.AnnouncementMethod(meth, supp_instrums=None)[source]

Bases: BaseAnnouncementMethod, Generic[_PMeth, _RMeth]

Represents a decorated method with associated metadata.

This class acts as a wrapper and provides an interface to interact with the supported instruments of a method decorated with @announcement. It also facilitates partially binding runtime arguments to the method before method execution.

Parameters:

meth (Callable[P, R]) – The decorated method to be managed.

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an AnnouncementMethod instance
>>> bar_method = AnnouncementMethod(Foo.bar)
>>>
>>> bar_method
AnnouncementMethod(meth=<function Foo.bar at 0x...>)
__repr__()

Returns a string representation of the BaseAnnouncement instance.

Returns:

The string representation of the instance.

Return type:

str

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an AnnouncementMethod instance
>>> bar_method = BaseAnnouncementMethod(Foo.bar)
>>>
>>> repr(bar_method)
'BaseAnnouncementMethod(meth=<function Foo.bar at 0x...>)'
bind(cls_instance, *args, **kwargs)[source]

Binds passed parameters to the method, returning a partially bound version.

This method partially binds the provided runtime arguments. It returns a BoundAnnouncementMethod object that represents the partially bound method, which can later be executed with additional arguments if needed.

Parameters:
  • cls_instance (Any) – The class instance to bind. This is the self arg defined in instance methods.

  • *args (P.args) – Additional positional arguments to bind to the method.

  • **kwargs (P.kwargs) – Additional keyword arguments to bind to the method.

Returns:

A new wrapper representing a

partially bound method.

Return type:

BoundAnnouncementMethod

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an AnnouncementMethod instance
>>> bar_method = AnnouncementMethod(Foo.bar)
>>>
>>> # Create an instance of the class and instrument
>>> instrument_instance = SomeInstrument()
>>> foo = Foo()
>>>
>>> # Binds method with instrument instance
>>> args = (foo, instrument_instance)
>>> bound_method = bar_method.bind(*args)
>>> bound_method
BoundAnnouncementMethod(announce_meth=AnnouncementMethod(meth=<function Foo.bar at 0x...>), bound_params=<BoundArguments (self=<domprob.announcements.method.Foo object at 0x...>, instrument=<domprob.announcements.method.SomeInstrument object at 0x...>)>)
classmethod from_callable(meth)[source]

Creates an AnnouncementMethod instance from a callable if it supports instruments.

This class method checks if the provided callable (meth) has associated metadata for supported instruments. If it does, an AnnouncementMethod instance is created and returned. Otherwise, None is returned.

Parameters:

meth (Callable[_PMeth, _RMeth]) – The method or function to be wrapped as an AnnouncementMethod.

Returns:

  • An instance of AnnouncementMethod if the callable has associated metadata.

  • None if the callable does not support instruments.

Return type:

AnnouncementMethod[_PMeth, _RMeth] | None

Example

>>> from domprob import announcement
>>>
>>> class SomeInstrument:
...     pass
...
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         print(f"Instrument: {instrument}")
...
>>> # Create an AnnouncementMethod instance from a method
>>> announce_meth = AnnouncementMethod.from_callable(Foo.bar)
>>> assert isinstance(announce_meth, AnnouncementMethod)
>>> print(announce_meth)
AnnouncementMethod(meth=<function Foo.bar at 0x...>)
>>> # Attempt to create an AnnouncementMethod from a method without metadata
>>> def no_announcement_method():
...     pass
...
>>> assert AnnouncementMethod.from_callable(no_announcement_method) is None
property meth: Callable[[_PMeth], _RMeth]

Returns the decorated method.

This method represents the underlying method associated with the announcement.

Returns:

The method associated with this

announcement.

Return type:

Callable[_PMeth, _RMeth]

Examples

>>> from domprob.announcements.method import BaseAnnouncementMethod
>>>
>>> def example_method():
...     pass
...
>>> base = BaseAnnouncementMethod(example_method)
>>> base.meth
<function example_method at 0x...>
property supp_instrums: Instruments

Returns the supported instruments for this method.

This property retrieves the metadata associated with the decorated method, indicating which instruments are supported.

Returns:

An Instruments object containing metadata

about the method’s supported instruments.

Return type:

Instruments

Examples

>>> from domprob.announcements.method import BaseAnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> def example_method(instrument: SomeInstrument) -> None:
...     pass
...
>>> base = BaseAnnouncementMethod(example_method)
>>> base.supp_instrums
Instruments(metadata=AnnouncementMetadata(method=<function example_method at 0x...>))
class domprob.announcements.method.AnnouncementMethodBinder(announce_meth)[source]

Bases: object

Handles argument binding for an AnnouncementMethod.

This class provides utilities for binding arguments to the method signature of an AnnouncementMethod, both partially and fully. It ensures that the provided arguments match the method signature and raises an exception if binding fails.

announce_meth

The method wrapper instance for which arguments will be bound.

Type:

AnnouncementMethod

Parameters:

announce_meth (AnnouncementMethod) – The method wrapper instance for which arguments will be bound.

Examples

>>> from collections import OrderedDict
>>> from domprob.announcements.method import (
...     AnnouncementMethod, AnnouncementMethodBinder
... )
>>>
>>> class Foo:
...     def bar(self, x: int = 5) -> None:
...         pass
>>>
>>> meth = AnnouncementMethod(Foo.bar)
>>> binder = AnnouncementMethodBinder(meth)
>>> binder
AnnouncementMethodBinder(announce_meth=AnnouncementMethod(meth=<function Foo.bar at 0x...>))
__repr__()[source]

Returns a string representation of the AnnouncementMethodBinder instance.

Returns:

A string representation of the instance.

Return type:

str

Examples

>>> def example_method():
...     pass
...
>>> method = AnnouncementMethod(example_method)
>>> binder = AnnouncementMethodBinder(method)
>>> repr(binder)
'AnnouncementMethodBinder(announce_meth=AnnouncementMethod(meth=<function example_method at 0x...>))'
static _apply_defaults(b_params)[source]

Applies default values to bound parameters.

This method ensures that any parameters with default values that were not explicitly provided during binding are assigned their default values.

Parameters:

b_params (BoundArguments) – The bound arguments for the method.

Returns:

The updated bound arguments with defaults

applied.

Return type:

BoundArguments

Examples

>>> from collections import OrderedDict
>>> from domprob.announcements.method import (
...     AnnouncementMethod, AnnouncementMethodBinder
... )
>>>
>>> class Foo:
...     def bar(self, x: int = 5) -> None:
...         pass
>>>
>>> meth = AnnouncementMethod(Foo.bar)
>>> binder = AnnouncementMethodBinder(meth)
>>>
>>> signature = inspect.signature(Foo.bar)
>>> b_arguments = BoundArguments(signature, OrderedDict())
>>> b_arguments
<BoundArguments ()>
>>> binder._apply_defaults(b_arguments)
<BoundArguments (x=5)>
_bind_partial(*args, **kwargs)[source]

Partially binds arguments to the method signature.

This method allows binding a subset of the arguments required by the method. It does not enforce that all required parameters are provided.

Parameters:
  • *args (Any) – Positional arguments to bind.

  • **kwargs (Any) – Keyword arguments to bind.

Returns:

The partially bound arguments.

Return type:

BoundArguments

Raises:

PartialBindException – If the arguments cannot be bound to the method.

Examples

>>> from collections import OrderedDict
>>> from domprob.announcements.method import (
...     AnnouncementMethod, AnnouncementMethodBinder
... )
>>>
>>> class Foo:
...     def bar(self, x: int, bool_: bool = True) -> None:
...         pass
>>>
>>> meth = AnnouncementMethod(Foo.bar)
>>> binder = AnnouncementMethodBinder(meth)
>>>
>>> b_arguments = binder._bind_partial(5, bool_=False)
>>> b_arguments
<BoundArguments (self=5, bool_=False)>
>>> try:
...     _ = binder._bind_partial(5, y=10, bool_=False)
... except PartialBindException:
...     print("Failed partial binding")
...
Failed partial binding
_infer_ann_params(params)[source]
Return type:

Optional[Generator[Parameter, Any, None]]

_infer_pos_params(params)[source]
Return type:

Generator[Parameter, None, None]

_instr: str = 'instrument'
_rn(param)[source]
Return type:

Parameter

bind(*args, **kwargs)[source]

Fully binds arguments to the method signature and returns a bound method.

This method ensures that all required arguments for the method are bound. It applies default values where applicable and returns a BoundAnnouncementMethod instance representing the method with its bound parameters.

Parameters:
  • *args (Any) – Positional arguments to bind.

  • **kwargs (Any) – Keyword arguments to bind.

Returns:

A wrapper around the method with

bound arguments.

Return type:

BoundAnnouncementMethod

Raises:

PartialBindException – If binding fails due to missing or incorrect arguments.

Examples

>>> from collections import OrderedDict
>>> from domprob.announcements.method import (
...     AnnouncementMethod, AnnouncementMethodBinder
... )
>>>
>>> class Foo:
...     def bar(self, x: int, bool_: bool = True) -> None:
...         pass
>>>
>>> meth = AnnouncementMethod(Foo.bar)
>>> binder = AnnouncementMethodBinder(meth)
>>>
>>> bound_meth = binder.bind(5)
>>> bound_meth
BoundAnnouncementMethod(announce_meth=AnnouncementMethod(meth=<function Foo.bar at 0x...>), bound_params=<BoundArguments (self=5, bool_=True)>)
>>> try:
...     _ = binder._bind_partial(5, y=10)
... except PartialBindException:
...     print("Failed partial binding")
...
Failed partial binding
get_signature()[source]

Retrieves the method signature of the wrapped AnnouncementMethod.

If an ‘instrument’ argument is not defined, manipulation occurs before binding to enable instrument access on the BoundAnnouncementMethod wrapper class. The parameters in the method signature will change so that a parameter is renamed to ‘instrument’. In priority order, an attempt is made to manipulate the parameters in the following ways:

  1. The parameters type hint annotations will be inspected. It will check if the type hint of an argument defined in the method signature is the same typemor a parent type of that defined in all announcement decorators that wrap the associated method.

    Warning

    If multiple parameters exist that match the type hinting criteria above, the leftmost parameter will take precedence.

  2. Fallback. If neither an ‘instrument’ parameter is defined or a parameter with the correct type hint annotations are defined, we will assign the first parameter (exc. ‘self’) as the ‘instrument’ parameter.

Returns:

The signature of the decorated method.

Return type:

inspect.Signature

Examples

>>> def example_method(x: int, y: str) -> None:
...     pass
...
>>> method = AnnouncementMethod(example_method)
>>> binder = AnnouncementMethodBinder(method)
>>> binder.get_signature()
<Signature (instrument: 'int', y: 'str') -> 'None'>
class domprob.announcements.method.BaseAnnouncementMethod(meth, supp_instrums=None)[source]

Bases: Generic[_PMeth, _RMeth]

Base class for announcement-related methods.

This class provides shared functionality for both AnnouncementMethod and BoundAnnouncementMethod, including caching and retrieval of supported instruments.

Parameters:

meth (Callable) – The method associated with this announcement.

__repr__()[source]

Returns a string representation of the BaseAnnouncement instance.

Returns:

The string representation of the instance.

Return type:

str

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an AnnouncementMethod instance
>>> bar_method = BaseAnnouncementMethod(Foo.bar)
>>>
>>> repr(bar_method)
'BaseAnnouncementMethod(meth=<function Foo.bar at 0x...>)'
property meth: Callable[[_PMeth], _RMeth]

Returns the decorated method.

This method represents the underlying method associated with the announcement.

Returns:

The method associated with this

announcement.

Return type:

Callable[_PMeth, _RMeth]

Examples

>>> from domprob.announcements.method import BaseAnnouncementMethod
>>>
>>> def example_method():
...     pass
...
>>> base = BaseAnnouncementMethod(example_method)
>>> base.meth
<function example_method at 0x...>
property supp_instrums: Instruments[source]

Returns the supported instruments for this method.

This property retrieves the metadata associated with the decorated method, indicating which instruments are supported.

Returns:

An Instruments object containing metadata

about the method’s supported instruments.

Return type:

Instruments

Examples

>>> from domprob.announcements.method import BaseAnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> def example_method(instrument: SomeInstrument) -> None:
...     pass
...
>>> base = BaseAnnouncementMethod(example_method)
>>> base.supp_instrums
Instruments(metadata=AnnouncementMetadata(method=<function example_method at 0x...>))
class domprob.announcements.method.BoundAnnouncementMethod(announce_meth, bound_params)[source]

Bases: BaseAnnouncementMethod, Generic[_PMeth, _RMeth]

Represents a partially bound method with associated metadata.

This class is used to wrap a method that has been partially bound with runtime arguments, including the instrument parameter. It facilitates logic, like validation, on the method with the runtime parameters before the method is executed.

Parameters:
  • announce_meth (AnnouncementMethod) – Original method wrapper that’s had parameters bound.

  • bound_params (inspect.BoundArguments) – Parameters that are bound to a method.

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an BoundAnnouncementMethod instance
>>> from collections import OrderedDict
>>> announce_meth = AnnouncementMethod(Foo.bar)
>>> sig = inspect.signature(Foo.bar)
>>> b_args = BoundArguments(sig, OrderedDict())
>>> # Bind the arguments correctly
>>> bound = sig.bind_partial(Foo(), SomeInstrument())
>>> b_args.arguments = bound.arguments
>>> bound_method = BoundAnnouncementMethod(announce_meth, b_args)
>>>
>>> bound_method
BoundAnnouncementMethod(announce_meth=AnnouncementMethod(meth=<function Foo.bar at 0x...>), bound_params=<BoundArguments (self=<domprob.announcements.method.Foo object at 0x...>, instrument=<domprob.announcements.method.SomeInstrument object at 0x...>)>)
__repr__()[source]

Returns a string representation of the InstrumentBoundAnnoMethod instance.

Returns:

The string representation.

Return type:

str

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> str:
...         return "Executed"
...
>>> # Create an BoundAnnouncementMethod instance
>>> from collections import OrderedDict
>>> announce_meth = AnnouncementMethod(Foo.bar)
>>> sig = inspect.signature(Foo.bar)
>>> b_args = BoundArguments(sig, OrderedDict())
>>> # Bind the arguments correctly
>>> bound = sig.bind_partial(Foo(), SomeInstrument())
>>> b_args.arguments = bound.arguments
>>> bound_method = BoundAnnouncementMethod(announce_meth, b_args)
>>>
>>> repr(bound_method)
'BoundAnnouncementMethod(announce_meth=AnnouncementMethod(meth=<function Foo.bar at 0x...>), bound_params=<BoundArguments (self=<domprob.announcements.method.Foo object at 0x...>, instrument=<domprob.announcements.method.SomeInstrument object at 0x...>)>)'
execute()[source]

Executes the bound method.

Returns:

The return value of the executed method.

Return type:

R

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> str:
...         return "Executed"
...
>>> # Create an BoundAnnouncementMethod instance
>>> from collections import OrderedDict
>>> announce_meth = AnnouncementMethod(Foo.bar)
>>> sig = inspect.signature(Foo.bar)
>>> b_args = BoundArguments(sig, OrderedDict())
>>> # Bind the arguments correctly
>>> bound = sig.bind_partial(Foo(), SomeInstrument())
>>> b_args.arguments = bound.arguments
>>> bound_method = BoundAnnouncementMethod(announce_meth, b_args)
>>>
>>> bound_method.execute()
'Executed'
property instrument: Any | None

Returns the runtime instrument instance argument bound to the method.

Returns:

The bound instrument instance.

Return type:

BaseInstrument

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an BoundAnnouncementMethod instance
>>> import inspect
>>> from collections import OrderedDict
>>> from domprob.announcements.method import (
...     AnnouncementMethod, BoundAnnouncementMethod
... )
>>>
>>> announce_meth = AnnouncementMethod(Foo.bar)
>>> sig = inspect.signature(Foo.bar)
>>> b_args = BoundArguments(sig, OrderedDict())
>>> # Bind the arguments correctly
>>> bound = sig.bind_partial(Foo(), SomeInstrument())
>>> b_args.arguments = bound.arguments
>>> bound_method = BoundAnnouncementMethod(announce_meth, b_args)
>>>
>>> bound_method.instrument
<....SomeInstrument object at 0x...>
property meth: Callable[[_PMeth], _RMeth]

Returns the decorated method.

This method represents the underlying method associated with the announcement.

Returns:

The method associated with this

announcement.

Return type:

Callable[_PMeth, _RMeth]

Examples

>>> from domprob.announcements.method import BaseAnnouncementMethod
>>>
>>> def example_method():
...     pass
...
>>> base = BaseAnnouncementMethod(example_method)
>>> base.meth
<function example_method at 0x...>
property params: BoundArguments

Returns the bound arguments applied to the method.

Returns:

Bound arguments applied to the

method.

Return type:

inspect.BoundArguments

Examples

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an BoundAnnouncementMethod instance
>>> import inspect
>>> from collections import OrderedDict
>>> from domprob.announcements.method import (
...     AnnouncementMethod, BoundAnnouncementMethod
... )
>>>
>>> announce_meth = AnnouncementMethod(Foo.bar)
>>> sig = inspect.signature(Foo.bar)
>>> b_args = BoundArguments(sig, OrderedDict())
>>> # Bind the arguments correctly
>>> bound = sig.bind_partial(Foo(), SomeInstrument())
>>> b_args.arguments = bound.arguments
>>> bound_method = BoundAnnouncementMethod(announce_meth, b_args)
>>>
>>> bound_method.instrument
<....SomeInstrument object at 0x...>
property supp_instrums: Instruments

Returns the supported instruments for this method.

This property retrieves the metadata associated with the decorated method, indicating which instruments are supported.

Returns:

An Instruments object containing metadata

about the method’s supported instruments.

Return type:

Instruments

Examples

>>> from domprob.announcements.method import BaseAnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> def example_method(instrument: SomeInstrument) -> None:
...     pass
...
>>> base = BaseAnnouncementMethod(example_method)
>>> base.supp_instrums
Instruments(metadata=AnnouncementMetadata(method=<function example_method at 0x...>))
validate()[source]

Validates the bound method using the validation orchestrator.

This method ensures that all runtime arguments and metadata associated with the bound method meet the specified validation criteria. If validation fails, an appropriate exception is raised.

Raises:

AnnouncementValidationException – If any validation rule fails.

Examples

Return type:

None

>>> class SomeInstrument:
...     pass
...
>>> # Define a class with a decorated method
>>> from domprob import announcement
>>>
>>> class Foo:
...     @announcement(SomeInstrument)
...     def bar(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> # Create an BoundAnnouncementMethod instance
>>> from collections import OrderedDict
>>> announce_meth = AnnouncementMethod(Foo.bar)
>>> sig = inspect.signature(Foo.bar)
>>> b_args = BoundArguments(sig, OrderedDict())
>>> # Bind the arguments correctly
>>> bound = sig.bind_partial(Foo(), SomeInstrument())
>>> b_args.arguments = bound.arguments
>>> bound_method = BoundAnnouncementMethod(announce_meth, b_args)
>>>
>>> # Validate the bound method
>>> bound_method.validate()
exception domprob.announcements.method.PartialBindException(meth, e)[source]

Bases: AnnouncementException

Exception raised when binding arguments to a method’s signature fails.

This exception is used to handle errors that occur during partial argument binding, including missing required parameters.

meth

The method whose arguments failed to bind.

Type:

AnnouncementMethod

e

The original exception that caused the failure.

Type:

Exception

__repr__()[source]

Returns a string representation of the PartialBindException instance.

The string includes the method and the original exception.

Returns:

A string representation of the exception instance.

Return type:

str

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Constructs the error message for the exception.

The message includes the name of the method and the details of the original exception.

Returns:

A descriptive error message for the exception.

Return type:

str

with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception domprob.announcements.exceptions.AnnouncementException[source]

Bases: DomprobException

Base exception class for errors related to the @announcement functionality.

This serves as a parent class for all exceptions raised within the announcements framework.

__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

Validation

class domprob.announcements.validation.base_validator.BaseValidator(next_=None)[source]

Bases: ABC

Abstract base class for creating validators in a chain of responsibility pattern.

This class defines a structure for implementing validation logic where each validator can perform a specific validation task and optionally pass the validation responsibility to the next validator in the chain. Subclasses must override the validate method to provide specific validation logic.

Parameters:

next (BaseValidator | None, optional) – The next validator in the chain. Defaults to None, indicating no further validation.

next_

Holds the reference to the next validator in the chain or None if this is the last validator.

Type:

BaseValidator | None

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.method import AnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         if not method.instrument:
...             raise ValueError("Instrument is required")
...         print("Validation successful")
...         super().validate(method)
...
>>> # Mock setup for example
>>> class SomeInstrument:
...     pass
...
>>> class Cls:
...     def method(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Cls.method)
>>> bound_meth = meth.bind(Cls(), SomeInstrument())
>>> validator = ExampleValidator()
>>> validator.validate(bound_meth)
Validation successful
>>> # Chaining validators
>>> validator1 = ExampleValidator()
>>> validator2 = ExampleValidator(next_=validator1)
>>> validator2.validate(bound_meth)
Validation successful
Validation successful
__repr__()[source]

Returns a string representation of the validator.

This includes the class name and the next_ validator in the chain, making it easier to debug and inspect validator chains.

Returns:

A string representation of the validator.

Return type:

str

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>> class ExampleValidator(BaseValidator):
...     def validate(self, meth: BoundAnnouncementMethod) -> None:
...         pass
...
>>> validator = ExampleValidator(next_=None)
>>> repr(validator)
'ExampleValidator(next_=None)'
>>> chained_validator = ExampleValidator(next_=validator)
>>> repr(chained_validator)
'ExampleValidator(next_=ExampleValidator(next_=None))'
_abc_impl = <_abc._abc_data object>
abstract validate(b_meth)[source]

Validates a BoundAnnouncementMethod instance.

This method performs the validation logic for the current validator and delegates to the next validator in the chain if one is defined. Subclasses must implement the specific validation logic by overriding this method.

Parameters:

b_meth (BoundAnnouncementMethod) – Bound method wrapper to validate.

Raises:
  • ValidatorException – If the validation fails.

  • Exception – If an unexpected error occurs during validation.

Return type:

None

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.method import AnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, meth: BoundAnnouncementMethod) -> None:
...         if not meth.instrument:
...             raise ValidatorException("Instrument is required")
...         print("Validation successful")
...         super().validate(meth)
...
>>> # Mock setup for example
>>> class SomeInstrument:
...     pass
...
>>> class Cls:
...     def method(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Cls.method)
>>> bound_meth = meth.bind(Cls(), SomeInstrument())
>>> validator = ExampleValidator()
>>> validator.validate(bound_meth)
Validation successful
exception domprob.announcements.validation.base_validator.ValidatorException[source]

Bases: AnnouncementException

Exception raised when a validation error occurs in a validator.

This exception is used to indicate that validation has failed during the execution of a validation chain. It inherits from AnnouncementException to ensure consistency in exception handling across the package.

__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class domprob.announcements.validation.chain.ValidationChain(base, *link_validators, validator_context=None)[source]

Bases: Generic[_ChainLink], MutableSequence[_ChainLink]

A class that represents a chain of validators for validating links.

The ValidationChain class manages a collection of validators that can sequentially validate links. It provides methods to add, insert, and remove validators, as well as to execute validations in a structured manner. The chain ensures type consistency and supports extensibility.

base

The expected base type for all links in the chain.

Type:

type

Parameters:
  • base (type) – The base type that all links in the chain must conform to.

  • *link_validators (ABCLinkValidator) – A list of validators in the chain.

  • validator_context (ABCLinkValidatorContext, optional) – The context in which the validators are validated.

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>> class ExampleValidator(ABCLinkValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> chain
ValidationChain(base='BaseValidator')
__contains__(item)[source]

Checks if a specific validator exists in the validation chain.

Parameters:

item (object) – The item to check for.

Returns:

True if the validator is in the chain, False otherwise.

Return type:

bool

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> "" in chain
False
>>> validator = ExampleValidator()
>>> chain.append(validator)
>>> validator in chain
True
__eq__(other)[source]

Compares two validation chains for equality.

Two validation chains are considered equal if they have the same base type and contain the same validators in the same order.

Parameters:

other (object) – The object to compare with.

Returns:

True if the chains are equal, False otherwise.

Return type:

bool

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain_1 = ValidationChain(BaseValidator)
>>> chain_2 = ValidationChain(BaseValidator)
>>> chain_1 == chain_2
True
>>> chain_1 == ""
False
>>> chain_1.append(ExampleValidator())
>>> chain_1 == chain_2
False
__iter__()[source]

Returns an iterator over the validators in the validation chain.

This method allows the validation chain to be iterated over directly, returning each validator in sequence.

Returns:

An iterator over the

validators.

Return type:

Iterator[ABCLinkValidator]

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> chain.append(ExampleValidator())
>>> chain.append(ExampleValidator())
>>>
>>> for link in chain:
...     repr(link)
...
'ExampleValidator(next_=ExampleValidator(next_=None))'
'ExampleValidator(next_=None)'
__len__()[source]

Returns the number of validators in the validation chain.

This method allows the use of the len() function to determine how many validators are in the chain.

Returns:

The number of validators in the chain.

Return type:

int

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> len(chain)
0
>>> chain.append(ExampleValidator())
>>> len(chain)
1
__repr__()[source]

Returns a string representation of the ValidationChain instance.

Returns:

A string representation of the ValidationChain.

Return type:

str

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> chain = ValidationChain(BaseValidator)
>>> repr(chain)
"ValidationChain(base='BaseValidator')"
_abc_impl = <_abc._abc_data object>
_delete_single_item(index, /)[source]

Handles deletion for a single element.

Return type:

None

_delete_slice_items(index, /)[source]
Return type:

None

Return type:

None

_set_single_item(index, link, /)[source]
Return type:

None

_set_slice_items(index, links, /)[source]
Return type:

None

append(value)[source]

Adds a validator to the end of the validation chain.

This method allows adding a new validator to the chain, ensuring it follows the chain’s base type requirements.

Parameters:

value (BaseValidator) – The validator to add to the chain.

Raises:

TypeError – If the provided validator is not an instance of self.base.

Examples

Return type:

None

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> chain.append(ExampleValidator())
clear()[source]

Removes all validators from the validation chain.

Return type:

None

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> chain.append(ExampleValidator())
>>> chain.append(ExampleValidator())
>>> len(chain)
2
>>> chain.clear()
>>> len(chain)
0
count(value) integer -- return number of occurrences of value
extend(values)[source]

Adds multiple validators to the end of the validation chain.

This method appends a list of validators to the chain. It ensures that each validator conforms to the chain’s base type requirements.

Parameters:

values (Iterable[BaseValidator]) – An iterable of validators to add to the chain.

Raises:

TypeError – If any of the provided validators are not instances of self.base.

Examples

Return type:

None

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> chain.extend([ExampleValidator(), ExampleValidator()])
>>> len(chain)
2
index(value[, start[, stop]]) integer -- return first index of value.

Raises ValueError if the value is not present.

Supporting start and stop arguments is optional, but recommended.

insert(index, value)[source]

Inserts a validator at the specified index in the validation chain.

This method adds a new validator at a specific position in the chain, shifting subsequent validators to the right.

Parameters:
  • index (int) – The position to insert the validator.

  • value (BaseValidator) – The validator to insert.

Raises:

TypeError – If the provided validator is not an instance of self.base.

Examples

Return type:

None

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, method: BoundAnnouncementMethod) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> chain.insert(0, ExampleValidator())
>>> len(chain)
1
pop([index]) item -- remove and return item at index (default last).

Raise IndexError if list is empty or index is out of range.

remove(value)

S.remove(value) – remove first occurrence of value. Raise ValueError if the value is not present.

reverse()

S.reverse() – reverse IN PLACE

validate_chain(*args, **kwargs)[source]

Validates the entire chain to ensure it meets the base type requirements.

This method checks that all validators in the chain are valid and comply with the chain’s expected rules. It raises an exception if any validator is invalid.

Return type:

None

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>>
>>> chain = ValidationChain(BaseValidator)
>>> try:
...     chain.validate_chain()
... except EmptyChainException as e:
...     print(e)
...
Nothing to validate, no links added to chain 'ValidationChain(base='BaseValidator')'
class domprob.announcements.validation.chain_validation.ABCLinkValidator(chain)[source]

Bases: ABC

Abstract base class for validators in a validation chain.

This class defines the structure for implementing validators that perform specific checks on links within a validation chain.

chain

The validation chain associated with this validator. It provides context for the validation process.

Type:

ValidationChain

Parameters:

chain (ValidationChain) – The validation chain to associate with this validator.

Examples

>>> from domprob.announcements.validation.chain import ABCLinkValidator
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(ABCLinkValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
__repr__()[source]

Returns a string representation of the validator.

Returns:

A string representation of the validator, including

its class name and the validation chain it belongs to.

Return type:

str

Examples

>>> from domprob.announcements.validation.chain import ABCLinkValidator
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(ABCLinkValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> validator = ExampleValidator(ValidationChain(BaseValidator))
>>> repr(validator)
"ExampleValidator(ValidationChain(base='BaseValidator'))"
_abc_impl = <_abc._abc_data object>
abstract validate(link)[source]

Validates a single link in the validation chain.

This abstract method must be implemented by subclasses to define specific validation logic.

Parameters:

link (_ChainLink) – The link to validate.

Raises:

NotImplementedError – If the subclass does not implement this method.

Return type:

None

class domprob.announcements.validation.chain_validation.ABCLinkValidatorContext(chain, *validators)[source]

Bases: ABC

Abstract base class for context-aware link validators in a validation chain.

This class provides an interface for validators that need additional context about the validation chain during the validation process. It enforces the implementation of the validate method, allowing subclasses to perform more sophisticated validations that depend on the state of the chain.

chain

The validation chain associated with this validator. It provides context for the validation process.

Type:

ValidationChain

Parameters:

chain (ValidationChain) – The validation chain to associate with this context-aware validator.

Examples

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>>
>>> class ExampleContext(ABCLinkValidatorContext):
...     def add_validators(self, *validators: type[BaseValidator]) -> None:
...         pass
...
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> validator_context = ExampleContext(chain)
>>> validator_context.validate(ExampleValidator())
__repr__()[source]

Returns a string representation of the context-aware validator.

Returns:

A string representation of the validator, showing the

class name and the validation chain it is associated with.

Return type:

str

Examples

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext,
...     BaseValidator,
...     ValidationChain
... )
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> class ExampleContext(ABCLinkValidatorContext):
...     def add_validators(self, *validators: type[BaseValidator]) -> None:
...         pass
...
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> chain = ValidationChain(ExampleValidator)
>>> context = ExampleContext(chain)
>>> repr(context)
"ExampleContext(chain=ValidationChain(base='ExampleValidator'))"
_abc_impl = <_abc._abc_data object>
abstract add_validators(*validators)[source]

Adds one or more validators to the validation chain.

This abstract method is designed to allow additional validators to be dynamically added to the validation chain during runtime. Each validator is appended to the chain, enabling customisation and extensibility of the validation process.

Parameters:

*validators (ABCLinkValidator) – One or more validator instances to add to the validation chain.

Return type:

None

Examples

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> class ExampleContext(ABCLinkValidatorContext):
...     def add_validators(self, *validators: type[BaseValidator]) -> None:
...         pass
...
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> chain = ValidationChain(ExampleValidator)
>>> context = ExampleContext(chain)
>>> context.add_validators(ExampleValidator, ExampleValidator)
abstract validate(link)[source]

Abstract method to validate a link in the chain using additional context.

This method must be implemented by subclasses to provide logic for validating a link with additional contextual information. This allows the validator to account for dynamic rules or states during validation.

Parameters:

link (_ChainLink) – The link to validate.

Raises:

NotImplementedError – If a subclass does not implement this method.

Examples

Return type:

None

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>>
>>> class ExampleContext(ABCLinkValidatorContext):
...     def add_validators(self, *validators: type[BaseValidator]) -> None:
...         pass
...
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> chain = ValidationChain(ExampleValidator)
>>> validator_context = ExampleContext(chain)
>>> validator_context.validate(ExampleValidator())
exception domprob.announcements.validation.chain_validation.EmptyChainException(chain)[source]

Bases: ValidationChainException

Exception raised when a validation chain is empty.

This exception indicates that no validators have been added to a validation chain, which prevents the chain from performing any meaningful validation.

Parameters:

chain (ValidationChain) – The empty validation chain.

chain

The empty validation chain.

Type:

ValidationChain

Examples

>>> from domprob.exceptions import EmptyChainException
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> try:
...     raise EmptyChainException(ValidationChain(BaseValidator))
... except EmptyChainException as e:
...     print(e)
...
Nothing to validate, no links added to chain 'ValidationChain(base='BaseValidator')'
__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Returns the error message associated with the exception.

Returns:

The error message describing the empty validation

chain issue.

Return type:

str

Examples

>>> from domprob.exceptions import EmptyChainException
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> exc = EmptyChainException(ValidationChain(BaseValidator))
>>> exc.msg
"Nothing to validate, no links added to chain 'ValidationChain(base='BaseValidator')'"
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception domprob.announcements.validation.chain_validation.InvalidLinkException(link, expected_type)[source]

Bases: ValidationChainException

Exception raised when an invalid link is added to a validation chain.

This exception is used to indicate that a link in the validation chain does not meet the required criteria or fails validation. It provides detailed information about the invalid link and the expected type.

The invalid link that caused the exception.

Type:

Any

expected_type

The expected type for valid links in the chain.

Type:

type[Any]

Parameters:
  • link (Any) – The link object that is invalid.

  • expected_type (type[Any]) – The expected type for links in the validation chain.

Examples

>>> from domprob.exceptions import InvalidLinkException
>>>
>>> def raise_invalid_link():
...     raise InvalidLinkException("InvalidLink", expected_type=int)
...
>>> try:
...     raise_invalid_link()
... except InvalidLinkException as e:
...     print(str(e))
Invalid link of type 'str', expected type 'int'
__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Constructs a detailed error message for the exception.

This property dynamically generates a human-readable string that describes the invalid link and the expected type.

Returns:

A string describing the invalid link and its expected

type.

Return type:

str

Examples

>>> exc = InvalidLinkException("InvalidLink", expected_type=int)
>>> exc.msg
"Invalid link of type 'str', expected type 'int'"
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception domprob.announcements.validation.chain_validation.LinkExistsException(link, chain)[source]

Bases: ValidationChainException

Exception raised when a duplicate link is added to a validation chain.

This exception is used to indicate that the specified link already exists in the validation chain and duplicates are not allowed. It provides details about the duplicate link and the chain where the conflict occurred.

Parameters:
  • link (Any) – The duplicate link that caused the exception.

  • chain (ValidationChain) – The validation chain where the duplicate was found.

The duplicate link.

Type:

Any

chain

The chain where the duplicate was detected.

Type:

ValidationChain

Examples

>>> from domprob.exceptions import LinkExistsException
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> try:
...     raise LinkExistsException("DuplicateLink", chain=ValidationChain(BaseValidator))  # type: ignore
... except LinkExistsException as e:
...     print(e)
...
Link ''DuplicateLink'' already exists in chain 'ValidationChain(base='BaseValidator')'
__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Constructs a detailed error message indicating a duplicate link in the validation chain.

Returns:

A message indicating the duplicate link and the

affected chain.

Return type:

str

Examples

>>> from domprob.exceptions import LinkExistsException
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> chain = ValidationChain(base=BaseValidator)
>>> exc = LinkExistsException("DuplicateLink", chain)  # type: ignore
>>> exc.msg
"Link ''DuplicateLink'' already exists in chain 'ValidationChain(base='BaseValidator')'"
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class domprob.announcements.validation.chain_validation.LinkTypeValidator(chain)[source]

Bases: ABCLinkValidator

Validator to ensure that links in the validation chain are of the expected type.

This validator checks whether each link added to the validation chain is an instance of the chain’s base type. If a link does not match the expected type, it raises an InvalidLinkException. This ensures type safety and consistency within the chain.

chain

The validation chain this validator is associated with.

Type:

ValidationChain

Examples

>>> from domprob.announcements.validation.chain_validation import LinkTypeValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> validator = LinkTypeValidator(ValidationChain(BaseValidator))
>>>
>>> try:
...     validator.validate(123)  # type: ignore
... except InvalidLinkException as e:
...     print(e)
...
Invalid link of type 'int', expected type 'BaseValidator'
__repr__()

Returns a string representation of the validator.

Returns:

A string representation of the validator, including

its class name and the validation chain it belongs to.

Return type:

str

Examples

>>> from domprob.announcements.validation.chain import ABCLinkValidator
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(ABCLinkValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> validator = ExampleValidator(ValidationChain(BaseValidator))
>>> repr(validator)
"ExampleValidator(ValidationChain(base='BaseValidator'))"
_abc_impl = <_abc._abc_data object>
validate(link)[source]

Validates that the provided link is of the expected type.

This method ensures that the given link is an instance of the chain’s base type. If the link is not of the expected type, it raises an InvalidLinkException.

Parameters:

link (_ChainLink) – The link to validate.

Raises:

InvalidLinkException – If the link is not of the expected type.

Return type:

None

Examples

>>> from domprob.announcements.validation.chain_validation import LinkTypeValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> validator = LinkTypeValidator(ValidationChain(BaseValidator))
>>>
>>> try:
...     validator.validate(123)  # type: ignore
... except InvalidLinkException as e:
...     print(e)
...
Invalid link of type 'int', expected type 'BaseValidator'
class domprob.announcements.validation.chain_validation.LinkValidatorContext(chain, *validators)[source]

Bases: ABCLinkValidatorContext

Concrete implementation of a context-aware link validator.

The LinkValidatorContext class extends ABCLinkValidatorContext to provide validation logic for links in a chain, utilising additional contextual information. It allows flexible and dynamic validation of links, depending on the state of the chain or external conditions.

chain

The validation chain associated with this context-aware validator.

Type:

ValidationChain

Parameters:

chain (ValidationChain) – The validation chain to associate with the validator.

Examples

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>> from domprob.announcements.validation.chain_validation import InvalidLinkException
>>>
>>> class ExampleLink:
...     pass
...
>>> chain = ValidationChain(BaseValidator)
>>> validator_context = LinkValidatorContext(chain)
>>> try:
...     validator_context.validate("invalid_link")  # type: ignore
... except InvalidLinkException as e:
...     print(e)
Invalid link of type 'str', expected type 'BaseValidator'
DEFAULT_VALIDATORS: tuple[type[ABCLinkValidator], ...] = (<class 'domprob.announcements.validation.chain_validation.LinkTypeValidator'>, <class 'domprob.announcements.validation.chain_validation.UniqueLinkValidator'>)
__repr__()[source]

Returns a string representation of the LinkValidatorContext.

Returns:

A string representation of the context, including its

class name and the associated validation chain.

Return type:

str

Examples

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>>
>>> class ExampleLink:
...     pass
...
>>> chain = ValidationChain(BaseValidator)
>>> validator_context = LinkValidatorContext(chain)
>>> repr(validator_context)
"LinkValidatorContext(ValidationChain(base='BaseValidator'))"
_abc_impl = <_abc._abc_data object>
add_validators(*validators)[source]

Adds one or more validators to the validation chain.

This method allows the dynamic addition of validators to the validation chain at runtime. Each provided validator is appended to the chain, enabling custom validation logic and extensibility.

Parameters:

*validators (ABCLinkValidator) – One or more validator instances to add to the validation chain.

Return type:

None

Examples

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(ABCLinkValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> chain = ValidationChain(BaseValidator)
>>> context = LinkValidatorContext(chain)
>>> context.add_validators(ExampleValidator, ExampleValidator)
validate(*links)[source]

Validates a link in the chain.

This method performs validation on the given links using the validators in the validation chain. It ensures that the link meets all the criteria enforced by the chain’s validators.

Parameters:

*links (_ChainLink) – The links to validate.

Raises:

Any – Exceptions raised by the individual validators in the chain if the link does not meet the required criteria.

Examples

Return type:

None

>>> from domprob.announcements.validation.chain import (
...     ABCLinkValidatorContext, ValidationChain
... )
>>> from domprob.announcements.validation.chain_validation import InvalidLinkException
>>>
>>> class ExampleLink:
...     pass
...
>>> chain = ValidationChain(BaseValidator)
>>> validator_context = LinkValidatorContext(chain)
>>> try:
...     validator_context.validate("invalid_link")  # type: ignore
... except InvalidLinkException as e:
...     print(e)
Invalid link of type 'str', expected type 'BaseValidator'
validators: list[type[ABCLinkValidator]]
class domprob.announcements.validation.chain_validation.UniqueLinkValidator(chain)[source]

Bases: ABCLinkValidator

Validator to ensure that links in the validation chain are unique.

This validator checks whether a link already exists in the validation chain. If a duplicate link is detected, it raises a LinkExistsException. This ensures that all links in the chain are unique.

chain

The validation chain this validator is associated with.

Type:

ValidationChain

Examples

>>> from domprob.announcements.validation.chain_validation import LinkTypeValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> chain = ValidationChain(BaseValidator)
>>> validator = UniqueLinkValidator(chain)
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> example_validator = ExampleValidator()
>>> chain.append(example_validator)
>>>
>>> try:
...     validator.validate(example_validator)
... except LinkExistsException as e:
...     print(e)
...
Link 'ExampleValidator(next_=None)' already exists in chain 'ValidationChain(base='BaseValidator')'
__repr__()

Returns a string representation of the validator.

Returns:

A string representation of the validator, including

its class name and the validation chain it belongs to.

Return type:

str

Examples

>>> from domprob.announcements.validation.chain import ABCLinkValidator
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> class ExampleValidator(ABCLinkValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> from domprob.announcements.validation.chain import ValidationChain
>>>
>>> validator = ExampleValidator(ValidationChain(BaseValidator))
>>> repr(validator)
"ExampleValidator(ValidationChain(base='BaseValidator'))"
_abc_impl = <_abc._abc_data object>
validate(link)[source]

Validates that the provided link does not already exist in the validation chain.

This method checks whether the given link is already present in the validation chain. If the link is a duplicate, it raises a LinkExistsException. This ensures that all links within the chain are unique.

Parameters:

link (_ChainLink) – The link to validate.

Raises:

LinkExistsException – If the link already exists in the validation chain.

Return type:

None

Examples

>>> from domprob.announcements.validation.chain_validation import LinkTypeValidator
>>> from domprob.announcements.validation.chain import ValidationChain
>>> from domprob.announcements.validation.base_validator import BaseValidator
>>>
>>> chain = ValidationChain(BaseValidator)
>>> validator = UniqueLinkValidator(chain)
>>>
>>> class ExampleValidator(BaseValidator):
...     def validate(self, link: BaseValidator) -> None:
...         pass
...
>>> example_validator = ExampleValidator()
>>> chain.append(example_validator)
>>>
>>> try:
...     validator.validate(example_validator)
... except LinkExistsException as e:
...     print(e)
...
Link 'ExampleValidator(next_=None)' already exists in chain 'ValidationChain(base='BaseValidator')'
exception domprob.announcements.validation.chain_validation.ValidationChainException[source]

Bases: AnnouncementException

Base exception class for errors related to validation chains.

This exception serves as the root for all validation chain-related errors, such as issues with chain construction, execution, or invalid links. It is designed to be extended by more specific exceptions within the validation framework.

__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class domprob.announcements.validation.orchestrator.AnnouncementValidationOrchestrator(chain=None)[source]

Bases: object

Orchestrates the validation of BoundAnnouncementMethod instances using a chain of validators.

The orchestrator is initialised with a ValidationChain, which can either be customised or use the default set of validators. Validators are applied sequentially to ensure that the BoundAnnouncementMethod adheres to defined rules and constraints.

DEFAULT_VALIDATORS

A tuple of default validator classes used to initialise the chain.

Type:

tuple[type[BaseValidator], …]

_chain

The validation chain that manages the sequence of validators.

Type:

ValidationChain

Parameters:

chain (ValidationChain | None, optional) – A custom validation chain. If not provided, a default chain is created with DEFAULT_VALIDATORS.

Examples

>>> from domprob.announcements.validation.orchestrator import AnnouncementValidationOrchestrator
>>> from domprob.announcements.method import AnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> class Example:
...     def method(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> method = AnnouncementMethod(Example.method)
>>> method.supp_instrums.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Example.method at 0x...>))
>>>
>>> bound_method = method.bind(Example(), SomeInstrument())
>>>
>>> orchestrator = AnnouncementValidationOrchestrator()
>>> orchestrator.validate(bound_method)
DEFAULT_VALIDATORS: tuple[type[BaseValidator], ...] = (<class 'domprob.announcements.validation.validators.SupportedInstrumentsExistValidator'>, <class 'domprob.announcements.validation.validators.InstrumentParamExistsValidator'>, <class 'domprob.announcements.validation.validators.InstrumentTypeValidator'>)
__repr__()[source]

Returns a string representation of the orchestrator.

The representation includes the class name and the associated validation chain.

Returns:

A string representation of the orchestrator.

Return type:

str

Examples

>>> orchestrator = AnnouncementValidationOrchestrator()
>>> repr(orchestrator)
"AnnouncementValidationOrchestrator(ValidationChain(base='BaseValidator'))"
register(*validators)[source]

Registers additional validators to the validation chain.

Validators are appended to the existing chain, and their instances are created dynamically.

Parameters:

*validators (type[BaseValidator]) – Validator classes to be added to the chain.

Return type:

AnnouncementValidationOrchestrator

Examples

>>> from domprob.announcements.validation.orchestrator import AnnouncementValidationOrchestrator
>>> from domprob.announcements.validation.validators import InstrumentTypeValidator
>>>
>>> orchestrator = AnnouncementValidationOrchestrator()
>>> orchestrator.register(InstrumentTypeValidator)
AnnouncementValidationOrchestrator(ValidationChain(base='BaseValidator'))
validate(method)[source]

Executes the validation chain on a BoundAnnouncementMethod instance.

This method ensures that all registered validators are applied sequentially to the method.

Parameters:

method (BoundAnnouncementMethod) – The method instance to validate.

Raises:

ValidatorException – If any of the validators in the chain fails.

Examples

>>> from domprob.announcements.validation.orchestrator import AnnouncementValidationOrchestrator
>>> from domprob.announcements.method import AnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> class Example:
...     def method(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Example.method)
>>> bound_meth = meth.bind(Example(), SomeInstrument())
>>> bound_meth.supp_instrums.record(SomeInstrument, required=True)
Instruments(metadata=AnnouncementMetadata(method=<function Example.method at 0x...>))
>>>
>>> orchestrator = AnnouncementValidationOrchestrator()
>>> orchestrator.validate(bound_meth)
exception domprob.announcements.validation.validators.InstrumTypeException(b_meth)[source]

Bases: ValidatorException

Exception raised when the instrument parameter does not match the expected type.

Parameters:

b_meth (BoundAnnouncementMethod) – Bound method that failed validation.

method

The method that failed validation.

Type:

Callable[…, Any]

instrument

The invalid instrument instance.

Type:

Any

supp_instrums

The supported instrument types.

Type:

Instruments

Examples

>>> from domprob.announcements.method import AnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> class Example:
...     def method(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Example.method)
>>> meth.supp_instrums.record(SomeInstrument, True)
Instruments(metadata=AnnouncementMetadata(method=<function Example.method at 0x...))
>>> bound_meth = meth.bind(Example(), 'InvalidInstrument')  # type: ignore
>>>
>>> try:
...     raise InstrumTypeException(bound_meth)
... except InstrumTypeException as e:
...     print(f"Error: {e}")
...
Error: Example.method(...) expects 'instrument' param to be one of: [SomeInstrument], but got: 'InvalidInstrument'
__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Constructs a detailed error message.

Returns:

Error message describing the invalid instrument.

Return type:

str

with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class domprob.announcements.validation.validators.InstrumentParamExistsValidator(next_=None)[source]

Bases: BaseValidator

Validator to check if the instrument parameter exists.

This validator raises a MissingInstrumentException if the instrument parameter is None.

Examples

>>> from domprob.announcements.validation.validators import InstrumentParamExistsValidator
>>> from domprob.announcements.method import AnnouncementMethod
>>>
>>> class SomeInstrument:
...     pass
...
>>> class Example:
...     def method(self, instrument: SomeInstrument) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Example.method)
>>> bound_meth = meth.bind(Example())
>>>
>>> validator = InstrumentParamExistsValidator()
>>> try:
...     validator.validate(bound_meth)
... except MissingInstrumException as e:
...     print(f"Error: {e}")
...
Error: 'instrument' param missing in Example.method(...)
__repr__()

Returns a string representation of the validator.

This includes the class name and the next_ validator in the chain, making it easier to debug and inspect validator chains.

Returns:

A string representation of the validator.

Return type:

str

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>> class ExampleValidator(BaseValidator):
...     def validate(self, meth: BoundAnnouncementMethod) -> None:
...         pass
...
>>> validator = ExampleValidator(next_=None)
>>> repr(validator)
'ExampleValidator(next_=None)'
>>> chained_validator = ExampleValidator(next_=validator)
>>> repr(chained_validator)
'ExampleValidator(next_=ExampleValidator(next_=None))'
_abc_impl = <_abc._abc_data object>
validate(b_meth)[source]

Validates the method to ensure the instrument parameter exists.

Parameters:

b_meth (BoundAnnouncementMethod) – Method with bound params to validate.

Raises:

MissingInstrumentException – If the instrument parameter is None.

Return type:

None

class domprob.announcements.validation.validators.InstrumentTypeValidator(next_=None)[source]

Bases: BaseValidator

Validator to check if the instrument is of a valid type.

This validator raises an InstrumentTypeException if the type of the instrument parameter is not one of the supported instrument types.

Examples

>>> from domprob.announcements.validation.validators import InstrumentTypeValidator
>>> from domprob.announcements.method import AnnouncementMethod
>>> class MockInstrument:
...     pass
...
>>> class Example:
...     def method(self, instrument: MockInstrument) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Example.method)
>>> bound_meth = meth.bind(Example(), 'InvalidInstrument')  # type: ignore
>>>
>>> validator = InstrumentTypeValidator()
>>> try:
...     validator.validate(bound_meth)
... except InstrumTypeException as e:
...     print(f"Error: {e}")
...
Error: Example.method(...) expects 'instrument' param to be one of: [], but got: 'InvalidInstrument'
__repr__()

Returns a string representation of the validator.

This includes the class name and the next_ validator in the chain, making it easier to debug and inspect validator chains.

Returns:

A string representation of the validator.

Return type:

str

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>> class ExampleValidator(BaseValidator):
...     def validate(self, meth: BoundAnnouncementMethod) -> None:
...         pass
...
>>> validator = ExampleValidator(next_=None)
>>> repr(validator)
'ExampleValidator(next_=None)'
>>> chained_validator = ExampleValidator(next_=validator)
>>> repr(chained_validator)
'ExampleValidator(next_=ExampleValidator(next_=None))'
_abc_impl = <_abc._abc_data object>
validate(b_meth)[source]

Validates the method by checking the type of the instrument parameter.

Parameters:

b_meth (InstrumentBoundAnnoMethod) – Method with bound params to validate.

Raises:

AnnoValidationException – If the instrument parameter is not an instance of any valid instrument classes.

Return type:

None

exception domprob.announcements.validation.validators.MissingInstrumException(method)[source]

Bases: ValidatorException

Exception raised when the instrument parameter is missing during a call to a method.

Parameters:

method (Callable[..., Any]) – The method where the missing instrument parameter was detected.

method

The method that caused the exception.

Type:

Callable[…, Any]

Examples

>>> from domprob.announcements.validation.validators import MissingInstrumException
>>> class Example:
...     def method(self):
...         pass
...
>>> try:
...     raise MissingInstrumException(Example().method)
... except MissingInstrumException as e:
...     print(f"Error: {e}")
...
Error: 'instrument' param missing in Example.method(...)
__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Constructs a detailed error message.

Returns:

Error message indicating the missing instrument

parameter.

Return type:

str

Examples

>>> class Example:
...     def method(self):
...         pass
...
>>> exc = MissingInstrumException(Example().method)
>>> exc.msg
"'instrument' param missing in Example.method(...)"
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception domprob.announcements.validation.validators.NoSupportedInstrumsException(method)[source]

Bases: ValidatorException

Exception raised when no supported instruments are defined for a method.

This exception indicates that the method’s metadata does not include any supported instrument types, which is required for proper validation.

Parameters:

method (Callable[..., Any]) – The method where the missing supported instruments were detected.

method

The method that caused the exception.

Type:

Callable[…, Any]

Examples

>>> from domprob.announcements.validation.validators import NoSupportedInstrumsException
>>> class Example:
...     def method(self):
...         pass
...
>>> try:
...     raise NoSupportedInstrumsException(Example().method)
... except NoSupportedInstrumsException as e:
...     print(f"Error: {e}")
...
Error: Example.method(...) has no supported instrument types defined
__repr__()

Return repr(self).

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
property msg: str

Constructs a detailed error message.

Returns:

Error message indicating that no supported instrument

types are defined for the method.

Return type:

str

Examples

>>> class Example:
...     def method(self):
...         pass
...
>>> exc = NoSupportedInstrumsException(Example().method)
>>> exc.msg
'Example.method(...) has no supported instrument types defined'
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class domprob.announcements.validation.validators.SupportedInstrumentsExistValidator(next_=None)[source]

Bases: BaseValidator

Validator to ensure that at least one supported instrument is defined.

This validator raises a NoSupportedInstrumentsException if the method’s metadata does not include any supported instrument types.

Examples

>>> from domprob.announcements.validation.validators import SupportedInstrumentsExistValidator
>>> from domprob.announcements.method import AnnouncementMethod
>>> class Example:
...     def method(self, instrument: Any) -> None:
...         pass
...
>>> meth = AnnouncementMethod(Example.method)
>>> bound_meth = meth.bind(Example())
>>>
>>> validator = SupportedInstrumentsExistValidator()
>>> try:
...     validator.validate(bound_meth)
... except NoSupportedInstrumsException as e:
...     print(f"Error: {e}")
...
Error: Example.method(...) has no supported instrument types defined
__repr__()

Returns a string representation of the validator.

This includes the class name and the next_ validator in the chain, making it easier to debug and inspect validator chains.

Returns:

A string representation of the validator.

Return type:

str

Examples

>>> from domprob.announcements.validation.base_validator import BaseValidator
>>> from domprob.announcements.method import BoundAnnouncementMethod
>>> class ExampleValidator(BaseValidator):
...     def validate(self, meth: BoundAnnouncementMethod) -> None:
...         pass
...
>>> validator = ExampleValidator(next_=None)
>>> repr(validator)
'ExampleValidator(next_=None)'
>>> chained_validator = ExampleValidator(next_=validator)
>>> repr(chained_validator)
'ExampleValidator(next_=ExampleValidator(next_=None))'
_abc_impl = <_abc._abc_data object>
validate(b_meth)[source]

Validates the method by checking the type of the instrument parameter.

Parameters:

b_meth (BoundAnnouncementMethod) – Method with bound params to validate.

Raises:

AnnoValidationException – If the instrument parameter is not an instance of any valid instrument classes.

Return type:

None