so_magic.utils package

The utils package provides a set of useful classes (and functions) that are commonly used by multiple SoMagic components. These classes serve as building blocks for the SoMagic library and they have been implemented following well-known and established software engineering patterns and best-practices. After all we want our Magic software to be based on solid foundations.

Submodules Overview

so_magic.utils.command_factory_interface module

This module is responsible to define an interface to construct Command objects (instances of the Command class).

so_magic.utils.command_interface module

so_magic.utils.commands module

so_magic.utils.linear_mapping module

This module exposes the MapOnLinearSpace class and the ‘universal_constructor’ method to create instances of it. Instances of MapOnLinearSpace can be used to project a number from one linear space to another.

so_magic.utils.mediator module

so_magic.utils.memoize module

Implementation of the object pool

so_magic.utils.notification module

Typical subject/observers pattern implementation. You can see this pattern mentioned also as event/notification or broadcast/listeners.

Provides the Observer class, serving as the interface that needs to be implemented by concrete classes; the update method needs to be overrode. Concrete Observers react to the notifications/updates issued by the Subject they had been attached to.

Provides the Subject class, serving with mechanisms to subscribe/unsubscribe (attach/detach) observers and also with a method to “notify” all subscribers about events.

so_magic.utils.registry module

so_magic.utils.singleton module

so_magic.utils.transformations module

This module provides the Transformer class. Its constructor can be used to create data transformation methods.

Exposed python objects (package’s public interface)

class so_magic.utils.BaseComponent(mediator: Optional[so_magic.utils.mediator.Mediator] = None)[source]

Bases: object

The Base Component provides the basic functionality of storing a mediator’s instance inside component objects.

property mediator: so_magic.utils.mediator.Mediator
class so_magic.utils.Command(receiver, method: str, *args)[source]

Bases: so_magic.utils.commands.BaseCommand

An runnable/executable Command that acts as a prototype through the ‘copy’ python magic function.

When a command instance is invoked with ‘copy’, the receiver is copied explicitly in a shallow way. The rest of the command arguments are assumed to be performance invariant (eg it is not expensive to copy the ‘method’ attribute, which is a string) and are handled automatically.

class so_magic.utils.CommandFactoryInterface[source]

Bases: abc.ABC

Define a way to create objects of type Command.

Classes implementing this interface define a way to construct (initialize) new Command objects (class instances).

abstract construct(*args, **kwargs)so_magic.utils.command_interface.CommandInterface[source]

Construct a new Command object (new class instance) that can be executed.

Returns

the command object (instance)

Return type

Command

class so_magic.utils.CommandFactoryType(*args, **kwargs)[source]

Bases: so_magic.utils.subclass_registry.SubclassRegistry

class so_magic.utils.CommandHistory[source]

Bases: object

The global command history is just a stack; supports ‘push’ and ‘pop’ methods.

pop()so_magic.utils.commands.Command[source]
push(command: so_magic.utils.commands.Command)[source]
property stack
class so_magic.utils.GenericMediator(*components, **kwargs)[source]

Bases: so_magic.utils.mediator.Mediator

Abstract Mediator class that automatically configures components received as *args through the constructor.

class so_magic.utils.Invoker(history: so_magic.utils.commands.CommandHistory)[source]

Bases: object

A class that simply executes a command and pushes it into its internal command history stack.

Parameters

history (CommandHistory) – the command history object which acts as a stack

execute_command(command: so_magic.utils.commands.Command)[source]
class so_magic.utils.MapOnLinearSpace(from_scale: so_magic.utils.linear_mapping.LinearScale, target_scale: so_magic.utils.linear_mapping.LinearScale, reverse: bool = False)[source]

Bases: object

Projection of a number from one linear scale to another.

Instances of this class can transform an input number and map it from an initial scale to a target scale.

Parameters
  • _from_scale (LinearScale) – the scale where the number is initially mapped

  • _target_scale (LinearScale) – the (target) scale where the number should be finally transformed/mapped to

  • _reverse (bool) – whether the target scale is inverted or not

property from_scale
property reverse
property target_scale
transform(number)[source]

Transform the input number to a different linear scale.

classmethod universal_constructor(from_scale, target_scale, reverse=False)[source]
class so_magic.utils.ObjectRegistry(*args, **kwargs)[source]

Bases: abc.ABC

Simple dict-like retrieval/inserting “store” facility.

add(key, value)[source]
get(key)[source]
pop(key)[source]
remove(key)[source]
exception so_magic.utils.ObjectRegistryError[source]

Bases: Exception

class so_magic.utils.ObjectsPool(constructor, build_hash, objects={})[source]

Bases: object

Class of objects that are able to return a reference to an object upon request.

Whenever an object is requested, it is checked whether it exists in the pool. Then if it exists, a reference is returned, otherwise a new object is constructed (given the provided callable) and its reference is returned.

Parameters
  • constructor (callable) – able to construct the object given arguments

  • objects (dict) – the data structure representing the object pool

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

Request an object from the pool.

Get or create an object given the input parameters. Existence in the pool is done using the python-build-in hash function. The input *args and **kwargs serve as input in the hash function to create unique keys with which to “query” the object pool.

Returns

the reference to the object that corresponds to the input arguments, regardless of whether it was found in the pool or not

Return type

object

classmethod new_empty(constructor, build_hash=None)[source]
class so_magic.utils.Observer[source]

Bases: so_magic.utils.notification.ObserverInterface, abc.ABC

class so_magic.utils.Singleton[source]

Bases: type

class so_magic.utils.SubclassRegistry(*args, **kwargs)[source]

Bases: type

Subclass Registry

A (parent) class using this class as metaclass gains the ‘subclasses’ class attribute as well as the ‘create’ and ‘register_as_subclass’ class methods.

The ‘subclasses’ attribute is a python dictionary having string identifiers as keys and subclasses of the (parent) class as values.

The ‘register_as_subclass’ class method can be used as a decorator to indicate that a (child) class should belong in the parent’s class registry. An input string argument will be used as the unique key to register the subclass.

The ‘create’ class method can be invoked with a (string) key and suitable constructor arguments to later construct instances of the corresponding child class.

Example

>>> from so_magic.utils import SubclassRegistry
>>> class ParentClass(metaclass=SubclassRegistry):
...  pass
>>> ParentClass.subclasses
{}
>>> @ParentClass.register_as_subclass('child')
... class ChildClass(ParentClass):
...  def __init__(self, child_attribute):
...   self.attr = child_attribute
>>> child_instance = ParentClass.create('child', 'attribute-value')
>>> child_instance.attr
'attribute-value'
>>> type(child_instance).__name__
'ChildClass'
>>> isinstance(child_instance, ChildClass)
True
>>> isinstance(child_instance, ParentClass)
True
>>> {k: v.__name__ for k, v in ParentClass.subclasses.items()}
{'child': 'ChildClass'}
create(subclass_identifier, *args, **kwargs)[source]

Create an instance of a registered subclass, given its unique identifier and runtime (constructor) arguments.

Invokes the identified subclass constructor passing any supplied arguments. The user needs to know the arguments to supply depending on the resulting constructor signature.

Parameters

subclass_identifier (str) – the unique identifier under which to look for the corresponding subclass

Raises

ValueError – In case the given identifier is unknown to the parent class

Returns

the instance of the registered subclass

Return type

object

register_as_subclass(subclass_identifier)[source]

Register a class as subclass of the parent class.

Adds the subclass’ constructor in the registry (dict) under the given (str) identifier. Overrides the registry in case of “identifier collision”. Can be used as a python decorator.

Parameters

subclass_identifier (str) – the user-defined identifier, under which to register the subclass

class so_magic.utils.Subject(*args, **kwargs)[source]

Bases: so_magic.utils.notification.SubjectInterface

The Subject owns some important state and can notify observers.

Both the _state and _observers attributes have a simple implementation, but can be overrode to accommodate for more complex scenarios.

The observers/subscribers are implemented as a python list. In more complex scenarios, the list of subscribers can be stored more comprehensively (categorized by event type, etc.).

The subscription management methods provided are ‘attach’ and ‘detach’ to add or remove a subscriber respectively

add(*observers)[source]

Subscribe multiple observers at once.

attach(observer: so_magic.utils.notification.Observer)None[source]

Attach an observer to the subject; subscribe the observer.

detach(observer: so_magic.utils.notification.Observer)None[source]

Detach an observer from the subject; unsubscribe the observer.

notify()None[source]

Trigger an update in each subscriber/observer.

property state
class so_magic.utils.Transformer(*args, **kwargs)[source]

Bases: so_magic.utils.transformations.RuntimeTransformer