Skip to content

Commit

Permalink
:add: deep search of annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
b3j0f committed Sep 20, 2016
1 parent 56549fb commit e543f39
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 7 deletions.
4 changes: 2 additions & 2 deletions README.rst
Expand Up @@ -86,8 +86,8 @@ Perspectives
Donation
--------

.. image:: https://cdn.rawgit.com/gratipay/gratipay-badge/2.3.0/dist/gratipay.png
:target: https://gratipay.com/b3j0f/
.. image:: https://liberapay.com/assets/widgets/donate.svg
:target: https://liberapay.com/b3j0f/donate
:alt: I'm grateful for gifts, but don't have a specific funding goal.

.. _Homepage: https://github.com/b3j0f/annotation
Expand Down
40 changes: 36 additions & 4 deletions b3j0f/annotation/core.py
Expand Up @@ -519,7 +519,9 @@ def remove(cls, target, exclude=None, ctx=None, select=lambda *p: True):

@classmethod
def get_annotations(
cls, target, exclude=None, ctx=None, select=lambda *p: True
cls, target,
exclude=None, ctx=None, select=lambda *p: True,
depth=1, followannotated=True, public=True, _history=None
):
"""Returns all input target annotations of cls type sorted
by definition order.
Expand All @@ -531,13 +533,23 @@ def get_annotations(
:param select: bool function which select annotations after applying
previous type filters. Takes a target, a ctx and an annotation in
parameters. True by default.
:param int depth: depth for searching annotations.
:param bool followannotated: if True (default) follow deeply only
annotated members.
:param bool public: if True (default) follow public members.
:param list _history: private parameter which save parsed elements.
:rtype: Annotation
"""

result = []

annotations_by_ctx = get_property(
elt=target, key=Annotation.__ANNOTATIONS_KEY__, ctx=ctx
)
try:
annotations_by_ctx = get_property(
elt=target, key=Annotation.__ANNOTATIONS_KEY__, ctx=ctx
)

except TypeError:
annotations_by_ctx = {}

if not annotations_by_ctx:
if ismethod(target):
Expand Down Expand Up @@ -582,6 +594,26 @@ def get_annotations(

result.append(annotation)

if depth > 1 and (result or not followannotated):

if _history is None:
_history = [target]

else:
_history.append(target)

for name, member in getmembers(target):
if (name[0] != '_' or not public) and member not in _history:

if ismethod(target) and name.startswith('im_'):
continue

result += cls.get_annotations(
target=member, exclude=exclude, ctx=ctx, select=select,
depth=depth-1, followannotated=followannotated,
_history=_history
)

return result

@classmethod
Expand Down
72 changes: 72 additions & 0 deletions b3j0f/annotation/test/core.py
Expand Up @@ -567,6 +567,78 @@ def __init__(self):

self.assertTrue(annotations)

def test_depthsearch(self):

annotations = [Annotation() for _ in range(4)]
annotation0 = annotations[0]
annotation1 = annotations[1]
annotation2 = annotations[2]
annotation3 = annotations[3]

@annotation0
class Test0(object):

@annotation0
@annotation1
class Test1(object):

class Test(object):

@annotation3
def test(self):
pass

@annotation2
class Test2(object):

pass

@annotation1
def test1(self):
pass

_annotations = Annotation.get_annotations(Test0, depth=5)

self.assertEqual(len(_annotations), 5)
self.assertNotIn(annotation3, _annotations)

def test_depthsearchnotfollowannotated(self):

annotations = [Annotation() for _ in range(4)]
annotation0 = annotations[0]
annotation1 = annotations[1]
annotation2 = annotations[2]
annotation3 = annotations[3]

@annotation0
class Test0(object):

@annotation0
@annotation1
class Test1(object):

class Test(object):

@annotation3
def test(self):
pass

@annotation2
class Test2(object):

pass

@annotation1
def test1(self):
pass

_annotations = Annotation.get_annotations(
Test0, depth=5, followannotated=False
)

self.assertEqual(len(_annotations), 6)
self.assertIn(annotation3, _annotations)


class GetLocalAnnotationsTest(AnnotationTest):
"""Test get local annotatations."""
Expand Down
2 changes: 1 addition & 1 deletion b3j0f/annotation/version.py
Expand Up @@ -33,4 +33,4 @@
# thanks to https://github.com/pycontribs/jira/blob/master/jira/version.py

#: project version
__version__ = '0.3.4'
__version__ = '0.3.5'
5 changes: 5 additions & 0 deletions changelog.rst
@@ -1,6 +1,11 @@
Changelog
=========

0.3.5 (2016/09/20)
------------------

- add depth parameter in searching deeply annotations.

0.3.4 (2016/06/06)
------------------

Expand Down

0 comments on commit e543f39

Please sign in to comment.