summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-12-07 21:43:04 -0500
committerChris McDonough <chrism@plope.com>2010-12-07 21:43:04 -0500
commit446967a9e2f682ca523cbcaa1e8ac4b009331ec5 (patch)
tree6ce94bec1d0a4504df212aae60a120f06daca6a3
parentad493deb36497518f982ab50a2ffb88803b96949 (diff)
downloadpyramid-446967a9e2f682ca523cbcaa1e8ac4b009331ec5.tar.gz
pyramid-446967a9e2f682ca523cbcaa1e8ac4b009331ec5.tar.bz2
pyramid-446967a9e2f682ca523cbcaa1e8ac4b009331ec5.zip
add an integration test for include, make sure the same callable is not processed more than once
-rw-r--r--pyramid/configuration.py27
-rw-r--r--pyramid/tests/includeapp1/__init__.py1
-rw-r--r--pyramid/tests/includeapp1/root.py10
-rw-r--r--pyramid/tests/includeapp1/three.py9
-rw-r--r--pyramid/tests/includeapp1/two.py9
-rw-r--r--pyramid/tests/test_configuration.py42
-rw-r--r--pyramid/tests/test_integration.py26
7 files changed, 118 insertions, 6 deletions
diff --git a/pyramid/configuration.py b/pyramid/configuration.py
index 2135c6d57..8cdb7512b 100644
--- a/pyramid/configuration.py
+++ b/pyramid/configuration.py
@@ -389,6 +389,7 @@ class Configurator(object):
def _make_context(self):
context = PyramidConfigurationMachine()
registerCommonDirectives(context)
+ context.registry = self.registry
return context
# API
@@ -397,7 +398,6 @@ class Configurator(object):
""" Commit pending configuration actions. """
self._ctx.execute_actions()
self._ctx = self._make_context()
- self._ctx.registry = self.registry
def with_package(self, package, _ctx=None):
""" Return a new Configurator instance with the same registry
@@ -746,11 +746,13 @@ class Configurator(object):
_context = self._ctx
for filename, func, module in sourcefiles:
- context = GroupingContextDecorator(_context)
- context.basepath = os.path.dirname(filename)
- context.includepath = _context.includepath + (filename,)
- context.package = package_of(module)
- func(Configurator.with_context(context))
+ spec = module.__name__ + ':' + func.__name__
+ if _context.processSpec(spec):
+ context = GroupingContextDecorator(_context)
+ context.basepath = os.path.dirname(filename)
+ context.includepath = _context.includepath + (spec,)
+ context.package = package_of(module)
+ func(Configurator.with_context(context))
def add_handler(self, route_name, pattern, handler, action=None, **kw):
@@ -2894,3 +2896,16 @@ class PyramidConfigurationMachine(ConfigurationMachine):
except:
return ''
+ def processSpec(self, spec):
+ """Check whether a callable needs to be processed. The ``spec``
+ refers to a unique identifier for the callable.
+
+ Return True if processing is needed and False otherwise. If
+ the callablke needs to be processed, it will be marked as
+ processed, assuming that the caller will procces the callable if
+ it needs to be processed.
+ """
+ if spec in self._seen_files:
+ return False
+ self._seen_files.add(spec)
+ return True
diff --git a/pyramid/tests/includeapp1/__init__.py b/pyramid/tests/includeapp1/__init__.py
new file mode 100644
index 000000000..eaeeb7ef6
--- /dev/null
+++ b/pyramid/tests/includeapp1/__init__.py
@@ -0,0 +1 @@
+# include app
diff --git a/pyramid/tests/includeapp1/root.py b/pyramid/tests/includeapp1/root.py
new file mode 100644
index 000000000..3b042c8c2
--- /dev/null
+++ b/pyramid/tests/includeapp1/root.py
@@ -0,0 +1,10 @@
+from pyramid.response import Response
+
+def aview(request):
+ return Response('root')
+
+def configure(config):
+ config.add_view(aview)
+ config.include('pyramid.tests.includeapp1.two.configure')
+ config.commit()
+
diff --git a/pyramid/tests/includeapp1/three.py b/pyramid/tests/includeapp1/three.py
new file mode 100644
index 000000000..a921bcd10
--- /dev/null
+++ b/pyramid/tests/includeapp1/three.py
@@ -0,0 +1,9 @@
+from pyramid.response import Response
+
+def aview(request):
+ return Response('three')
+
+def configure(config):
+ config.add_view(aview, name='three')
+ config.add_view(aview) # will be overridden by root when resolved
+
diff --git a/pyramid/tests/includeapp1/two.py b/pyramid/tests/includeapp1/two.py
new file mode 100644
index 000000000..960d77e3d
--- /dev/null
+++ b/pyramid/tests/includeapp1/two.py
@@ -0,0 +1,9 @@
+from pyramid.response import Response
+
+def aview(request):
+ return Response('two')
+
+def configure(config):
+ config.add_view(aview, name='two')
+ config.include('pyramid.tests.includeapp1.three.configure')
+ config.add_view(aview) # will be overridden by root when resolved
diff --git a/pyramid/tests/test_configuration.py b/pyramid/tests/test_configuration.py
index 488be73eb..21f6a4f44 100644
--- a/pyramid/tests/test_configuration.py
+++ b/pyramid/tests/test_configuration.py
@@ -3442,6 +3442,48 @@ class ConfiguratorTests(unittest.TestCase):
config.add_view(view2)
self.assertRaises(ConfigurationConflictError, config.commit)
+ def test_commit_conflict_resolved_with_include(self):
+ config = self._makeOne()
+ def view1(request): pass
+ def view2(request): pass
+ def includeme(config):
+ config.add_view(view2)
+ config.add_view(view1)
+ config.include(includeme)
+ config.commit()
+ registeredview = self._getViewCallable(config)
+ self.assertEqual(registeredview.__name__, 'view1')
+
+ def test_commit_conflict_with_two_includes(self):
+ from zope.configuration.config import ConfigurationConflictError
+ config = self._makeOne()
+ def view1(request): pass
+ def view2(request): pass
+ def includeme1(config):
+ config.add_view(view1)
+ def includeme2(config):
+ config.add_view(view2)
+ config.include(includeme1)
+ config.include(includeme2)
+ self.assertRaises(ConfigurationConflictError, config.commit)
+
+ def test_commit_conflict_resolved_with_two_includes_and_local(self):
+ from zope.configuration.config import ConfigurationConflictError
+ config = self._makeOne()
+ def view1(request): pass
+ def view2(request): pass
+ def view3(request): pass
+ def includeme1(config):
+ config.add_view(view1)
+ def includeme2(config):
+ config.add_view(view2)
+ config.include(includeme1)
+ config.include(includeme2)
+ config.add_view(view3)
+ config.commit()
+ registeredview = self._getViewCallable(config)
+ self.assertEqual(registeredview.__name__, 'view3')
+
class Test__map_view(unittest.TestCase):
def setUp(self):
from pyramid.registry import Registry
diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py
index 9e9ea78b2..7dc74aaf8 100644
--- a/pyramid/tests/test_integration.py
+++ b/pyramid/tests/test_integration.py
@@ -241,6 +241,32 @@ class TestExceptionViewsApp(IntegrationBase):
res = self.testapp.get('/route_raise_exception4', status=200)
self.failUnless('whoa' in res.body)
+class ImperativeIncludeConfigurationTest(unittest.TestCase):
+ def setUp(self):
+ from pyramid.configuration import Configurator
+ config = Configurator()
+ from pyramid.tests.includeapp1.root import configure
+ configure(config)
+ app = config.make_wsgi_app()
+ from webtest import TestApp
+ self.testapp = TestApp(app)
+ self.config = config
+
+ def tearDown(self):
+ self.config.end()
+
+ def test_root(self):
+ res = self.testapp.get('/', status=200)
+ self.failUnless('root' in res.body)
+
+ def test_two(self):
+ res = self.testapp.get('/two', status=200)
+ self.failUnless('two' in res.body)
+
+ def test_three(self):
+ res = self.testapp.get('/three', status=200)
+ self.failUnless('three' in res.body)
+
class DummyContext(object):
pass