summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2010-10-26 00:44:36 -0400
committerChris McDonough <chrism@plope.com>2010-10-26 00:44:36 -0400
commit8edaacf0a0dbb96b1444cdb8fe4ce1538fb7b92d (patch)
tree6f7045cc3dcacdda03c7b1b7956a5003206f3a68
parentd9c9241ecd71754b15d82fa61405413ec2699ff2 (diff)
downloadpyramid-8edaacf0a0dbb96b1444cdb8fe4ce1538fb7b92d.tar.gz
pyramid-8edaacf0a0dbb96b1444cdb8fe4ce1538fb7b92d.tar.bz2
pyramid-8edaacf0a0dbb96b1444cdb8fe4ce1538fb7b92d.zip
readd make_app (karl depends on it)
-rw-r--r--docs/api.rst1
-rw-r--r--docs/api/router.rst8
-rw-r--r--docs/latexindex.rst1
-rw-r--r--docs/tutorials/bfg/index.rst42
-rw-r--r--pyramid/configuration.py56
-rw-r--r--pyramid/router.py5
-rw-r--r--pyramid/tests/test_configuration.py68
7 files changed, 180 insertions, 1 deletions
diff --git a/docs/api.rst b/docs/api.rst
index a4d853942..8d93ff450 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -22,6 +22,7 @@ documentation is organized alphabetically by module name.
api/paster
api/renderers
api/request
+ api/router
api/scripting
api/security
api/settings
diff --git a/docs/api/router.rst b/docs/api/router.rst
new file mode 100644
index 000000000..e5ffe97ce
--- /dev/null
+++ b/docs/api/router.rst
@@ -0,0 +1,8 @@
+.. _router_module:
+
+:mod:`pyramid.router`
+---------------------
+
+.. automodule:: pyramid.router
+
+.. autofunction:: pyramid.router.make_app(root_factory, package=None, filename='configure.zcml', settings=None)
diff --git a/docs/latexindex.rst b/docs/latexindex.rst
index 493aa8232..10cca4401 100644
--- a/docs/latexindex.rst
+++ b/docs/latexindex.rst
@@ -93,6 +93,7 @@ API Reference
api/paster
api/renderers
api/request
+ api/router
api/scripting
api/security
api/settings
diff --git a/docs/tutorials/bfg/index.rst b/docs/tutorials/bfg/index.rst
index 4689831fa..efced23fb 100644
--- a/docs/tutorials/bfg/index.rst
+++ b/docs/tutorials/bfg/index.rst
@@ -96,8 +96,16 @@ Here's how to convert a :mod:`repoze.bfg` application to a
converted recursively, except Python files which live in
directories which start with a ``.`` (dot).
+ - Each ZCML file found (recursively) within the path will have the
+ default ``xmlns`` attribute attached to the ``configure`` tag
+ changed from ``http://namespaces.repoze.org/bfg`` to
+ ``http://pylonshq.com/pyramid``. Every ZCML file beneath the
+ top-level path (files ending with ``.zcml``) will be visited and
+ converted recursively, except ZCML files which live in
+ directories which start with a ``.`` (dot).
+
- ZCML files which contain directives that have attributes which
- name ``repoze.bfg``
+ name a ``repoze.bfg`` API module or attribute of an API module
(e.g. ``context="repoze.bfg.exceptions.NotFound"``) will be
converted to :mod:`pyramid` compatible ZCML attributes
(e.g. ``context="pyramid.exceptions.NotFound``). Every ZCML file
@@ -136,6 +144,38 @@ Here's how to convert a :mod:`repoze.bfg` application to a
the documentation of the :mod:`pyramid` add-on package for
information.
+#. *Only if you use ZCML and add-ons which use ZCML*: The default
+ ``xmlns`` of the ``configure`` tag in ZCML has changed. The
+ ``bfg2pyramid`` script effects the default namespace change (it
+ changes the ``configure`` tag default ``xmlns`` from
+ ``http://namespaces.repoze.org/bfg`` to
+ ``http://pylonshq.com/pyramid``).
+
+ This means that uses of add-ons which define ZCML directives in the
+ ``http://namespaces.repoze.org/bfg`` namespace will begin to "fail"
+ (they're actually not really failing, but your ZCML assumes that
+ they will always be used within a ``configure`` tag which names the
+ ``http://namespaces.repoze.org/bfg`` namespace as its default
+ ``xmlns``). Symptom: when you attempt to start the application, an
+ error such as ``ConfigurationError: ('Unknown directive',
+ u'http://namespaces.repoze.org/bfg', u'workflow')`` is printed to
+ the console and the application fails to start. In such a case,
+ either add an ``xmlns="http://namespaces.repoze.org/bfg"``
+ attribute to each tag which causes a failure, or define a namespace
+ alias in the configure tag and prefix each failing tag. For
+ example, change this "failing" tag instance::
+
+ <configure xmlns="http://pylonshq.com/pyramid">
+ <failingtag attr="foo"/>
+ </configure>
+
+ To this, which will begin to succeed::
+
+ <configure xmlns="http://pylonshq.com/pyramid"
+ xmlns:bfg="http://namespaces.repoze.org/bfg">
+ <bfg:failingtag attr="foo"/>
+ </configure>
+
#. Retest your application using :mod:`pyramid`. This might be as
easy as:
diff --git a/pyramid/configuration.py b/pyramid/configuration.py
index ecb7cc9da..3589cbede 100644
--- a/pyramid/configuration.py
+++ b/pyramid/configuration.py
@@ -2452,6 +2452,62 @@ def isexception(o):
(inspect.isclass(o) and (issubclass(o, Exception)))
)
+# note that ``options`` is a b/w compat alias for ``settings`` and
+# ``Configurator`` is a testing dep inj
+def make_app(root_factory, package=None, filename='configure.zcml',
+ settings=None, options=None, Configurator=Configurator):
+ """ Return a Router object, representing a fully configured
+ :mod:`pyramid` WSGI application.
+
+ .. warning:: Use of this function is deprecated as of
+ :mod:`pyramid` 1.0. You should instead use a
+ :class:`pyramid.configuration.Configurator` instance to
+ perform startup configuration as shown in
+ :ref:`configuration_narr`.
+
+ ``root_factory`` must be a callable that accepts a :term:`request`
+ object and which returns a traversal root object. The traversal
+ root returned by the root factory is the *default* traversal root;
+ it can be overridden on a per-view basis. ``root_factory`` may be
+ ``None``, in which case a 'default default' traversal root is
+ used.
+
+ ``package`` is a Python :term:`package` or module representing the
+ application's package. It is optional, defaulting to ``None``.
+ ``package`` may be ``None``. If ``package`` is ``None``, the
+ ``filename`` passed or the value in the ``options`` dictionary
+ named ``configure_zcml`` must be a) absolute pathname to a
+ :term:`ZCML` file that represents the application's configuration
+ *or* b) a :term:`resource specification` to a :term:`ZCML` file in
+ the form ``dotted.package.name:relative/file/path.zcml``.
+
+ ``filename`` is the filesystem path to a ZCML file (optionally
+ relative to the package path) that should be parsed to create the
+ application registry. It defaults to ``configure.zcml``. It can
+ also be a ;term:`resource specification` in the form
+ ``dotted_package_name:relative/file/path.zcml``. Note that if any
+ value for ``configure_zcml`` is passed within the ``settings``
+ dictionary, the value passed as ``filename`` will be ignored,
+ replaced with the ``configure_zcml`` value.
+
+ ``settings``, if used, should be a dictionary containing runtime
+ settings (e.g. the key/value pairs in an app section of a
+ PasteDeploy file), with each key representing the option and the
+ key's value representing the specific option value,
+ e.g. ``{'reload_templates':True}``. Note that the keyword
+ parameter ``options`` is a backwards compatibility alias for the
+ ``settings`` keyword parameter.
+ """
+ settings = settings or options or {}
+ zcml_file = settings.get('configure_zcml', filename)
+ config = Configurator(package=package, settings=settings,
+ root_factory=root_factory)
+ config.hook_zca()
+ config.begin()
+ config.load_zcml(zcml_file)
+ config.end()
+ return config.make_wsgi_app()
+
class DottedNameResolver(object):
""" This class resolves dotted name references to 'global' Python
objects (objects which can be imported) to those objects.
diff --git a/pyramid/router.py b/pyramid/router.py
index 3ec23c3e4..038bed6d6 100644
--- a/pyramid/router.py
+++ b/pyramid/router.py
@@ -23,6 +23,11 @@ from pyramid.threadlocal import manager
from pyramid.traversal import DefaultRootFactory
from pyramid.traversal import ModelGraphTraverser
+from pyramid.configuration import make_app # b/c
+
+make_app # prevent PyFlakes from complaining
+
+
class Router(object):
implements(IRouter)
diff --git a/pyramid/tests/test_configuration.py b/pyramid/tests/test_configuration.py
index f3958c7de..913476a7b 100644
--- a/pyramid/tests/test_configuration.py
+++ b/pyramid/tests/test_configuration.py
@@ -3927,6 +3927,50 @@ class TestRequestOnly(unittest.TestCase):
foo = Foo()
self.assertFalse(self._callFUT(foo))
+class TestMakeApp(unittest.TestCase):
+ def setUp(self):
+ testing.setUp()
+
+ def tearDown(self):
+ testing.tearDown()
+
+ def _callFUT(self, *arg, **kw):
+ from pyramid.configuration import make_app
+ return make_app(*arg, **kw)
+
+ def test_it(self):
+ settings = {'a':1}
+ rootfactory = object()
+ app = self._callFUT(rootfactory, settings=settings,
+ Configurator=DummyConfigurator)
+ self.assertEqual(app.root_factory, rootfactory)
+ self.assertEqual(app.settings, settings)
+ self.assertEqual(app.zcml_file, 'configure.zcml')
+ self.assertEqual(app.zca_hooked, True)
+
+ def test_it_options_means_settings(self):
+ settings = {'a':1}
+ rootfactory = object()
+ app = self._callFUT(rootfactory, options=settings,
+ Configurator=DummyConfigurator)
+ self.assertEqual(app.root_factory, rootfactory)
+ self.assertEqual(app.settings, settings)
+ self.assertEqual(app.zcml_file, 'configure.zcml')
+
+ def test_it_with_package(self):
+ package = object()
+ rootfactory = object()
+ app = self._callFUT(rootfactory, package=package,
+ Configurator=DummyConfigurator)
+ self.assertEqual(app.package, package)
+
+ def test_it_with_custom_configure_zcml(self):
+ rootfactory = object()
+ settings = {'configure_zcml':'2.zcml'}
+ app = self._callFUT(rootfactory, filename='1.zcml', settings=settings,
+ Configurator=DummyConfigurator)
+ self.assertEqual(app.zcml_file, '2.zcml')
+
class TestDottedNameResolver(unittest.TestCase):
def _makeOne(self, package=None):
from pyramid.configuration import DottedNameResolver
@@ -4202,6 +4246,30 @@ class DummySecurityPolicy:
def permits(self, context, principals, permission):
return self.permitted
+class DummyConfigurator(object):
+ def __init__(self, registry=None, package=None, root_factory=None,
+ settings=None):
+ self.root_factory = root_factory
+ self.package = package
+ self.settings = settings
+
+ def begin(self, request=None):
+ self.begun = True
+ self.request = request
+
+ def end(self):
+ self.ended = True
+
+ def load_zcml(self, filename):
+ self.zcml_file = filename
+
+ def make_wsgi_app(self):
+ return self
+
+ def hook_zca(self):
+ self.zca_hooked = True
+
+
class DummyAccept(object):
def __init__(self, *matches):
self.matches = list(matches)