Add the registries implementation.

Review Request #14014 — Created July 8, 2024 and submitted — Latest diff uploaded

Information

python-registries
main

Reviewers

This provides the implementation of the registries functionality. This
is based heavily on Djblets's registries support, but with some notable
differences.

Primarily, error handling is different. The version in Djblets had a
sort of split concept of errors. A registry had a map of error codes
(strings) to messages (as format strings). Internally, these would be
paired with one or more exceptions. Subclasses were able to override the
message format strings, or add new ones that map to custom error codes.

Rather than going through this whole process, we now simply use
exceptions, and define the exception classes on the registry. Each
exception class maps to a specific message formatting string, and is
raised like normal. Subclasses that want to customize messages can
define a subclass of the exception and assign it to the right attribute
on the registry.

The other change is more usability-focused, having to do with attribute
matching.

Previously, Registry.get(), Registry.get_or_none(), and
Registry.unregister_by_attr() took attr_name and attr_value
positional arguments, and the caller always had to pass both. This was
error-prone for the common case of a registry that only had one lookup
attribute.

Now, for this common case, the caller can leave out the attribute name
and just pass in the attribute value.

Alternatively (and required when multiple lookup attributes are
possible), the caller can pass in my_attr=my_value. This is nicer than
passing in "my_attr", my_value as positional arguments, or
attr_name="my_attr", attr_value=my_value. It should eliminate the need
for wrapper methods.

Third, it lacks the deprecated mixins and other code. It also does not
ship a registry_populated signal (as this was a Django-ism). The hooks
support makes it easy for consumers to trigger signals themselves.

Otherwise, this works just like Djblets's registries, with a better
design, and should be feature-complete for a 1.0.

All unit tests pass on Python 3.8-3.13.

Commits

Files