API

class reg.IRegistry

A registration API for components.

clear()

Clear registry of all registrations.

exact(key, classes)

Get registered component for exactly key and classes.

Parameters:
  • key (hashable object, normally function.) – Get component for this key.
  • classes (list of classes.) – List of classes for which to get component.
Returns:

registered component, or None.

Does not go to base classes, just returns exact registration.

Returns None if no registration exists.

register(key, classes, component)

Register a component.

Parameters:
  • key (hashable object, normally function.) – Register component for this key.
  • classes (list of classes.) – List of classes for which to register component.
  • component (object.) – Any python object, often a function. Can be a reg.Matcher instance.

The key is a hashable object, often a function object, by which the component can be looked up.

classes is a list of 0 to n classes that the component is registered for. If multiple sources are listed, a registration is made for that combination of sources.

The component is a python object (function, class, instance, etc) that is registered. If you’re working with multiple dispatch, you would register a function that expects instances of the classes in classes as its arguments.

class reg.IClassLookup
all(key, classes)

Look up all components, by key and classes.

Parameters:
  • key (hashable object, normally function.) – Get components for this key.
  • classes (list of classes.) – List of classes for which to get components.
Returns:

iterable of found components.

The key is a hashable object, often a function object, by which the components are looked up.

classes is a list of 0 to n classes that we use to look up the components. If multiple classes are listed, the lookup is made for that combination of classes. All registered components for combinations of base classes are also returned.

A Cartesian product is made of all combinations of base classes to do this, sorted by inheritance, first class to last class, most specific to least specific.

This calculation is relatively expensive so you can wrap a class lookup in a reg.CachingClassLookup proxy to speed up subsequent calls.

If no components can be found, the iterable returned will be empty.

get(key, classes)

Look up a component, by key and classes of arguments.

Parameters:
  • key (hashable object, normally function.) – Get component for this key.
  • classes (list of classes.) – List of classes for which to get component.
Returns:

registered component, or None.

The key is a hashable object, often a function object, by which the component is looked up.

classes is a list of 0 to n classes that we use to look up the component. If multiple classes are listed, the lookup is made for that combination of classes.

In order to find the most matching registered component, a Cartesian product is made of all combinations of base classes given, sorted by inheritance, first class to last class, most specific to least specific.

This calculation is relatively expensive so you can wrap a class lookup in a reg.CachingClassLookup proxy to speed up subsequent calls.

If the component can be found, it will be returned. If the component cannot be found, None is returned.

class reg.ClassRegistry

Bases: reg.registry.IRegistry, reg.registry.IClassLookup

class reg.Registry

Bases: reg.registry.IRegistry, reg.lookup.Lookup

class reg.Lookup(class_lookup)

Look up objects for a key.

The lookup API is also available directly on a function decorated with reg.generic(). The call method stands in for the actual function call. If the call method is in use from reg.generic, ComponentLookupError is never raised, and instead the fall back is to the function being decorated.

all(key, args, predicates=None)

Lookup up all components registered for args.

Parameters:
  • key (hashable object, normally function.) – Look up components for this key.
  • args (list of objects.) – Look up components for these arguments.
  • predicates (dict.) – predicates (used by Matcher)
Returns:

iterable of registered components.

The behavior of this method is like that of component, but it looks up all the matching components for the arguments. This means that if one component is registered for a class and another for its base class, all() with an instance of the class as its argument will return both components.

Will check whether the found component is an Matcher, in which case it will be called with args. If non-None is returned, the found value is included as a matching component. If a matcher is involved and the predicates parameter is supplied, this will be used for the matcher, overriding any predicate calculation it may do itself. Otherwise the predicates parameter has no effect.

If no components can be found, the iterable will be empty.

call(key, args, default=<Sentinel>, **kw)

Call function based on multiple dispatch on args.

Parameters:
  • key (hashable object, normally function.) – Call function for this key.
  • args (list of objects.) – Call function with these arguments.
  • default (object.) – default value to return if lookup fails.
  • kw – extra keyword arguments passed to the function called.
Returns:

result of function call.

Raises:

ComponentLookupError

The behavior of this method is like that of component, but it performs an extra step: it calls the found component with the args given as arguments.

This amounts to an implementation of multiple dispatch: zero or more arguments can be used to dispatch the function on.

If the found component has a lookup argument, it will pass the lookup to this argument too. This allows you to pass along lookup completely explicitly between generic functions.

component(key, args, default=<Sentinel>, predicates=None)

Look up a component.

Parameters:
  • key (hashable object, normally function.) – Look up component for this key.
  • args (list of objects.) – Look up component for these arguments.
  • default (object.) – default value to return if lookup fails.
  • predicates (dict.) – optional predicate ditcionary for matcher, overriding the matcher’s predicate calculation.
Returns:

registered component.

Raises:

ComponentLookupError

A component can be any Python object.

key is a hashable object that is used to determine what to look up. Normally it is a Python function.

args is a list of 0 to n objects that we use to look up the component. The classes of the args are used to do the look up. If multiple args are listed, the lookup is made for that combination of args.

If the component found is an instance of class:Matcher, it will be called with args as parameters (matcher(*args)). The matcher can return an object, in which case will be returned as the real matching component. If the matcher returns None it will look for a match higher up the ancestor chain of args. If a predicates argument is supplied this is used by the matcher instead of doing its own predicate calculation from the arguments. This can be useful in combination with the reg.PredicateMatcher to override which predicates are used in a lookup.

If a component can be found, it will be returned. If the component cannot be found, a ComponentLookupError will be raised, unless a default argument is specified, in which case it will be returned.

class reg.Matcher

Look up by calling and returning value.

If a component that subclasses Matcher is registered, it it is called with args, i.e. matcher(*args). The resulting value is considered to be the looked up component. If the resulting value is None, no component is found for this matcher.

A matcher can be found multiple times during a lookup (if the first matcher results in None. Information such as predicates may have to be calculated multiple times in that case. This can be avoided by defining a predicates method which takes the arguments used for the lookup as arguments. The result should be a dictionary which is passed as keyword arguments into this matcher, as well as any further candidate matchers if this one returns None.

exception reg.ComponentLookupError

Error raised when a component cannot be found.

Will only be raised if nod default argument was supplied during lookup.

class reg.ListClassLookup(lookups)

Bases: reg.registry.IClassLookup

A simple list of class lookups functioning as a single IClassLookup.

Go through all items in the list, starting at the beginning and try to find the component. If found in a lookup, return it right away.

class reg.ChainClassLookup(lookup, next)

Bases: reg.registry.IClassLookup

Chain a class lookup on top of another class lookup.

Look in the supplied IClassLookup object first, and if not found, look in the next IClassLookup object. This way multiple IClassLookup objects can be chained together.

class reg.CachingClassLookup(class_lookup)

Bases: reg.registry.IClassLookup

Cache an existing class lookup.

All previous accesses to class lookup are cached.

reg.generic(func)

Turn a function into a generic function.

Parameters:func (function.) – Function to turn into a multiple dispatch function.
Returns:multiple dispatch version of function.

When someone calls the wrapped function, the arguments determine what actual function will be called. In particular the classes of the arguments are inspected. For each combination of arguments a different function can be registered.

The function itself provides a default implementation in case no more specific registered function can be found for its arguments.

Can be used as a decorator:

@reg.generic
def my_function(...):
    ...
class reg.PredicateRegistry(predicates)

A registry that can be used to index items by predicate.

class reg.Predicate(name, index_factory, calc=None, default=None)

A predicate.

class reg.KeyIndex

An index for matching predicates by key.

exception reg.PredicateRegistryError

An error using the predicate registry.

class reg.implicit.Implicit

Implicit global lookup.

There will only one singleton instance of this, called reg.implicit. The lookup can then be accessed using reg.implicit.lookup.

Generic functions as well as their component and all methods make use of this information if you do not pass an explicit lookup argument to them. This is handy as it becomes unnecessary to have to pass a lookup object everywhere.

The drawback is that this single global lookup is implicit, which makes it harder to test in isolation. Reg supports testing with the explicit lookup argument, but that is not useful if you are testing code that relies on an implicit lookup. Therefore Reg strives to make the implicit global lookup as explicit as possible so that it can be manipulated in tests where this is necessary.

It is also possible for a framework to change the implicit lookup during run-time. This is done by simply assigning to implicit.lookup. The lookup is stored on a thread-local and is unique per thread.

Reg offers facilities to compose such a custom lookup:

  • reg.ListClassLookup and reg.ChainClassLookup which can be used to chain multiple IClassLookup instances together.
  • reg.CachingClassLookup which can be used to create a faster caching version of an IClassLookup.
  • reg.Lookup which can be used to turn a IClassLookup into a proper ILookup.

To change the lookup back to a lookup in the global implicit registry, call reset.

The implicit lookup is thread-local: each thread has a separate implicit global lookup.

clear()

Clear global implicit lookup.

initialize(lookup)

Initialize implicit with lookup.

Parameters:lookup (ILookup.) – The lookup that will be the global implicit lookup.
lookup

Get the implicit ILookup.

reset()

Reset global implicit lookup to original lookup.

This can be used to wipe out any composed lookups that were installed in this thread.

exception reg.NoImplicitLookupError

No implicit lookup was registered.

Register an implicit lookup by calling reg.implicit.initialize(), or pass an explicit lookup argument to generic function calls.

reg.mapply(func, *args, **kw)

Apply keyword arguments to function only if it defines them.

So this works without error as b is ignored:

def foo(a):
    pass

mapply(foo, a=1, b=2)

Zope has an mapply that does this but a lot more too. py.test has an implementation of getting the argument names for a function/method that we’ve borrowed.

reg.arginfo(callable)

Get information about the arguments of a callable.

Returns a inspect.ArgSpec object as for inspect.getargspec().

inspect.getargspec() returns information about the arguments of a function. arginfo also works for classes and instances with a __call__ defined. Unlike getargspec, arginfo treats bound methods like functions, so that the self argument is not reported.

arginfo caches previous calls (except for instances with a __call__), making calling it repeatedly cheap.

This was originally inspired by the pytest.core varnames() function, but has been completely rewritten to handle class constructors, also show other getarginfo() information, and for readability.