From 0291e21a746ba45e858f747d22630dacc00b5e1f Mon Sep 17 00:00:00 2001 From: Federico Caselli Date: Tue, 27 Aug 2024 18:13:04 +0200 Subject: [PATCH 1/2] fix: avoid infinite recursion on attribute access in GenericActors. this was triggered by sphinx autodoc use of inspect.signature that tried to access the missing `__signature__` attribute on GenericActors --- docs/source/conf.py | 4 ++-- dramatiq/generic.py | 3 +++ tests/test_generic_actors.py | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 0036d0f8..84f0a974 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -18,11 +18,11 @@ import alabaster # noqa -import dramatiq # noqa - sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath('./')) +import dramatiq # noqa + # -- General configuration ------------------------------------------------ diff --git a/dramatiq/generic.py b/dramatiq/generic.py index b72244e5..d993ee5b 100644 --- a/dramatiq/generic.py +++ b/dramatiq/generic.py @@ -40,6 +40,9 @@ def __new__(metacls, name, bases, attrs): return clazz def __getattr__(cls, name): + if '__actor__' not in cls.__dict__: + # avoid infinite recursion on GenericActor + raise AttributeError(f"type object '{cls.__name__}' has no attribute '{name}'") return getattr(cls.__actor__, name) diff --git a/tests/test_generic_actors.py b/tests/test_generic_actors.py index c697a770..f35a81a6 100644 --- a/tests/test_generic_actors.py +++ b/tests/test_generic_actors.py @@ -117,3 +117,8 @@ def perform(self): # And the actor registry should be called with CustomActor actor_registry.assert_called_once_with(CustomActor) + + +def test_getattr_generic_actor(): + with pytest.raises(AttributeError): + dramatiq.GenericActor.missing_property \ No newline at end of file From f3dc0bb30a687e3847a2b598f9b4994230f1dda6 Mon Sep 17 00:00:00 2001 From: Federico Caselli Date: Tue, 27 Aug 2024 18:17:34 +0200 Subject: [PATCH 2/2] style: fix linter errors --- dramatiq/generic.py | 4 ++-- tests/test_generic_actors.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dramatiq/generic.py b/dramatiq/generic.py index d993ee5b..6ad79e90 100644 --- a/dramatiq/generic.py +++ b/dramatiq/generic.py @@ -40,9 +40,9 @@ def __new__(metacls, name, bases, attrs): return clazz def __getattr__(cls, name): - if '__actor__' not in cls.__dict__: + if "__actor__" not in cls.__dict__: # avoid infinite recursion on GenericActor - raise AttributeError(f"type object '{cls.__name__}' has no attribute '{name}'") + raise AttributeError(f"type object {cls.__name__!r} has no attribute {name!r}") return getattr(cls.__actor__, name) diff --git a/tests/test_generic_actors.py b/tests/test_generic_actors.py index f35a81a6..cca25fd4 100644 --- a/tests/test_generic_actors.py +++ b/tests/test_generic_actors.py @@ -121,4 +121,4 @@ def perform(self): def test_getattr_generic_actor(): with pytest.raises(AttributeError): - dramatiq.GenericActor.missing_property \ No newline at end of file + dramatiq.GenericActor.missing_property