Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply class decorators to all consumer methods #138

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions tests/unit/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,26 @@ class DummyAnnotation(decorators.MethodAnnotation):
def test_call_with_child_class(
self, method_annotation, request_definition_builder
):
class Parent(object):
class Parent(interfaces.Consumer):
builder = request_definition_builder

class Child(Parent):
pass

# Method annotation should not decorate RequestDefinitionBuilder
# attribute of parent class (e.g., `Parent.builder`).
# Method annotation should decorate RequestDefinitionBuilder attribute
# of parent class (e.g., `Parent.builder`).
method_annotation(Child)
builder = request_definition_builder.method_handler_builder
assert builder.add_annotation.called

def test_no_call_on_non_consumer(
self, method_annotation, request_definition_builder
):
class Class(object):
builder = request_definition_builder

method_annotation(Class)
builder = request_definition_builder.method_handler_builder
assert not builder.add_annotation.called


Expand Down
3 changes: 2 additions & 1 deletion tests/unit/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class Child(Parent):
other_builder = request_definition_builder

assert dict(helpers.get_api_definitions(Child)) == {
"other_builder": request_definition_builder
"builder": request_definition_builder,
"other_builder": request_definition_builder,
}


Expand Down
6 changes: 2 additions & 4 deletions uplink/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ def get_api_definitions(service):
class.

Note:
Only attributes defined directly on the class are considered. In
other words, inherited `RequestDefinitionBuilder` attributes
are ignored.
All attributes are considered, not only defined directly on the class.

Args:
service: A class object.
Expand All @@ -28,7 +26,7 @@ def get_api_definitions(service):
# report in Python issue tracker). Directly invoking `getattr` to
# force Python's attribute lookup protocol is a decent workaround to
# ensure parity:
class_attributes = ((k, getattr(service, k)) for k in service.__dict__)
class_attributes = ((k, getattr(service, k)) for k in dir(service))

is_definition = interfaces.RequestDefinitionBuilder.__instancecheck__
return [(k, v) for k, v in class_attributes if is_definition(v)]
Expand Down