summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-11-30 13:55:02 -0500
committerChris McDonough <chrism@plope.com>2011-11-30 13:55:02 -0500
commit57a9d679eb78e774c271bf68f6e805dc2b8186c4 (patch)
tree66991b16bcfd3394669ff9556576e017bbc5d3da
parent82ba1088e98d6e33136b5e78f87ac02d0daa7879 (diff)
downloadpyramid-57a9d679eb78e774c271bf68f6e805dc2b8186c4.tar.gz
pyramid-57a9d679eb78e774c271bf68f6e805dc2b8186c4.tar.bz2
pyramid-57a9d679eb78e774c271bf68f6e805dc2b8186c4.zip
add tests for introspectable; add more interface docs and expose actioninfo
-rw-r--r--docs/api/interfaces.rst2
-rw-r--r--pyramid/interfaces.py27
-rw-r--r--pyramid/registry.py29
-rw-r--r--pyramid/tests/test_registry.py93
4 files changed, 125 insertions, 26 deletions
diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst
index 64f2773d3..5b190b53b 100644
--- a/docs/api/interfaces.rst
+++ b/docs/api/interfaces.rst
@@ -74,3 +74,5 @@ Other Interfaces
.. autointerface:: IIntrospector
:members:
+ .. autointerface:: IActionInfo
+ :members:
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index 6bb0c6738..2576b4e35 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -897,11 +897,10 @@ class IIntrospector(Interface):
an error if an introspectable related to the category name and
discriminator does not exist."""
- def related(category_name, discriminator):
+ def related(intr):
""" Return a sequence of IIntrospectables related to the
- IIntrospectable associated with (``category_name``,
- ``discriminator``). Return the empty sequence if no relations for
- exist."""
+ IIntrospectable ``intr``. Return the empty sequence if no relations
+ for exist."""
def add(intr):
""" Add the IIntrospectable ``intr`` (use instead of
@@ -968,14 +967,14 @@ class IIntrospectable(Interface):
the ``category_name`` and ``discriminator``) during action execution.
"""
- def register(introspector, action_info=''):
+ def register(introspector, action_info):
""" Register this IIntrospectable with an introspector. This method
is invoked during action execution. Adds the introspectable and its
- relations to the introspector. ``introspector`` should be an
- object implementing IIntrospector. ``action_info`` should be a
- string representing the call that registered this introspectable
- (e.g. with line numbers, etc). Pseudocode for an implementation of
- this method:
+ relations to the introspector. ``introspector`` should be an object
+ implementing IIntrospector. ``action_info`` should be a object
+ implementing the interface :class:`pyramid.interfaces.IActionInfo`
+ representing the call that registered this introspectable.
+ Pseudocode for an implementation of this method:
.. code-block:: python
@@ -996,6 +995,14 @@ class IIntrospectable(Interface):
return hash((self.category_name,) + (self.discriminator,))
"""
+class IActionInfo(Interface):
+ filename = Attribute('filename as a string')
+ lineno = Attribute('line number in file as an integer')
+ function = Attribute('a string representing the function or method '
+ 'that was executing')
+ linerepr = Attribute('a string representing the call site '
+ 'which caused the action to be executed')
+
# configuration phases: a lower phase number means the actions associated
# with this phase will be executed earlier than those with later phase
# numbers. The default phase number is 0, FTR.
diff --git a/pyramid/registry.py b/pyramid/registry.py
index 813cde715..a6d70bfa8 100644
--- a/pyramid/registry.py
+++ b/pyramid/registry.py
@@ -170,7 +170,7 @@ class Introspector(object):
class Introspectable(dict):
order = 0 # mutated by introspector.add
- action_info = None # mutated by introspectable.register
+ action_info = None # mutated by self.register
def __init__(self, category_name, discriminator, title, type_name):
self.category_name = category_name
@@ -185,19 +185,6 @@ class Introspectable(dict):
def unrelate(self, category_name, discriminator):
self._relations.append((False, category_name, discriminator))
- def register(self, introspector, action_info):
- self.action_info = action_info
- introspector.add(self)
- for relate, category_name, discriminator in self._relations:
- if relate:
- method = introspector.relate
- else:
- method = introspector.unrelate
- method(
- (self.category_name, self.discriminator),
- (category_name, discriminator)
- )
-
@property
def discriminator_hash(self):
return hash(self.discriminator)
@@ -215,4 +202,18 @@ class Introspectable(dict):
__bool__ = __nonzero__ # py3
+ def register(self, introspector, action_info):
+ self.action_info = action_info
+ introspector.add(self)
+ for relate, category_name, discriminator in self._relations:
+ if relate:
+ method = introspector.relate
+ else:
+ method = introspector.unrelate
+ method(
+ (self.category_name, self.discriminator),
+ (category_name, discriminator)
+ )
+
+
global_registry = Registry('global')
diff --git a/pyramid/tests/test_registry.py b/pyramid/tests/test_registry.py
index 5b2152d3a..3d68688d1 100644
--- a/pyramid/tests/test_registry.py
+++ b/pyramid/tests/test_registry.py
@@ -43,9 +43,19 @@ class TestRegistry(unittest.TestCase):
self.assertEqual(registry._settings, 'foo')
class TestIntrospector(unittest.TestCase):
- def _makeOne(self):
+ def _getTargetClass(slf):
from pyramid.registry import Introspector
- return Introspector()
+ return Introspector
+
+ def _makeOne(self):
+ return self._getTargetClass()()
+
+ def test_conformance(self):
+ from zope.interface.verify import verifyClass
+ from zope.interface.verify import verifyObject
+ from pyramid.interfaces import IIntrospector
+ verifyClass(IIntrospector, self._getTargetClass())
+ verifyObject(IIntrospector, self._makeOne())
def test_add(self):
inst = self._makeOne()
@@ -240,6 +250,85 @@ class TestIntrospector(unittest.TestCase):
del inst._categories['category']
self.assertRaises(KeyError, inst.related, intr)
+class TestIntrospectable(unittest.TestCase):
+ def _getTargetClass(slf):
+ from pyramid.registry import Introspectable
+ return Introspectable
+
+ def _makeOne(self, *arg, **kw):
+ return self._getTargetClass()(*arg, **kw)
+
+ def _makeOnePopulated(self):
+ return self._makeOne('category', 'discrim', 'title', 'type')
+
+ def test_conformance(self):
+ from zope.interface.verify import verifyClass
+ from zope.interface.verify import verifyObject
+ from pyramid.interfaces import IIntrospectable
+ verifyClass(IIntrospectable, self._getTargetClass())
+ verifyObject(IIntrospectable, self._makeOnePopulated())
+
+ def test_relate(self):
+ inst = self._makeOnePopulated()
+ inst.relate('a', 'b')
+ self.assertEqual(inst._relations, [(True, 'a', 'b')])
+
+ def test_unrelate(self):
+ inst = self._makeOnePopulated()
+ inst.unrelate('a', 'b')
+ self.assertEqual(inst._relations, [(False, 'a', 'b')])
+
+ def test_discriminator_hash(self):
+ inst = self._makeOnePopulated()
+ self.assertEqual(inst.discriminator_hash, hash(inst.discriminator))
+
+ def test___hash__(self):
+ inst = self._makeOnePopulated()
+ self.assertEqual(hash(inst),
+ hash((inst.category_name,) + (inst.discriminator,)))
+
+ def test___repr__(self):
+ inst = self._makeOnePopulated()
+ self.assertEqual(
+ repr(inst),
+ "<Introspectable category 'category', discriminator 'discrim'>")
+
+ def test___nonzero__(self):
+ inst = self._makeOnePopulated()
+ self.assertEqual(inst.__nonzero__(), True)
+
+ def test___bool__(self):
+ inst = self._makeOnePopulated()
+ self.assertEqual(inst.__bool__(), True)
+
+ def test_register(self):
+ introspector = DummyIntrospector()
+ action_info = object()
+ inst = self._makeOnePopulated()
+ inst._relations.append((True, 'category1', 'discrim1'))
+ inst._relations.append((False, 'category2', 'discrim2'))
+ inst.register(introspector, action_info)
+ self.assertEqual(inst.action_info, action_info)
+ self.assertEqual(introspector.intrs, [inst])
+ self.assertEqual(introspector.relations,
+ [(('category', 'discrim'), ('category1', 'discrim1'))])
+ self.assertEqual(introspector.unrelations,
+ [(('category', 'discrim'), ('category2', 'discrim2'))])
+
+class DummyIntrospector(object):
+ def __init__(self):
+ self.intrs = []
+ self.relations = []
+ self.unrelations = []
+
+ def add(self, intr):
+ self.intrs.append(intr)
+
+ def relate(self, *pairs):
+ self.relations.append(pairs)
+
+ def unrelate(self, *pairs):
+ self.unrelations.append(pairs)
class DummyModule:
__path__ = "foo"