Reg is a Python library that provides generic function support to Python. It help you build powerful registration and configuration APIs for your application, library or framework.
The key_predicate function is gone. You can now use Predicate(..., index=KeyIndex) or match_key instead.
The class_predicate function is gone. You can now use Predicate(..., index=ClassIndex), match_instance or match_class instead.
The undocumented Sentinel class and NOT_FOUND object are gone.
The class PredicateRegistry is not longer part of the API. Internally, the classes MultiPredicate, MultiIndex, SingleValueRegistry have all been merged into PredicateRegistry, which should now considered an implementation detail.
The second argument for match_key is now optional; if you don’t supply it match_key will generate a predicate function that extracts that name by default.
The documentation now includes a section describing the internals of Reg.
Upload universal wheels to pypi during release.
Reg has undergone another API breaking change. The goals of this change were:
reg.Registry is gone. Instead you register directly on the dispatch function:
@reg.dispatch('a') def foo(a): ... def foo_implementation(a): ... foo.register(foo_implementation, a=Document)
Caching is now per dispatch function, not globally per lookup. You can pass a get_key_lookup function that wraps reg.PredicateRegistry instance inside a reg.DictCachingKeyLookup cache. You can also use a reg.LruCachingKeyLookup if you expect a dispatch to be called with a large amount of possible predicate combinations, to preserve memory.
The whole concept of a “lookup” is gone:
If you do not use the context-dependent dispatch feature, then to upgrade your code:
remove any reg.set_implicit from your code, setup of Lookup and the like.
If you use an explicit lookup argument you can just remove them.
You also need to change your registration code: no more reg.Registry setup.
Change your registrations to be on the dispatch objects itself using Dispatch.register.
To enable caching you need to set up get_key_lookup on the dispatch functions. You can create a partially applied version of dispatch to make this less verbose:
import reg from functools import partial def get_caching_key_lookup(r): return reg.CachingKeyLookup(r, 5000, 5000, 5000) dispatch = partial(reg.dispatch, get_key_lookup=get_caching_key_lookup)
dispatch_external_predicates is gone. Just use dispatch directly. You can add predicates to an existing Dispatch object using the add_predicates method.
If you do use the context-dependent dispatch feature, then you also need to:
In some cases you want a context-dependent method that actually does not dispatch on any of its arguments. To support this use case you can simply set function (that takes an app argument) as a the method on the context class directly:
Context.my_method = some_function
If you want to set up a function that doesn’t take a reference to a Context instance as its first argument, you can use reg.methodify to turn it into a method that ignores its first argument:
Context.my_method = reg.methodify(some_function)
If you want to register a function that might or might not have a reference to a Context instance as its first argument, called, e.g., app, you can use the following:
Context.my_method = reg.methodify(some_function, selfname='app')
Removed the helper function mapply from the API.
Removed the exception class KeyExtractorError from the API. When passing the wrong number of arguments to a dispatch function, or when using the wrong argument names, you will now get a TypeError, in conformity with standard Python behaviour.
Removed the KeyExtractor class from the API. Callables used in predicate construction now expect the same arguments as the dispatch function.
Removed the argnames attribute from Predicate and its descendant.
Remove the match_argname predicate. You can now use match_instance with no callable instead.
The second argument for match_class is now optional; if you don’t supply it match_class will generate a predicate function that extracts that name by default.
The second argument for match_instance is now optional; if you don’t supply it match_instance will generate a predicate function that extracts that name by default.
Include doctests in Tox and Travis.
We now use virtualenv and pip instead of buildout to set up the development environment. The development documentation has been updated accordingly.
As we reached 100% code coverage for pytest, coveralls integration was replaced by the --fail-under=100 argument of coverage report in the tox coverage test.
Total rewrite of Reg! This includes a range of changes that can break code. The primary motivations for this rewrite:
Some specific changes:
Replaced @reg.generic decorator with @reg.dispatch() decorator. This decorator can be configured with predicates that extract information from the arguments. Rewrite this:
@reg.generic def foo(obj): pass
@reg.dispatch('obj') def foo(obj): pass
@reg.generic def bar(a, b): pass
@reg.dispatch('a', 'b') def bar(a, b): pass
This is to get dispatch on the classes of these instance arguments. If you want to match on the class of an attribute of an argument (for instance) you can use match_instance with a function:
@reg.dispatch(match_instance('a', lambda a: a.attr))
The first argument to match_instance is the name of the predicate by which you refer to it in register_function.
You can also use match_class to have direct dispatch on classes (useful for replicating classmethods), and match_key to have dispatch on the (immutable) value of the argument (useful for a view predicate system). Like for match_instance, you supply functions to these match functions that extract the exact information to dispatch on from the argument.
The register_function API replaces the register API to register a function. Replace this:
r.register(foo, (SomeClass,), dispatched_to)
r.register_function(foo, dispatched_to, obj=SomeClass)
You now use keyword parameters to indicate exactly those arguments specified by reg.dispatch() are actually predicate arguments. You don’t need to worry about the order of predicates anymore when you register a function for it.
The new classgeneric functionality is part of the predicate system now; you can use reg.match_class instead. Replace:
@reg.classgeneric def foo(cls): pass
@reg.dispatch(reg.match_class('cls', lambda cls: cls)) def foo(cls): pass
You can do this with any argument now, not just the first one.
pep443 support is gone. Reg is focused on its own dispatch system.
Compose functionality is gone – it turns out Morepath doesn’t use lookup composition to support App inheritance. The cached lookup functionality has moved into registry.py and now also supports caching of predicate-based lookups.
Dependency on the future module is gone in favor of a small amount of compatibility code.
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
|File Name & Checksum SHA256 Checksum Help||Version||File Type||Upload Date|
|reg-0.11-py2.py3-none-any.whl (34.6 kB) Copy SHA256 Checksum SHA256||py2.py3||Wheel||Dec 23, 2016|
|reg-0.11.tar.gz (53.7 kB) Copy SHA256 Checksum SHA256||–||Source||Dec 23, 2016|