Skip to content

Commit

Permalink
Merge pull request #79 from tbr/master
Browse files Browse the repository at this point in the history
Enhancement for Provides decorator
  • Loading branch information
tcalmant authored May 5, 2017
2 parents 7746a43 + bedb3f8 commit 591f730
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
31 changes: 23 additions & 8 deletions pelix/ipopo/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,18 @@ def _get_specifications(specifications):
:return: A list of strings
:raise ValueError: Invalid specification found
"""
if not specifications:
if not specifications or specifications is object:
raise ValueError("No specifications given")
elif inspect.isclass(specifications):
# Get the name of the class
return [specifications.__name__]
if Provides.USE_MODULE_QUALNAME:
# Get the name of the class
if not specifications.__module__:
return [specifications.__qualname__]
else:
return [specifications.__module__ + "." + specifications.__qualname__]
else:
# Legacy behavior
return [specifications.__name__]
elif is_string(specifications):
# Specification name
specifications = specifications.strip()
Expand Down Expand Up @@ -814,7 +821,10 @@ class Bar(object):
HANDLER_ID = constants.HANDLER_PROVIDES
""" ID of the handler configured by this decorator """

def __init__(self, specifications, controller=None):
USE_MODULE_QUALNAME = False
""" Selects the methodology to generate a specification from a class. A value of False uses __name__ (legacy), while True enables __name__ + '.' + __qualname__ """

def __init__(self, specifications=None, controller=None):
"""
:param specifications: A list of provided interface(s) name(s)
(can't be empty)
Expand All @@ -834,7 +844,7 @@ def __init__(self, specifications, controller=None):
elif ' ' in controller:
raise ValueError("Controller name contains spaces")

self.__specifications = _get_specifications(specifications)
self.__specifications = specifications
self.__controller = controller

def __call__(self, clazz):
Expand All @@ -860,9 +870,14 @@ def __call__(self, clazz):

# Avoid duplicates (but keep the order)
filtered_specs = []
for spec in self.__specifications:
if spec not in filtered_specs:
filtered_specs.append(spec)
if not self.__specifications:
filtered_specs = _get_specifications(clazz.__bases__)
else:
# Avoid duplicates (but keep the order)
specs = _get_specifications(self.__specifications)
for spec in specs:
if spec not in filtered_specs:
filtered_specs.append(spec)

# Store the service information
config = context.set_handler_default(self.HANDLER_ID, [])
Expand Down
11 changes: 1 addition & 10 deletions tests/ipopo/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,21 +232,12 @@ class DummyClass(object):
def method():
pass

# Empty specification
for empty in (None, "", " "):
self.assertRaises(ValueError, decorators.Provides, empty)

# No error should be raised
log_off()
decorators.Provides("spec", empty)
log_on()

# Field name with a space
self.assertRaises(ValueError, decorators.Provides, "spec", "a space")

# Invalid specification type
for invalid in ([1, 2, 3], tuple((1, 2, 3)), 123):
self.assertRaises(ValueError, decorators.Provides, invalid)
self.assertRaises(ValueError, decorators._get_specifications, invalid)
self.assertRaises(ValueError, decorators.Provides, "spec", invalid)

# Invalid target
Expand Down

0 comments on commit 591f730

Please sign in to comment.