Skip to content

Commit

Permalink
fix: make class-based actors act more like normal classes
Browse files Browse the repository at this point in the history
Fixes #15
  • Loading branch information
Bogdanp committed Nov 21, 2017
1 parent 198377b commit 4ae2902
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
18 changes: 17 additions & 1 deletion dramatiq/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@ def __new__(cls, name, bases, attrs):
if not getattr(meta, "abstract", False):
options = {name: getattr(meta, name) for name in vars(meta) if not name.startswith("_")}
options.pop("abstract", False)
return actor(clazz(), **options)

clazz_instance = clazz()
actor_instance = actor(clazz_instance, **options)
setattr(clazz, "__getattr__", generic_actor.__getattr__)
setattr(clazz_instance, "__actor__", actor_instance)
return clazz_instance

setattr(meta, "abstract", False)
return clazz

def __getattr__(cls, name):
return getattr(cls.__actor__, name)


class GenericActor(metaclass=generic_actor):
"""Base-class for class-based actors.
Expand Down Expand Up @@ -54,6 +62,14 @@ class GenericActor(metaclass=generic_actor):
>>> FooTask.send()
>>> BarTask.send()
Attributes:
logger(Logger): The actor's logger.
broker(Broker): The broker this actor is bound to.
actor_name(str): The actor's name.
queue_name(str): The actor's queue.
priority(int): The actor's priority.
options(dict): Arbitrary options that are passed to the broker
and middleware.
"""

class Meta:
Expand Down
19 changes: 15 additions & 4 deletions tests/test_generic_actors.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ class Add(dramatiq.GenericActor):
def perform(self, x, y):
return x + y

# Then Add should be an instance of Actor
assert isinstance(Add, dramatiq.Actor)
# Then Add.__actor__ should be an instance of Actor
assert isinstance(Add.__actor__, dramatiq.Actor)

# And it should be callable
assert Add(1, 2) == 3
Expand Down Expand Up @@ -71,8 +71,8 @@ def get_task_name(self):

# Then both subclasses should be actors
# And they should inherit the parent's meta
assert isinstance(FooTask, dramatiq.Actor)
assert isinstance(BarTask, dramatiq.Actor)
assert isinstance(FooTask.__actor__, dramatiq.Actor)
assert isinstance(BarTask.__actor__, dramatiq.Actor)
assert FooTask.queue_name == BarTask.queue_name == "tasks"

# When I send both actors a message
Expand All @@ -84,3 +84,14 @@ def get_task_name(self):

# Then my calls database should contain both task names
assert calls == {"Foo", "Bar"}


def test_generic_actors_can_have_class_attributes(stub_broker):
# Given a generic actor with class attributes
class DoSomething(dramatiq.GenericActor):
STATUS_RUNNING = "running"
STATUS_DONE = "done"

# When I access one of it class attributes
# Then I should get back that attribute's value
assert DoSomething.STATUS_DONE == "done"

0 comments on commit 4ae2902

Please sign in to comment.