Skip to content

Commit

Permalink
Merge pull request #40 from BrianPugh/set-item-interface
Browse files Browse the repository at this point in the history
Set item interface
  • Loading branch information
BrianPugh authored Oct 24, 2023
2 parents de7af4b + 41f5a73 commit d1739ab
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 0 deletions.
9 changes: 9 additions & 0 deletions autoregistry/_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
InvalidNameError,
KeyCollisionError,
ModuleAliasError,
RegistryError,
)


Expand Down Expand Up @@ -145,6 +146,12 @@ class _DictMixin:
def __getitem__(self, key: str) -> Type:
return self.__registry__.config.getitem(self.__registry__, key)

def __setitem__(self, key: str, value: Any):
if type(self) is RegistryDecorator:
self.__registry__.register(value, key, root=True)
else:
raise RegistryError("Cannot directly setitem on a Registry subclass.")

def __iter__(self) -> Generator[str, None, None]:
yield from self.__registry__

Expand Down Expand Up @@ -261,6 +268,7 @@ def __new__(
if namespace["__registry__"].config.redirect:
for method_name in [
"__getitem__",
"__setitem__",
"__iter__",
"__len__",
"__contains__",
Expand Down Expand Up @@ -306,6 +314,7 @@ class Registry(metaclass=RegistryMeta):
__call__: Callable
__contains__: Callable[..., bool]
__getitem__: Callable[[str], Type]
__setitem__: Callable[[str, Any], Type]
__iter__: Callable
__len__: Callable[..., int]
clear: Callable[[], None]
Expand Down
1 change: 1 addition & 0 deletions docs/source/Configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ doesn't impact the auto-derived registration key.

``name`` and ``aliases`` values are **not** subject to configured naming rules and will **not** be modified
by configurations like ``strip_suffix``.
Similarly, directly setting a registry element ``my_registry["myfunction"] = myfunction`` is not subject to naming rules.
However, values are still subject to the ``overwrite`` configuration and will raise ``KeyCollisionError`` if
``name`` or ``aliases`` attempts to overwrite an existing entry while ``overwrite=False``.
Additionally, ``name`` and ``aliases`` may **not** contain a ``.`` or a ``/`` due to :ref:`Key Splitting`.
Expand Down
8 changes: 8 additions & 0 deletions docs/source/Overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ object and use it to decorate functions.
return 2 * x
# Assigning as you would a dictionary also works
def baz(x):
return 3 * x
my_registry["baz"] = baz # The key could be any string.
# You can also register classes this way.
@my_registry
class Baz:
Expand Down
14 changes: 14 additions & 0 deletions tests/test_classes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest
from common import construct_pokemon_classes

import autoregistry
from autoregistry import Registry


Expand Down Expand Up @@ -81,6 +82,19 @@ def test_defaults_get():
assert Pokemon.get("foo", Charmander) == Charmander


def test_classes_setitem_exception():
"""Don't allow setting items for a Registry subclass since it breaks the hierarchy."""

class Foo(Registry):
pass

def bar():
pass

with pytest.raises(autoregistry.RegistryError):
Foo["bar"] = bar


def test_multiple_inheritence_last():
class Foo:
pass
Expand Down
21 changes: 21 additions & 0 deletions tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,27 @@ def bar():
assert list(registry) == ["bar"]


def test_registry_dictionary_assign():
registry = Registry()

def bar():
pass

registry["foo"] = bar
assert registry["foo"] == bar


def test_registry_dictionary_assign_collision():
registry = Registry()

def bar():
pass

registry["foo"] = bar
with pytest.raises(autoregistry.KeyCollisionError):
registry["foo"] = bar


def test_registry_module_alias():
import fake_module

Expand Down

0 comments on commit d1739ab

Please sign in to comment.