From 4e6973c658bd0cbbb569341f0135ab03aac0d99b Mon Sep 17 00:00:00 2001 From: Mike Orr Date: Tue, 14 Feb 2012 00:00:22 -0800 Subject: Add contributor. --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 050225b5b..a3c1ab35b 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -160,3 +160,5 @@ Contributors - Klee Dienes, 2011/10/30 - Michael Ryabushin, 2011/12/14 + +- Mike Orr, 2012/02/14 -- cgit v1.2.3 From 94c28eb885204f93222dcc0bb3340ae1514b62dd Mon Sep 17 00:00:00 2001 From: Mike Orr Date: Tue, 14 Feb 2012 00:17:46 -0800 Subject: Update Akhet definition. --- docs/glossary.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index 8307c0472..60920a73a 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -876,12 +876,11 @@ Glossary on the Jinja2 templating system. Akhet - Akhet is a Pyramid-based development environment which provides a - Pylons-esque scaffold which sports support for :term:`view handler` - application development, :term:`SQLAlchemy` support, :term:`Mako` - templating by default, and other Pylons-like features. See - http://docs.pylonsproject.org/projects/akhet/dev/index.html for more - information. + `Akhet `_ is a + Pyramid library and demo application with a Pylons-like feel. + It's most known for its former application scaffold, which helped + users transition from Pylons and those prefering a more Pylons-like API. + The scaffold has been retired but the demo plays a similar role. Pyramid Cookbook An additional documentation resource for Pyramid which presents topical, -- cgit v1.2.3 From 3885448eea74d4c79bf34dae0fb3a7fc767cb85c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 17 Feb 2012 20:58:12 -0500 Subject: docs rearranging / fixing --- docs/api/config.rst | 88 +++++++++++++++++++++++++++------------------------ docs/whatsnew-1.3.rst | 7 +--- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/docs/api/config.rst b/docs/api/config.rst index 3fc2cfc44..87ba94673 100644 --- a/docs/api/config.rst +++ b/docs/api/config.rst @@ -7,56 +7,27 @@ .. autoclass:: Configurator - .. attribute:: registry - - The :term:`application registry` which holds the configuration - associated with this configurator. - - .. automethod:: begin - - .. automethod:: end - - .. automethod:: hook_zca - - .. automethod:: unhook_zca - - .. automethod:: get_settings - - .. automethod:: commit - - .. automethod:: action - - .. automethod:: include - - .. automethod:: add_directive - - .. automethod:: with_package - - .. automethod:: maybe_dotted + .. automethod:: add_route - .. automethod:: absolute_asset_spec + .. automethod:: add_view - .. automethod:: setup_registry + .. automethod:: add_static_view(name, path, cache_max_age=3600, permission=NO_PERMISSION_REQUIRED) .. automethod:: add_renderer - .. automethod:: add_response_adapter - - .. automethod:: add_route + .. automethod:: add_subscriber - .. automethod:: add_static_view(name, path, cache_max_age=3600, permission=NO_PERMISSION_REQUIRED) + .. automethod:: add_response_adapter .. automethod:: add_settings - .. automethod:: add_subscriber - .. automethod:: add_translation_dirs - .. automethod:: add_view - .. automethod:: add_tween - .. automethod:: derive_view + .. automethod:: add_traverser + + .. automethod:: add_resource_url_adapter .. automethod:: make_wsgi_app() @@ -94,17 +65,45 @@ .. automethod:: set_notfound_view - .. automethod:: add_traverser - .. automethod:: set_renderer_globals_factory(factory) + .. automethod:: begin + + .. automethod:: end + + .. automethod:: hook_zca + + .. automethod:: unhook_zca + + .. automethod:: get_settings + + .. automethod:: commit + + .. automethod:: action + + .. automethod:: include + + .. automethod:: add_directive + + .. automethod:: with_package + + .. automethod:: maybe_dotted + + .. automethod:: absolute_asset_spec + + .. automethod:: setup_registry + + .. automethod:: derive_view + .. attribute:: introspectable A shortcut attribute which points to the :class:`pyramid.registry.Introspectable` class (used during directives to provide introspection to actions). - This attribute is new as of :app:`Pyramid` 1.3. + .. note:: + + This attribute is new as of :app:`Pyramid` 1.3. .. attribute:: introspector @@ -114,7 +113,14 @@ ``introspector`` argument, this attribute will be that value. Otherwise, it will be an instance of a default introspector type. - This attribute is new as of :app:`Pyramid` 1.3. + .. note:: + + This attribute is new as of :app:`Pyramid` 1.3. + + .. attribute:: registry + + The :term:`application registry` which holds the configuration + associated with this configurator. .. attribute:: global_registries diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst index acb884d49..d2df88093 100644 --- a/docs/whatsnew-1.3.rst +++ b/docs/whatsnew-1.3.rst @@ -243,11 +243,6 @@ Minor Feature Additions - We allow extra keyword arguments to be passed to the :meth:`pyramid.config.Configurator.action` method. -- New API: :meth:`pyramid.config.Configurator.set_request_property`. Add lazy - property descriptors to a request without changing the request factory. - This method provides conflict detection and is the suggested way to add - properties to a request. - - Responses generated by Pyramid's :class:`pyramid.views.static_view` now use a ``wsgi.file_wrapper`` (see http://www.python.org/dev/peps/pep-0333/#optional-platform-specific-file-handling) @@ -318,7 +313,7 @@ Minor Feature Additions partially. - A new API named :meth:`pyramid.request.Request.resource_path` now exists. - It works like :meth:`pyramid.request.Request.resource_url`` but produces a + It works like :meth:`pyramid.request.Request.resource_url` but produces a relative URL rather than an absolute one. - The :meth:`pyramid.request.Request.route_url` API now accepts these -- cgit v1.2.3 From ee9769d5a23bc346911c00b482865360babf9f36 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 08:17:32 -0500 Subject: minor wording fixes --- docs/narr/hooks.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2c4310080..a782b9ec6 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -145,10 +145,10 @@ Here's some sample code that implements a minimal forbidden view: Changing the Request Factory ---------------------------- -Whenever :app:`Pyramid` handles a :term:`WSGI` request, it creates a -:term:`request` object based on the WSGI environment it has been passed. By -default, an instance of the :class:`pyramid.request.Request` class is created -to represent the request object. +Whenever :app:`Pyramid` handles a request from a :term:`WSGI` server, it +creates a :term:`request` object based on the WSGI environment it has been +passed. By default, an instance of the :class:`pyramid.request.Request` +class is created to represent the request object. The class (aka "factory") that :app:`Pyramid` uses to create a request object instance can be changed by passing a ``request_factory`` argument to the @@ -236,11 +236,11 @@ Adding Renderer Globals (Deprecated) is documented in :ref:`beforerender_event`. Whenever :app:`Pyramid` handles a request to perform a rendering (after a -view with a ``renderer=`` configuration attribute is invoked, or when any -of the methods beginning with ``render`` within the :mod:`pyramid.renderers` +view with a ``renderer=`` configuration attribute is invoked, or when any of +the methods beginning with ``render`` within the :mod:`pyramid.renderers` module are called), *renderer globals* can be injected into the *system* values sent to the renderer. By default, no renderer globals are injected, -and the "bare" system values (such as ``request``, ``context``, and +and the "bare" system values (such as ``request``, ``context``, ``view``, and ``renderer_name``) are the only values present in the system dictionary passed to every renderer. @@ -447,7 +447,7 @@ that implements the following interface: More than one traversal algorithm can be active at the same time. For instance, if your :term:`root factory` returns more than one type of object -conditionally, you could claim that an alternate traverser adapter is ``for`` +conditionally, you could claim that an alternate traverser adapter is "for" only one particular class or interface. When the root factory returned an object that implemented that class or interface, a custom traverser would be used. Otherwise, the default traverser would be used. For example: -- cgit v1.2.3 From 20ecd354ab99eb0dec5617115f4288ec9262270c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 08:26:26 -0500 Subject: expand --- docs/narr/advconfig.rst | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 5f2175d2a..0060ef65c 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -122,9 +122,10 @@ configuration or configuration that results from the execution of a Manually Resolving Conflicts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There are a number of ways to manually resolve conflicts: the "right" way, by -strategically using :meth:`pyramid.config.Configurator.commit`, or by using -an "autocommitting" configurator. +There are a number of ways to manually resolve conflicts: by changing +registrations to not conflict, by strategically using +:meth:`pyramid.config.Configurator.commit`, or by using an "autocommitting" +configurator. The Right Thing +++++++++++++++ @@ -294,9 +295,18 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.add_route`, :meth:`~pyramid.config.Configurator.add_renderer`, :meth:`~pyramid.config.Configurator.set_request_factory`, +:meth:`~pyramid.config.Configurator.set_session_factory`, +:meth:`~pyramid.config.Configurator.set_request_property`, +:meth:`~pyramid.config.Configurator.set_root_factory`, +:meth:`~pyramid.config.Configurator.set_view_mapper`, +:meth:`~pyramid.config.Configurator.set_authentication_policy`, +:meth:`~pyramid.config.Configurator.set_authorization_policy`, :meth:`~pyramid.config.Configurator.set_renderer_globals_factory`, -:meth:`~pyramid.config.Configurator.set_locale_negotiator` and -:meth:`~pyramid.config.Configurator.set_default_permission`. +:meth:`~pyramid.config.Configurator.set_locale_negotiator`, +:meth:`~pyramid.config.Configurator.set_default_permission`, +:meth:`~pyramid.config.Configurator.add_traverser`, +:meth:`~pyramid.config.Configurator.add_resource_url_adapter`, +and :meth:`~pyramid.config.Configurator.add_response_adapter`. :meth:`~pyramid.config.Configurator.add_static_view` also indirectly provides conflict detection, because it's implemented in terms of the -- cgit v1.2.3 From e0551cd9e73a20f2180fecb1134e07d5ebb90c68 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 08:39:33 -0500 Subject: move add_traverser and add_resource_url_adapter to adapters --- docs/narr/introspector.rst | 22 ++++- pyramid/config/adapters.py | 147 +++++++++++++++++++++++++++- pyramid/config/factories.py | 143 --------------------------- pyramid/tests/test_config/test_adapters.py | 122 +++++++++++++++++++++++ pyramid/tests/test_config/test_factories.py | 114 --------------------- 5 files changed, 289 insertions(+), 259 deletions(-) diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 08cc430f6..d465c47d9 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -540,10 +540,30 @@ introspectables in categories not described here. The (resolved) interface or class object that represents the return value of a root factory that this traverser will be used for. - ``factory`` + ``adapter`` The (resolved) traverser class. +``resource url adapters`` + + Each introspectable in the ``resource url adapters`` category represents a + call to :meth:`pyramid.config.Configurator.add_resource_url_adapter`; each + will have the following data. + + ``adapter`` + + The (resolved) resource URL adapter class. + + ``resource_iface`` + + The (resolved) interface or class object that represents the resource + interface that this url adapter is registered for. + + ``request_iface`` + + The (resolved) interface or class object that represents the request + interface that this url adapter is registered for. + Introspection in the Toolbar ---------------------------- diff --git a/pyramid/config/adapters.py b/pyramid/config/adapters.py index 04571bec3..b6dfdaf41 100644 --- a/pyramid/config/adapters.py +++ b/pyramid/config/adapters.py @@ -1,6 +1,10 @@ from zope.interface import Interface -from pyramid.interfaces import IResponse +from pyramid.interfaces import ( + IResponse, + ITraverser, + IResourceURL, + ) from pyramid.config.util import action_method @@ -72,3 +76,144 @@ class AdaptersConfiguratorMixin(object): # cope with WebOb response objects that aren't decorated with IResponse from webob import Response as WebobResponse self.registry.registerSelfAdapter((WebobResponse,), IResponse) + + @action_method + def add_traverser(self, adapter, iface=None): + """ + The superdefault :term:`traversal` algorithm that :app:`Pyramid` uses + is explained in :ref:`traversal_algorithm`. Though it is rarely + necessary, this default algorithm can be swapped out selectively for + a different traversal pattern via configuration. The section + entitled :ref:`changing_the_traverser` details how to create a + traverser class. + + For example, to override the superdefault traverser used by Pyramid, + you might do something like this: + + .. code-block:: python + + from myapp.traversal import MyCustomTraverser + config.add_traverser(MyCustomTraverser) + + This would cause the Pyramid superdefault traverser to never be used; + intead all traversal would be done using your ``MyCustomTraverser`` + class, no matter which object was returned by the :term:`root + factory` of this application. Note that we passed no arguments to + the ``iface`` keyword parameter. The default value of ``iface``, + ``None`` represents that the registered traverser should be used when + no other more specific traverser is available for the object returned + by the root factory. + + However, more than one traversal algorithm can be active at the same + time. The traverser used can depend on the result of the :term:`root + factory`. For instance, if your root factory returns more than one + type of object conditionally, you could claim that an alternate + traverser adapter should be used agsinst one particular class or + interface returned by that root factory. When the root factory + returned an object that implemented that class or interface, a custom + traverser would be used. Otherwise, the default traverser would be + used. The ``iface`` argument represents the class of the object that + the root factory might return or an :term:`interface` that the object + might implement. + + To use a particular traverser only when the root factory returns a + particular class: + + .. code-block:: python + + config.add_traverser(MyCustomTraverser, MyRootClass) + + When more than one traverser is active, the "most specific" traverser + will be used (the one that matches the class or interface of the + value returned by the root factory most closely). + + Note that either ``adapter`` or ``iface`` can be a :term:`dotted + Python name` or a Python object. + + See :ref:`changing_the_traverser` for more information. + """ + iface = self.maybe_dotted(iface) + adapter= self.maybe_dotted(adapter) + def register(iface=iface): + if iface is None: + iface = Interface + self.registry.registerAdapter(adapter, (iface,), ITraverser) + discriminator = ('traverser', iface) + intr = self.introspectable( + 'traversers', + discriminator, + 'traverser for %r' % iface, + 'traverser', + ) + intr['adapter'] = adapter + intr['iface'] = iface + self.action(discriminator, register, introspectables=(intr,)) + + @action_method + def add_resource_url_adapter(self, adapter, resource_iface=None, + request_iface=None): + """ + When you add a traverser as described in + :ref:`changing_the_traverser`, it's convenient to continue to use the + :meth:`pyramid.request.Request.resource_url` API. However, since the + way traversal is done may have been modified, the URLs that + ``resource_url`` generates by default may be incorrect when resources + are returned by a custom traverser. + + If you've added a traverser, you can change how + :meth:`~pyramid.request.Request.resource_url` generates a URL for a + specific type of resource by calling this method. + + The ``adapter`` argument represents a class that implements the + :class:`~pyramid.interfaces.IResourceURL` interface. The class + constructor should accept two arguments in its constructor (the + resource and the request) and the resulting instance should provide + the attributes detailed in that interface (``virtual_path`` and + ``physical_path``, in particular). + + The ``resource_iface`` argument represents a class or interface that + the resource should possess for this url adapter to be used when + :meth:`pyramid.request.Request.resource_url` looks up a resource url + adapter. If ``resource_iface`` is not passed, or it is passed as + ``None``, the adapter will be used for every type of resource. + + The ``request_iface`` argument represents a class or interface that + the request should possess for this url adapter to be used when + :meth:`pyramid.request.Request.resource_url` looks up a resource url + adapter. If ``request_iface`` is not epassed, or it is passed as + ``None``, the adapter will be used for every type of request. + + See :ref:`changing_resource_url` for more information. + + .. note:: + + This API is new in Pyramid 1.3. + """ + adapter = self.maybe_dotted(adapter) + resource_iface = self.maybe_dotted(resource_iface) + request_iface = self.maybe_dotted(request_iface) + def register(resource_iface=resource_iface, + request_iface=request_iface): + if resource_iface is None: + resource_iface = Interface + if request_iface is None: + request_iface = Interface + self.registry.registerAdapter( + adapter, + (resource_iface, request_iface), + IResourceURL, + ) + discriminator = ('resource url adapter', resource_iface, request_iface) + intr = self.introspectable( + 'resource url adapters', + discriminator, + 'resource url adapter for resource iface %r, request_iface %r' % ( + resource_iface, request_iface), + 'resource url adapter', + ) + intr['adapter'] = adapter + intr['resource_iface'] = resource_iface + intr['request_iface'] = request_iface + self.action(discriminator, register, introspectables=(intr,)) + + diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py index 76f8d86ed..eb4442e98 100644 --- a/pyramid/config/factories.py +++ b/pyramid/config/factories.py @@ -1,5 +1,3 @@ -from zope.interface import Interface - from pyramid.config.util import action_method from pyramid.interfaces import ( @@ -9,8 +7,6 @@ from pyramid.interfaces import ( IRequestProperties, IRootFactory, ISessionFactory, - ITraverser, - IResourceURL, ) from pyramid.traversal import DefaultRootFactory @@ -144,145 +140,6 @@ class FactoriesConfiguratorMixin(object): self.action(('request properties', name), register, introspectables=(intr,)) - @action_method - def add_traverser(self, factory, iface=None): - """ - The superdefault :term:`traversal` algorithm that :app:`Pyramid` uses - is explained in :ref:`traversal_algorithm`. Though it is rarely - necessary, this default algorithm can be swapped out selectively for - a different traversal pattern via configuration. The section - entitled :ref:`changing_the_traverser` details how to create a - traverser class. - - For example, to override the superdefault traverser used by Pyramid, - you might do something like this: - - .. code-block:: python - - from myapp.traversal import MyCustomTraverser - config.add_traverser(MyCustomTraverser) - - This would cause the Pyramid superdefault traverser to never be used; - intead all traversal would be done using your ``MyCustomTraverser`` - class, no matter which object was returned by the :term:`root - factory` of this application. Note that we passed no arguments to - the ``iface`` keyword parameter. The default value of ``iface``, - ``None`` represents that the registered traverser should be used when - no other more specific traverser is available for the object returned - by the root factory. - - However, more than one traversal algorithm can be active at the same - time. The traverser used can depend on the result of the :term:`root - factory`. For instance, if your root factory returns more than one - type of object conditionally, you could claim that an alternate - traverser adapter should be used agsinst one particular class or - interface returned by that root factory. When the root factory - returned an object that implemented that class or interface, a custom - traverser would be used. Otherwise, the default traverser would be - used. The ``iface`` argument represents the class of the object that - the root factory might return or an :term:`interface` that the object - might implement. - - To use a particular traverser only when the root factory returns a - particular class: - - .. code-block:: python - - config.add_traverser(MyCustomTraverser, MyRootClass) - - When more than one traverser is active, the "most specific" traverser - will be used (the one that matches the class or interface of the - value returned by the root factory most closely). - - Note that either ``factory`` or ``iface`` can be a :term:`dotted - Python name` or a Python object. - - See :ref:`changing_the_traverser` for more information. - """ - iface = self.maybe_dotted(iface) - factory = self.maybe_dotted(factory) - def register(iface=iface): - if iface is None: - iface = Interface - self.registry.registerAdapter(factory, (iface,), ITraverser) - discriminator = ('traverser', iface) - intr = self.introspectable( - 'traversers', - discriminator, - 'traverser for %r' % iface, - 'traverser', - ) - intr['factory'] = factory - intr['iface'] = iface - self.action(discriminator, register, introspectables=(intr,)) - - @action_method - def add_resource_url_adapter(self, factory, resource_iface=None, - request_iface=None): - """ - When you add a traverser as described in - :ref:`changing_the_traverser`, it's convenient to continue to use the - :meth:`pyramid.request.Request.resource_url` API. However, since the - way traversal is done may have been modified, the URLs that - ``resource_url`` generates by default may be incorrect when resources - are returned by a custom traverser. - - If you've added a traverser, you can change how - :meth:`~pyramid.request.Request.resource_url` generates a URL for a - specific type of resource by calling this method. - - The ``factory`` argument represents a class that implements the - :class:`~pyramid.interfaces.IResourceURL` interface. The class - constructor should accept two arguments in its constructor (the - resource and the request) and the resulting instance should provide - the attributes detailed in that interface (``virtual_path`` and - ``physical_path``, in particular). - - The ``resource_iface`` argument represents a class or interface that - the resource should possess for this url adapter to be used when - :meth:`pyramid.request.Request.resource_url` looks up a resource url - adapter. If ``resource_iface`` is not passed, or it is passed as - ``None``, the adapter will be used for every type of resource. - - The ``request_iface`` argument represents a class or interface that - the request should possess for this url adapter to be used when - :meth:`pyramid.request.Request.resource_url` looks up a resource url - adapter. If ``request_iface`` is not epassed, or it is passed as - ``None``, the adapter will be used for every type of request. - - See :ref:`changing_resource_url` for more information. - - .. note:: - - This API is new in Pyramid 1.3. - """ - factory = self.maybe_dotted(factory) - resource_iface = self.maybe_dotted(resource_iface) - request_iface = self.maybe_dotted(request_iface) - def register(resource_iface=resource_iface, - request_iface=request_iface): - if resource_iface is None: - resource_iface = Interface - if request_iface is None: - request_iface = Interface - self.registry.registerAdapter( - factory, - (resource_iface, request_iface), - IResourceURL, - ) - discriminator = ('resource url adapter', resource_iface, request_iface) - intr = self.introspectable( - 'resource url adapters', - discriminator, - 'resource url adapter for resource iface %r, request_iface %r' % ( - resource_iface, request_iface), - 'resource url adapter', - ) - intr['factory'] = factory - intr['resource_iface'] = resource_iface - intr['request_iface'] = request_iface - self.action(discriminator, register, introspectables=(intr,)) - def _set_request_properties(event): request = event.request plist = request.registry.queryUtility(IRequestProperties) diff --git a/pyramid/tests/test_config/test_adapters.py b/pyramid/tests/test_config/test_adapters.py index 84b7119cf..b89571639 100644 --- a/pyramid/tests/test_config/test_adapters.py +++ b/pyramid/tests/test_config/test_adapters.py @@ -112,3 +112,125 @@ class AdaptersConfiguratorMixinTests(unittest.TestCase): result = config.registry.queryAdapter('foo', IResponse) self.assertTrue(result.body, b'foo') + def test_add_traverser_dotted_names(self): + from pyramid.interfaces import ITraverser + config = self._makeOne(autocommit=True) + config.add_traverser( + 'pyramid.tests.test_config.test_adapters.DummyTraverser', + 'pyramid.tests.test_config.test_adapters.DummyIface') + iface = DummyIface() + traverser = config.registry.getAdapter(iface, ITraverser) + self.assertEqual(traverser.__class__, DummyTraverser) + self.assertEqual(traverser.root, iface) + + def test_add_traverser_default_iface_means_Interface(self): + from pyramid.interfaces import ITraverser + config = self._makeOne(autocommit=True) + config.add_traverser(DummyTraverser) + traverser = config.registry.getAdapter(None, ITraverser) + self.assertEqual(traverser.__class__, DummyTraverser) + + def test_add_traverser_nondefault_iface(self): + from pyramid.interfaces import ITraverser + config = self._makeOne(autocommit=True) + config.add_traverser(DummyTraverser, DummyIface) + iface = DummyIface() + traverser = config.registry.getAdapter(iface, ITraverser) + self.assertEqual(traverser.__class__, DummyTraverser) + self.assertEqual(traverser.root, iface) + + def test_add_traverser_introspectables(self): + config = self._makeOne() + config.add_traverser(DummyTraverser, DummyIface) + actions = config.action_state.actions + self.assertEqual(len(actions), 1) + intrs = actions[0]['introspectables'] + self.assertEqual(len(intrs), 1) + intr = intrs[0] + self.assertEqual(intr.type_name, 'traverser') + self.assertEqual(intr.discriminator, ('traverser', DummyIface)) + self.assertEqual(intr.category_name, 'traversers') + self.assertEqual(intr.title, 'traverser for %r' % DummyIface) + self.assertEqual(intr['adapter'], DummyTraverser) + self.assertEqual(intr['iface'], DummyIface) + + def test_add_resource_url_adapter_dotted_names(self): + from pyramid.interfaces import IResourceURL + config = self._makeOne(autocommit=True) + config.add_resource_url_adapter( + 'pyramid.tests.test_config.test_adapters.DummyResourceURL', + 'pyramid.tests.test_config.test_adapters.DummyIface', + 'pyramid.tests.test_config.test_adapters.DummyIface', + ) + iface = DummyIface() + adapter = config.registry.getMultiAdapter((iface, iface), + IResourceURL) + self.assertEqual(adapter.__class__, DummyResourceURL) + self.assertEqual(adapter.resource, iface) + self.assertEqual(adapter.request, iface) + + def test_add_resource_url_default_interfaces_mean_Interface(self): + from pyramid.interfaces import IResourceURL + config = self._makeOne(autocommit=True) + config.add_resource_url_adapter(DummyResourceURL) + iface = DummyIface() + adapter = config.registry.getMultiAdapter((iface, iface), + IResourceURL) + self.assertEqual(adapter.__class__, DummyResourceURL) + self.assertEqual(adapter.resource, iface) + self.assertEqual(adapter.request, iface) + + def test_add_resource_url_nodefault_interfaces(self): + from zope.interface import Interface + from pyramid.interfaces import IResourceURL + config = self._makeOne(autocommit=True) + config.add_resource_url_adapter(DummyResourceURL, DummyIface, + DummyIface) + iface = DummyIface() + adapter = config.registry.getMultiAdapter((iface, iface), + IResourceURL) + self.assertEqual(adapter.__class__, DummyResourceURL) + self.assertEqual(adapter.resource, iface) + self.assertEqual(adapter.request, iface) + bad_result = config.registry.queryMultiAdapter( + (Interface, Interface), + IResourceURL, + ) + self.assertEqual(bad_result, None) + + def test_add_resource_url_adapter_introspectables(self): + config = self._makeOne() + config.add_resource_url_adapter(DummyResourceURL, DummyIface) + actions = config.action_state.actions + self.assertEqual(len(actions), 1) + intrs = actions[0]['introspectables'] + self.assertEqual(len(intrs), 1) + intr = intrs[0] + self.assertEqual(intr.type_name, 'resource url adapter') + self.assertEqual(intr.discriminator, + ('resource url adapter', DummyIface, None)) + self.assertEqual(intr.category_name, 'resource url adapters') + self.assertEqual( + intr.title, + "resource url adapter for resource iface " + ", " + "request_iface None" + ) + self.assertEqual(intr['adapter'], DummyResourceURL) + self.assertEqual(intr['resource_iface'], DummyIface) + self.assertEqual(intr['request_iface'], None) + + +class DummyTraverser(object): + def __init__(self, root): + self.root = root + +class DummyIface(object): + pass + +class DummyResourceURL(object): + def __init__(self, resource, request): + self.resource = resource + self.request = request + + diff --git a/pyramid/tests/test_config/test_factories.py b/pyramid/tests/test_config/test_factories.py index 5f300a73e..0930f9603 100644 --- a/pyramid/tests/test_config/test_factories.py +++ b/pyramid/tests/test_config/test_factories.py @@ -129,108 +129,6 @@ class TestFactoriesMixin(unittest.TestCase): self.assertEqual(callables, [('foo', foo, False), ('bar', foo, True)]) - def test_add_traverser_dotted_names(self): - from pyramid.interfaces import ITraverser - config = self._makeOne(autocommit=True) - config.add_traverser( - 'pyramid.tests.test_config.test_factories.DummyTraverser', - 'pyramid.tests.test_config.test_factories.DummyIface') - iface = DummyIface() - traverser = config.registry.getAdapter(iface, ITraverser) - self.assertEqual(traverser.__class__, DummyTraverser) - self.assertEqual(traverser.root, iface) - - def test_add_traverser_default_iface_means_Interface(self): - from pyramid.interfaces import ITraverser - config = self._makeOne(autocommit=True) - config.add_traverser(DummyTraverser) - traverser = config.registry.getAdapter(None, ITraverser) - self.assertEqual(traverser.__class__, DummyTraverser) - - def test_add_traverser_nondefault_iface(self): - from pyramid.interfaces import ITraverser - config = self._makeOne(autocommit=True) - config.add_traverser(DummyTraverser, DummyIface) - iface = DummyIface() - traverser = config.registry.getAdapter(iface, ITraverser) - self.assertEqual(traverser.__class__, DummyTraverser) - self.assertEqual(traverser.root, iface) - - def test_add_traverser_introspectables(self): - config = self._makeOne() - config.add_traverser(DummyTraverser, DummyIface) - actions = config.action_state.actions - self.assertEqual(len(actions), 1) - intrs = actions[0]['introspectables'] - self.assertEqual(len(intrs), 1) - intr = intrs[0] - self.assertEqual(intr.type_name, 'traverser') - self.assertEqual(intr.discriminator, ('traverser', DummyIface)) - self.assertEqual(intr.category_name, 'traversers') - self.assertEqual(intr.title, 'traverser for %r' % DummyIface) - - def test_add_resource_url_adapter_dotted_names(self): - from pyramid.interfaces import IResourceURL - config = self._makeOne(autocommit=True) - config.add_resource_url_adapter( - 'pyramid.tests.test_config.test_factories.DummyResourceURL', - 'pyramid.tests.test_config.test_factories.DummyIface', - 'pyramid.tests.test_config.test_factories.DummyIface', - ) - iface = DummyIface() - adapter = config.registry.getMultiAdapter((iface, iface), - IResourceURL) - self.assertEqual(adapter.__class__, DummyResourceURL) - self.assertEqual(adapter.resource, iface) - self.assertEqual(adapter.request, iface) - - def test_add_resource_url_default_interfaces_mean_Interface(self): - from pyramid.interfaces import IResourceURL - config = self._makeOne(autocommit=True) - config.add_resource_url_adapter(DummyResourceURL) - iface = DummyIface() - adapter = config.registry.getMultiAdapter((iface, iface), - IResourceURL) - self.assertEqual(adapter.__class__, DummyResourceURL) - self.assertEqual(adapter.resource, iface) - self.assertEqual(adapter.request, iface) - - def test_add_resource_url_nodefault_interfaces(self): - from zope.interface import Interface - from pyramid.interfaces import IResourceURL - config = self._makeOne(autocommit=True) - config.add_resource_url_adapter(DummyResourceURL, DummyIface, - DummyIface) - iface = DummyIface() - adapter = config.registry.getMultiAdapter((iface, iface), - IResourceURL) - self.assertEqual(adapter.__class__, DummyResourceURL) - self.assertEqual(adapter.resource, iface) - self.assertEqual(adapter.request, iface) - bad_result = config.registry.queryMultiAdapter( - (Interface, Interface), - IResourceURL, - ) - self.assertEqual(bad_result, None) - - def test_add_resource_url_adapter_introspectables(self): - config = self._makeOne() - config.add_resource_url_adapter(DummyResourceURL, DummyIface) - actions = config.action_state.actions - self.assertEqual(len(actions), 1) - intrs = actions[0]['introspectables'] - self.assertEqual(len(intrs), 1) - intr = intrs[0] - self.assertEqual(intr.type_name, 'resource url adapter') - self.assertEqual(intr.discriminator, - ('resource url adapter', DummyIface, None)) - self.assertEqual(intr.category_name, 'resource url adapters') - self.assertEqual( - intr.title, - "resource url adapter for resource iface " - ", " - "request_iface None" - ) class DummyRequest(object): @@ -244,15 +142,3 @@ class DummyRequest(object): self.callables = [] self.callables.append((name, callable, reify)) -class DummyTraverser(object): - def __init__(self, root): - self.root = root - -class DummyIface(object): - pass - -class DummyResourceURL(object): - def __init__(self, resource, request): - self.resource = resource - self.request = request - -- cgit v1.2.3 From 66b20a9d467582064b91295dfd364118cc68a568 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 10:12:17 -0500 Subject: categorized configurator methods --- docs/api/config.rst | 133 +++++++++++++++++++++++++++------------------------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/docs/api/config.rst b/docs/api/config.rst index 87ba94673..b76fed9cb 100644 --- a/docs/api/config.rst +++ b/docs/api/config.rst @@ -1,99 +1,102 @@ .. _configuration_module: +.. role:: methodcategory + :class: methodcategory + :mod:`pyramid.config` --------------------- .. automodule:: pyramid.config - .. autoclass:: Configurator - - .. automethod:: add_route - - .. automethod:: add_view - - .. automethod:: add_static_view(name, path, cache_max_age=3600, permission=NO_PERMISSION_REQUIRED) - - .. automethod:: add_renderer - - .. automethod:: add_subscriber - - .. automethod:: add_response_adapter - - .. automethod:: add_settings +.. autoclass:: Configurator - .. automethod:: add_translation_dirs + :methodcategory:`Controlling Configuration State` - .. automethod:: add_tween + .. automethod:: commit + .. automethod:: begin + .. automethod:: end + .. automethod:: include + .. automethod:: make_wsgi_app() + .. automethod:: scan - .. automethod:: add_traverser + :methodcategory:`Adding Routes and Views` - .. automethod:: add_resource_url_adapter - - .. automethod:: make_wsgi_app() + .. automethod:: add_route + .. automethod:: add_static_view(name, path, cache_max_age=3600, permission=NO_PERMISSION_REQUIRED) + .. automethod:: add_view + .. automethod:: set_forbidden_view + .. automethod:: set_notfound_view - .. automethod:: override_asset(to_override, override_with) + :methodcategory:`Adding an Event Subscriber` - .. automethod:: scan + .. automethod:: add_subscriber - .. automethod:: set_locale_negotiator + :methodcategory:`Using Security` + .. automethod:: set_authentication_policy + .. automethod:: set_authorization_policy .. automethod:: set_default_permission - .. automethod:: set_session_factory - - .. automethod:: set_request_factory + :methodcategory:`Setting Request Properties` .. automethod:: set_request_property - .. automethod:: set_root_factory - - .. automethod:: set_view_mapper - - .. automethod:: set_authentication_policy - - .. automethod:: set_authorization_policy - - .. automethod:: testing_securitypolicy + :methodcategory:`Using I18N` - .. automethod:: testing_resources - - .. automethod:: testing_add_subscriber + .. automethod:: add_translation_dirs + .. automethod:: set_locale_negotiator - .. automethod:: testing_add_renderer + :methodcategory:`Overriding Assets` - .. automethod:: set_forbidden_view + .. automethod:: override_asset(to_override, override_with) - .. automethod:: set_notfound_view + :methodcategory:`Setting Renderer Globals` .. automethod:: set_renderer_globals_factory(factory) - .. automethod:: begin - - .. automethod:: end - - .. automethod:: hook_zca - - .. automethod:: unhook_zca + :methodcategory:`Getting and Adding Settings` + .. automethod:: add_settings .. automethod:: get_settings - .. automethod:: commit + :methodcategory:`Hooking Pyramid Behavior` - .. automethod:: action + .. automethod:: add_renderer + .. automethod:: add_resource_url_adapter + .. automethod:: add_response_adapter + .. automethod:: add_traverser + .. automethod:: add_tween + .. automethod:: set_request_factory + .. automethod:: set_root_factory + .. automethod:: set_session_factory + .. automethod:: set_view_mapper - .. automethod:: include + :methodcategory:`Extension Author APIs` + .. automethod:: action .. automethod:: add_directive - .. automethod:: with_package - .. automethod:: maybe_dotted + :methodcategory:`Utility Methods` .. automethod:: absolute_asset_spec - + .. automethod:: derive_view + .. automethod:: maybe_dotted .. automethod:: setup_registry - .. automethod:: derive_view + :methodcategory:`ZCA-Related APIs` + + .. automethod:: hook_zca + .. automethod:: unhook_zca + + :methodcategory:`Testing Helper APIs` + + .. automethod:: testing_add_renderer + .. automethod:: testing_add_subscriber + .. automethod:: testing_resources + .. automethod:: testing_securitypolicy + + :methodcategory:`Attributes` .. attribute:: introspectable @@ -122,15 +125,15 @@ The :term:`application registry` which holds the configuration associated with this configurator. - .. attribute:: global_registries +.. attribute:: global_registries - The set of registries that have been created for :app:`Pyramid` - applications, one per each call to - :meth:`pyramid.config.Configurator.make_wsgi_app` in the current - process. The object itself supports iteration and has a ``last`` - property containing the last registry loaded. + The set of registries that have been created for :app:`Pyramid` + applications, one per each call to + :meth:`pyramid.config.Configurator.make_wsgi_app` in the current + process. The object itself supports iteration and has a ``last`` property + containing the last registry loaded. - The registries contained in this object are stored as weakrefs, - thus they will only exist for the lifetime of the actual - applications for which they are being used. + The registries contained in this object are stored as weakrefs, thus they + will only exist for the lifetime of the actual applications for which they + are being used. -- cgit v1.2.3 From e75229aede80ade185d0624f6e1cc05e4db23513 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 10:58:14 -0500 Subject: fix search links --- pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl | 2 +- pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl index 8d85ed991..743eab026 100644 --- a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl @@ -32,7 +32,7 @@

Search documentation

-
+
diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt index 0bfac946e..d64f18fca 100644 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt @@ -32,7 +32,7 @@

Search documentation

-
+
-- cgit v1.2.3 From 118ea0c512a82d3dfcc6fe283afcd30818c14993 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 15:18:36 -0500 Subject: deprecate pyramid.interfaces.IContextURL and pyramid.traversal.TraversalContextURL, add tests for ResourceURL constructor logic --- pyramid/interfaces.py | 11 +++++++ pyramid/tests/test_traversal.py | 64 ++++++++++++++++++++++++++++++++++------- pyramid/tests/test_url.py | 3 +- pyramid/traversal.py | 12 ++++++++ 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 5b9edf31a..399b3efa3 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -1,3 +1,5 @@ +from zope.deprecation import deprecated + from zope.interface import ( Attribute, Interface, @@ -780,6 +782,15 @@ class IContextURL(IResourceURL): def __call__(): """ Return a URL that points to the context. """ +deprecated( + 'IContextURL', + 'As of Pyramid 1.3 the, "pyramid.interfaces.IContextURL" interface is ' + 'scheduled to be removed. Use the ' + '"pyramid.config.Configurator.add_resource_url_adapter" method to register' + 'a class that implements "pyramid.interfaces.IResourceURL" instead.' + 'See the "What\'s new In Pyramid 1.3" document for a further description.' + ) + class IPackageOverrides(Interface): """ Utility for pkg_resources overrides """ diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py index 1f9971ca5..8261ad7d9 100644 --- a/pyramid/tests/test_traversal.py +++ b/pyramid/tests/test_traversal.py @@ -1,6 +1,8 @@ import unittest +import warnings from pyramid.testing import cleanUp + from pyramid.compat import ( text_, native_, @@ -9,6 +11,11 @@ from pyramid.compat import ( PY3, ) +with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + from pyramid.interfaces import IContextURL + assert(len(w) == 1) + class TraversalPathTests(unittest.TestCase): def _callFUT(self, path): from pyramid.traversal import traversal_path @@ -452,9 +459,8 @@ class ResourceTreeTraverserTests(unittest.TestCase): self.assertEqual(result['virtual_root_path'], ()) def test_call_with_environ(self): - import warnings - warnings.filterwarnings('ignore') - try: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') policy = self._makeOne(None) environ = self._getEnviron() result = policy(environ) @@ -465,8 +471,7 @@ class ResourceTreeTraverserTests(unittest.TestCase): self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) - finally: - warnings.resetwarnings() + self.assertEqual(len(w), 1) class FindInterfaceTests(unittest.TestCase): def _callFUT(self, context, iface): @@ -857,13 +862,13 @@ class QuotePathSegmentTests(unittest.TestCase): result = self._callFUT(s) self.assertEqual(result, 'abc') -class TraversalContextURLTests(unittest.TestCase): +class ResourceURLTests(unittest.TestCase): def _makeOne(self, context, url): return self._getTargetClass()(context, url) def _getTargetClass(self): - from pyramid.traversal import TraversalContextURL - return TraversalContextURL + from pyramid.traversal import ResourceURL + return ResourceURL def _registerTraverser(self, traverser): from pyramid.threadlocal import get_current_registry @@ -874,16 +879,21 @@ class TraversalContextURLTests(unittest.TestCase): def test_class_conforms_to_IContextURL(self): from zope.interface.verify import verifyClass - from pyramid.interfaces import IContextURL verifyClass(IContextURL, self._getTargetClass()) def test_instance_conforms_to_IContextURL(self): from zope.interface.verify import verifyObject - from pyramid.interfaces import IContextURL context = DummyContext() request = DummyRequest() verifyObject(IContextURL, self._makeOne(context, request)) + def test_instance_conforms_to_IResourceURL(self): + from pyramid.interfaces import IResourceURL + from zope.interface.verify import verifyObject + context = DummyContext() + request = DummyRequest() + verifyObject(IResourceURL, self._makeOne(context, request)) + def test_call_withlineage(self): baz = DummyContext() bar = DummyContext(baz) @@ -1036,6 +1046,39 @@ class TraversalContextURLTests(unittest.TestCase): result = context_url() self.assertEqual(result, 'abc') + def test_IResourceURL_attributes_with_vroot(self): + from pyramid.interfaces import VH_ROOT_KEY + root = DummyContext() + root.__parent__ = None + root.__name__ = None + one = DummyContext() + one.__parent__ = root + one.__name__ = 'one' + two = DummyContext() + two.__parent__ = one + two.__name__ = 'two' + environ = {VH_ROOT_KEY:'/one'} + request = DummyRequest(environ) + context_url = self._makeOne(two, request) + self.assertEqual(context_url.physical_path, '/one/two/') + self.assertEqual(context_url.virtual_path, '/two/') + + def test_IResourceURL_attributes_no_vroot(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + one = DummyContext() + one.__parent__ = root + one.__name__ = 'one' + two = DummyContext() + two.__parent__ = one + two.__name__ = 'two' + environ = {} + request = DummyRequest(environ) + context_url = self._makeOne(two, request) + self.assertEqual(context_url.physical_path, '/one/two/') + self.assertEqual(context_url.virtual_path, '/one/two/') + class TestVirtualRoot(unittest.TestCase): def setUp(self): cleanUp() @@ -1048,7 +1091,6 @@ class TestVirtualRoot(unittest.TestCase): return virtual_root(resource, request) def test_registered(self): - from pyramid.interfaces import IContextURL from zope.interface import Interface request = _makeRequest() request.registry.registerAdapter(DummyContextURL, (Interface,Interface), diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 3c36363ed..7b05368ce 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -27,7 +27,8 @@ class TestURLMethodsMixin(unittest.TestCase): return request def _registerContextURL(self, reg): - from pyramid.interfaces import IContextURL + with warnings.catch_warnings(record=True): + from pyramid.interfaces import IContextURL from zope.interface import Interface class DummyContextURL(object): def __init__(self, context, request): diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 9801f8f18..328fde4a5 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -1,5 +1,7 @@ import warnings +from zope.deprecation import deprecated + from zope.interface import implementer from zope.interface.interfaces import IInterface @@ -796,6 +798,16 @@ class ResourceURL(object): TraversalContextURL = ResourceURL # bw compat as of 1.3 +deprecated( + 'TraversalContextURL', + 'As of Pyramid 1.3 the, "pyramid.traversal.TraversalContextURL" class is ' + 'scheduled to be removed. Use the ' + '"pyramid.config.Configurator.add_resource_url_adapter" method to register' + 'a class that implements "pyramid.interfaces.IResourceURL" instead.' + 'See the "What\'s new In Pyramid 1.3" document for a further description.' + ) + + @lru_cache(1000) def _join_path_tuple(tuple): return tuple and '/'.join([quote_path_segment(x) for x in tuple]) or '/' -- cgit v1.2.3 From 44f585291d5f98892a94b3dafca42a70c4f3fc02 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 15:20:27 -0500 Subject: comment intent --- pyramid/traversal.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 328fde4a5..75931557e 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -753,8 +753,10 @@ class ResourceURL(object): if physical_path.startswith(vroot_path): virtual_path = physical_path[len(vroot_path):] - self.virtual_path = virtual_path - self.physical_path = physical_path + self.virtual_path = virtual_path # IResourceURL attr + self.physical_path = physical_path # IResourceURL attr + + # bw compat self.resource = resource self.context = resource # bw compat alias for IContextURL compat self.request = request -- cgit v1.2.3 From 99de4d85466711bf0a2321df2c2bf0a273989015 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 15:23:16 -0500 Subject: reorder tests --- pyramid/tests/test_traversal.py | 71 +++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py index 8261ad7d9..8e0bb2494 100644 --- a/pyramid/tests/test_traversal.py +++ b/pyramid/tests/test_traversal.py @@ -878,6 +878,7 @@ class ResourceURLTests(unittest.TestCase): reg.registerAdapter(traverser, (Interface,), ITraverser) def test_class_conforms_to_IContextURL(self): + # bw compat from zope.interface.verify import verifyClass verifyClass(IContextURL, self._getTargetClass()) @@ -975,39 +976,7 @@ class ResourceURLTests(unittest.TestCase): result = context_url() self.assertEqual(result, 'http://example.com:5432/one/two/') - def test_virtual_root_no_virtual_root_path(self): - root = DummyContext() - root.__name__ = None - root.__parent__ = None - one = DummyContext() - one.__name__ = 'one' - one.__parent__ = root - request = DummyRequest() - context_url = self._makeOne(one, request) - self.assertEqual(context_url.virtual_root(), root) - - def test_virtual_root_no_virtual_root_path_with_root_on_request(self): - context = DummyContext() - context.__parent__ = None - request = DummyRequest() - request.root = DummyContext() - context_url = self._makeOne(context, request) - self.assertEqual(context_url.virtual_root(), request.root) - - def test_virtual_root_with_virtual_root_path(self): - from pyramid.interfaces import VH_ROOT_KEY - context = DummyContext() - context.__parent__ = None - traversed_to = DummyContext() - environ = {VH_ROOT_KEY:'/one'} - request = DummyRequest(environ) - traverser = make_traverser({'context':traversed_to, 'view_name':''}) - self._registerTraverser(traverser) - context_url = self._makeOne(context, request) - self.assertEqual(context_url.virtual_root(), traversed_to) - self.assertEqual(context.request.environ['PATH_INFO'], '/one') - - def test_empty_names_not_ignored(self): + def test_call_empty_names_not_ignored(self): bar = DummyContext() empty = DummyContext(bar) root = DummyContext(empty) @@ -1022,7 +991,7 @@ class ResourceURLTests(unittest.TestCase): result = context_url() self.assertEqual(result, 'http://example.com:5432//bar/') - def test_local_url_returns_None(self): + def test_call_local_url_returns_None(self): resource = DummyContext() def resource_url(request, info): self.assertEqual(info['virtual_path'], '/') @@ -1034,7 +1003,7 @@ class ResourceURLTests(unittest.TestCase): result = context_url() self.assertEqual(result, 'http://example.com:5432/') - def test_local_url_returns_url(self): + def test_call_local_url_returns_url(self): resource = DummyContext() def resource_url(request, info): self.assertEqual(info['virtual_path'], '/') @@ -1046,6 +1015,38 @@ class ResourceURLTests(unittest.TestCase): result = context_url() self.assertEqual(result, 'abc') + def test_virtual_root_no_virtual_root_path(self): + root = DummyContext() + root.__name__ = None + root.__parent__ = None + one = DummyContext() + one.__name__ = 'one' + one.__parent__ = root + request = DummyRequest() + context_url = self._makeOne(one, request) + self.assertEqual(context_url.virtual_root(), root) + + def test_virtual_root_no_virtual_root_path_with_root_on_request(self): + context = DummyContext() + context.__parent__ = None + request = DummyRequest() + request.root = DummyContext() + context_url = self._makeOne(context, request) + self.assertEqual(context_url.virtual_root(), request.root) + + def test_virtual_root_with_virtual_root_path(self): + from pyramid.interfaces import VH_ROOT_KEY + context = DummyContext() + context.__parent__ = None + traversed_to = DummyContext() + environ = {VH_ROOT_KEY:'/one'} + request = DummyRequest(environ) + traverser = make_traverser({'context':traversed_to, 'view_name':''}) + self._registerTraverser(traverser) + context_url = self._makeOne(context, request) + self.assertEqual(context_url.virtual_root(), traversed_to) + self.assertEqual(context.request.environ['PATH_INFO'], '/one') + def test_IResourceURL_attributes_with_vroot(self): from pyramid.interfaces import VH_ROOT_KEY root = DummyContext() -- cgit v1.2.3 From 2be06a6151e6e21ab680dff8c0e669f05c769ab5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 15:28:26 -0500 Subject: comment --- pyramid/traversal.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 75931557e..8c1e3f434 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -798,7 +798,7 @@ class ResourceURL(object): app_url = self.request.application_url # never ends in a slash return app_url + self.virtual_path -TraversalContextURL = ResourceURL # bw compat as of 1.3 +TraversalContextURL = ResourceURL # deprecated as of 1.3 deprecated( 'TraversalContextURL', @@ -809,7 +809,6 @@ deprecated( 'See the "What\'s new In Pyramid 1.3" document for a further description.' ) - @lru_cache(1000) def _join_path_tuple(tuple): return tuple and '/'.join([quote_path_segment(x) for x in tuple]) or '/' -- cgit v1.2.3 From 4c49ad3306522ce4b1806ac7175447d7e8a3c3a9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 15:36:20 -0500 Subject: spacing --- pyramid/interfaces.py | 4 ++-- pyramid/traversal.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 399b3efa3..5d9d29afa 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -786,8 +786,8 @@ deprecated( 'IContextURL', 'As of Pyramid 1.3 the, "pyramid.interfaces.IContextURL" interface is ' 'scheduled to be removed. Use the ' - '"pyramid.config.Configurator.add_resource_url_adapter" method to register' - 'a class that implements "pyramid.interfaces.IResourceURL" instead.' + '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' + 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' 'See the "What\'s new In Pyramid 1.3" document for a further description.' ) diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 8c1e3f434..3b2c96021 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -756,9 +756,9 @@ class ResourceURL(object): self.virtual_path = virtual_path # IResourceURL attr self.physical_path = physical_path # IResourceURL attr - # bw compat + # bw compat for IContextURL methods self.resource = resource - self.context = resource # bw compat alias for IContextURL compat + self.context = resource self.request = request # IContextURL method (deprecated in 1.3) @@ -804,8 +804,8 @@ deprecated( 'TraversalContextURL', 'As of Pyramid 1.3 the, "pyramid.traversal.TraversalContextURL" class is ' 'scheduled to be removed. Use the ' - '"pyramid.config.Configurator.add_resource_url_adapter" method to register' - 'a class that implements "pyramid.interfaces.IResourceURL" instead.' + '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' + 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' 'See the "What\'s new In Pyramid 1.3" document for a further description.' ) -- cgit v1.2.3 From 8b59f6a32f7851be0152caaa94ffe5e0366b8815 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 16:53:57 -0500 Subject: dont allow a registration for the request type in add_resource_url_adapter (we can always add it later, but can never take it away); squash an import warning --- docs/narr/hooks.rst | 2 +- pyramid/config/adapters.py | 25 ++++++------------------- pyramid/tests/test_config/test_adapters.py | 15 +++++---------- pyramid/traversal.py | 5 ++++- 4 files changed, 16 insertions(+), 31 deletions(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a782b9ec6..eaccc14a3 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -495,7 +495,7 @@ For example: from myapp.traversal import ResourceURLAdapter from myapp.resources import MyRoot - config.add_resource_url_adapter(ResourceURLAdapter, resource_iface=MyRoot) + config.add_resource_url_adapter(ResourceURLAdapter, MyRoot) In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will be used to provide services to :meth:`~pyramid.request.Request.resource_url` diff --git a/pyramid/config/adapters.py b/pyramid/config/adapters.py index b6dfdaf41..5f15f2e46 100644 --- a/pyramid/config/adapters.py +++ b/pyramid/config/adapters.py @@ -150,8 +150,7 @@ class AdaptersConfiguratorMixin(object): self.action(discriminator, register, introspectables=(intr,)) @action_method - def add_resource_url_adapter(self, adapter, resource_iface=None, - request_iface=None): + def add_resource_url_adapter(self, adapter, resource_iface=None): """ When you add a traverser as described in :ref:`changing_the_traverser`, it's convenient to continue to use the @@ -175,13 +174,7 @@ class AdaptersConfiguratorMixin(object): the resource should possess for this url adapter to be used when :meth:`pyramid.request.Request.resource_url` looks up a resource url adapter. If ``resource_iface`` is not passed, or it is passed as - ``None``, the adapter will be used for every type of resource. - - The ``request_iface`` argument represents a class or interface that - the request should possess for this url adapter to be used when - :meth:`pyramid.request.Request.resource_url` looks up a resource url - adapter. If ``request_iface`` is not epassed, or it is passed as - ``None``, the adapter will be used for every type of request. + ``None``, the url adapter will be used for every type of resource. See :ref:`changing_resource_url` for more information. @@ -191,29 +184,23 @@ class AdaptersConfiguratorMixin(object): """ adapter = self.maybe_dotted(adapter) resource_iface = self.maybe_dotted(resource_iface) - request_iface = self.maybe_dotted(request_iface) - def register(resource_iface=resource_iface, - request_iface=request_iface): + def register(resource_iface=resource_iface): if resource_iface is None: resource_iface = Interface - if request_iface is None: - request_iface = Interface self.registry.registerAdapter( adapter, - (resource_iface, request_iface), + (resource_iface, Interface), IResourceURL, ) - discriminator = ('resource url adapter', resource_iface, request_iface) + discriminator = ('resource url adapter', resource_iface) intr = self.introspectable( 'resource url adapters', discriminator, - 'resource url adapter for resource iface %r, request_iface %r' % ( - resource_iface, request_iface), + 'resource url adapter for resource iface %r' % resource_iface, 'resource url adapter', ) intr['adapter'] = adapter intr['resource_iface'] = resource_iface - intr['request_iface'] = request_iface self.action(discriminator, register, introspectables=(intr,)) diff --git a/pyramid/tests/test_config/test_adapters.py b/pyramid/tests/test_config/test_adapters.py index b89571639..83ea0f05b 100644 --- a/pyramid/tests/test_config/test_adapters.py +++ b/pyramid/tests/test_config/test_adapters.py @@ -160,7 +160,6 @@ class AdaptersConfiguratorMixinTests(unittest.TestCase): config.add_resource_url_adapter( 'pyramid.tests.test_config.test_adapters.DummyResourceURL', 'pyramid.tests.test_config.test_adapters.DummyIface', - 'pyramid.tests.test_config.test_adapters.DummyIface', ) iface = DummyIface() adapter = config.registry.getMultiAdapter((iface, iface), @@ -169,7 +168,7 @@ class AdaptersConfiguratorMixinTests(unittest.TestCase): self.assertEqual(adapter.resource, iface) self.assertEqual(adapter.request, iface) - def test_add_resource_url_default_interfaces_mean_Interface(self): + def test_add_resource_url_default_resource_iface_means_Interface(self): from pyramid.interfaces import IResourceURL config = self._makeOne(autocommit=True) config.add_resource_url_adapter(DummyResourceURL) @@ -180,12 +179,11 @@ class AdaptersConfiguratorMixinTests(unittest.TestCase): self.assertEqual(adapter.resource, iface) self.assertEqual(adapter.request, iface) - def test_add_resource_url_nodefault_interfaces(self): + def test_add_resource_url_nodefault_resource_iface(self): from zope.interface import Interface from pyramid.interfaces import IResourceURL config = self._makeOne(autocommit=True) - config.add_resource_url_adapter(DummyResourceURL, DummyIface, - DummyIface) + config.add_resource_url_adapter(DummyResourceURL, DummyIface) iface = DummyIface() adapter = config.registry.getMultiAdapter((iface, iface), IResourceURL) @@ -208,18 +206,15 @@ class AdaptersConfiguratorMixinTests(unittest.TestCase): intr = intrs[0] self.assertEqual(intr.type_name, 'resource url adapter') self.assertEqual(intr.discriminator, - ('resource url adapter', DummyIface, None)) + ('resource url adapter', DummyIface)) self.assertEqual(intr.category_name, 'resource url adapters') self.assertEqual( intr.title, "resource url adapter for resource iface " - ", " - "request_iface None" + "" ) self.assertEqual(intr['adapter'], DummyResourceURL) self.assertEqual(intr['resource_iface'], DummyIface) - self.assertEqual(intr['request_iface'], None) - class DummyTraverser(object): def __init__(self, root): diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 3b2c96021..b514d4c16 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -9,12 +9,15 @@ from repoze.lru import lru_cache from pyramid.interfaces import ( IResourceURL, - IContextURL, IRequestFactory, ITraverser, VH_ROOT_KEY, ) +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + from pyramid.interfaces import IContextURL + from pyramid.compat import ( PY3, native_, -- cgit v1.2.3 From 72254a26514966119d2a1d28ea2ac51283ceaa68 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 18:59:58 -0500 Subject: avoid deprecation warning at import --- pyramid/traversal.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 3b2c96021..b514d4c16 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -9,12 +9,15 @@ from repoze.lru import lru_cache from pyramid.interfaces import ( IResourceURL, - IContextURL, IRequestFactory, ITraverser, VH_ROOT_KEY, ) +with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + from pyramid.interfaces import IContextURL + from pyramid.compat import ( PY3, native_, -- cgit v1.2.3 From 63c969d03564d31a2e1d691c0696e6705e297dbe Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 19:00:16 -0500 Subject: garden --- TODO.txt | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/TODO.txt b/TODO.txt index ab26a87a8..c9e7a0b9f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -4,12 +4,21 @@ Pyramid TODOs Nice-to-Have ------------ +- Create a "mako_renderer_factory_factory" that provides searches in settings + for "mako."-prefixed keys but allows other prefixes to be used to create + different factories that don't use the global mako settings. This would be + useful for the debug toolbar, which can currently be sabotaged by someone + using custom mako configuration settings. + +- Add docs about upgrading between Pyramid versions (e.g. how to see + deprecation warnings). + - Fix renderers chapter to better document system values passed to template renderers. -- Put includes in development.ini on separate lines and fix project.rst to - tell people to comment out only the debugtoolbar include when they want to - disable. +- Put includes in development.ini within scaffolding and tutorials on + separate lines and fix project.rst to tell people to comment out only the + debugtoolbar include when they want to disable. - Modify view mapper narrative docs to not use pyramid_handlers. @@ -20,23 +29,25 @@ Nice-to-Have - Introspection: - * ``default root factory`` category? + * ``default root factory`` category (prevent folks from needing to searh + "root factories" category)? - * ``default view mapper`` category? + * ``default view mapper`` category (prevent folks from needing to search + "view mappers" category)? * get rid of "tweens" category (can't sort properly?) - * implement ptweens and proutes based on introspection instead of current - state of affairs. - - * introspection hiding for directives? + * Introspection hiding for directives for purposes of omitting toolbar + registrations. Maybe toolbar can just use a null introspector? - Fix deployment recipes in cookbook (discourage proxying without changing server). - Try "with transaction.manager" in an exception view with SQLA (preempt homina homina response about how to write "to the database" from within in - an exception view). + an exception view). Note: tried this and couldn't formulate the right + situation where the database could not be written to within an exception + view (but didn't try exhaustively). - Add narrative docs for wsgiapp and wsgiapp2. @@ -44,7 +55,8 @@ Nice-to-Have - Basic WSGI documentation (pipeline / app / server). -- Change docs about creating a venusian decorator to not use ZCA. +- Change docs about creating a venusian decorator to not use ZCA (use + configurator methods instead). - Try to better explain the relationship between a renderer and a template in the templates chapter and elsewhere. Scan the documentation for reference @@ -113,6 +125,8 @@ Future - 1.5: Remove ``pyramid.requests.DeprecatedRequestMethodsMixin``. +- 1.6: Remove IContextURL and TraversalContextURL. + Probably Bad Ideas ------------------ -- cgit v1.2.3 From 95129f178f674a9f8def9aa853bacbc2b8e8f0d3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 19:00:45 -0500 Subject: dont mention arg by name --- docs/narr/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a782b9ec6..eaccc14a3 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -495,7 +495,7 @@ For example: from myapp.traversal import ResourceURLAdapter from myapp.resources import MyRoot - config.add_resource_url_adapter(ResourceURLAdapter, resource_iface=MyRoot) + config.add_resource_url_adapter(ResourceURLAdapter, MyRoot) In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will be used to provide services to :meth:`~pyramid.request.Request.resource_url` -- cgit v1.2.3 From 7f89e2d6c727d3022b38f09d72921afd9302a39c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 19:18:46 -0500 Subject: rendering --- pyramid/paster.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/paster.py b/pyramid/paster.py index cee437ec4..5102e7b9b 100644 --- a/pyramid/paster.py +++ b/pyramid/paster.py @@ -33,7 +33,7 @@ def get_app(config_uri, name=None, loadapp=loadapp): return app def get_appsettings(config_uri, name=None, appconfig=appconfig): - """ Return a dictionary representing the key/value pairs in an ``app` + """ Return a dictionary representing the key/value pairs in an ``app`` section within the file represented by ``config_uri``. If the ``name`` is None, this will attempt to parse the name from -- cgit v1.2.3 From d21ba4b61e901b27ceae36f29dac23387a8129d5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 19 Feb 2012 11:05:33 -0500 Subject: - Put ``pyramid.includes`` targets within ini files in scaffolds on separate lines in order to be able to tell people to comment out only the ``pyramid_debugtoolbar`` line when they want to disable the toolbar. --- CHANGES.txt | 7 +++++ TODO.txt | 4 --- docs/narr/MyProject/development.ini | 3 ++- docs/narr/project.rst | 31 ++++++++++++++++++---- .../wiki/src/authorization/development.ini | 8 +++--- .../wiki/src/authorization/production.ini | 6 +++-- .../tutorials/wiki/src/basiclayout/development.ini | 8 +++--- docs/tutorials/wiki/src/basiclayout/production.ini | 6 +++-- docs/tutorials/wiki/src/models/development.ini | 8 +++--- docs/tutorials/wiki/src/models/production.ini | 6 +++-- docs/tutorials/wiki/src/tests/development.ini | 8 +++--- docs/tutorials/wiki/src/tests/production.ini | 6 +++-- docs/tutorials/wiki/src/views/development.ini | 8 +++--- docs/tutorials/wiki/src/views/production.ini | 6 +++-- .../wiki2/src/authorization/development.ini | 5 ++-- .../wiki2/src/authorization/production.ini | 3 ++- .../wiki2/src/basiclayout/development.ini | 5 ++-- .../tutorials/wiki2/src/basiclayout/production.ini | 3 ++- docs/tutorials/wiki2/src/models/development.ini | 5 ++-- docs/tutorials/wiki2/src/models/production.ini | 3 ++- docs/tutorials/wiki2/src/tests/development.ini | 5 ++-- docs/tutorials/wiki2/src/tests/production.ini | 3 ++- docs/tutorials/wiki2/src/views/development.ini | 5 ++-- docs/tutorials/wiki2/src/views/production.ini | 3 ++- pyramid/scaffolds/alchemy/development.ini_tmpl | 5 ++-- pyramid/scaffolds/alchemy/production.ini_tmpl | 3 ++- pyramid/scaffolds/starter/development.ini_tmpl | 3 ++- pyramid/scaffolds/zodb/development.ini_tmpl | 8 +++--- pyramid/scaffolds/zodb/production.ini_tmpl | 6 +++-- 29 files changed, 121 insertions(+), 59 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 22f8320f9..feba9156e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -93,6 +93,13 @@ Documentation - Don't create a ``session`` instance in SQLA Wiki tutorial, use raw ``DBSession`` instead (this is more common in real SQLA apps). +Scaffolding +----------- + +- Put ``pyramid.includes`` targets within ini files in scaffolds on separate + lines in order to be able to tell people to comment out only the + ``pyramid_debugtoolbar`` line when they want to disable the toolbar. + Dependencies ------------ diff --git a/TODO.txt b/TODO.txt index c9e7a0b9f..7a3b17bc5 100644 --- a/TODO.txt +++ b/TODO.txt @@ -16,10 +16,6 @@ Nice-to-Have - Fix renderers chapter to better document system values passed to template renderers. -- Put includes in development.ini within scaffolding and tutorials on - separate lines and fix project.rst to tell people to comment out only the - debugtoolbar include when they want to disable. - - Modify view mapper narrative docs to not use pyramid_handlers. - Modify the urldispatch chapter examples to assume a scan rather than diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 2ccedb27b..3c38e3805 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar +pyramid.includes = + pyramid_debugtoolbar [server:main] use = egg:waitress#main diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4566a4fb8..5a519ca30 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -348,27 +348,48 @@ when you use the ``production.ini`` file instead of the ``development.ini`` ini file to run the application. You can also turn the debug toolbar off by editing ``development.ini`` and -commenting out the line ``pyramid.includes = pyramid_debugtoolbar``. For -example, instead of: +commenting out a line. For example, instead of: .. code-block:: ini :linenos: [app:main] ... - pyramid.includes = pyramid_debugtoolbar + pyramid.includes = + pyramid_debugtoolbar -Put a hash mark in front of the ``pyramid.includes`` line: +Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: .. code-block:: ini :linenos: [app:main] ... - #pyramid.includes = pyramid_debugtoolbar + pyramid.includes = + # pyramid_debugtoolbar Then restart the application to see that the toolbar has been turned off. +Note that if you comment out the ``pryamid_debugtoolbar`` line, the ``#`` +*must* be in the first column. If you put the hash mark anywhere except the +first column instead, for example like this: + +.. code-block:: ini + :linenos: + + [app:main] + ... + pyramid.includes = + #pyramid_debugtoolbar + +When you attempt to restart the application with a section like the abvoe +you'll receive an error that ends something like this, and the application +will not start: + +.. code-block:: text + + ImportError: No module named #pyramid_debugtoolbar + .. index:: single: project structure diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index 47566515c..74781caed 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -6,9 +6,11 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_zodbconn + pyramid_tm + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini index 919efce1e..2da493def 100644 --- a/docs/tutorials/wiki/src/authorization/production.ini +++ b/docs/tutorials/wiki/src/authorization/production.ini @@ -6,8 +6,10 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm - pyramid_zodbconn +pyramid.includes = + pyramid_tm + pyramid_zodbconn + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 3acff7f6d..5a3dba52a 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -6,9 +6,11 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_zodbconn + pyramid_tm + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini index 919efce1e..2da493def 100644 --- a/docs/tutorials/wiki/src/basiclayout/production.ini +++ b/docs/tutorials/wiki/src/basiclayout/production.ini @@ -6,8 +6,10 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm - pyramid_zodbconn +pyramid.includes = + pyramid_tm + pyramid_zodbconn + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 47566515c..74781caed 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -6,9 +6,11 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_zodbconn + pyramid_tm + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini index 919efce1e..2da493def 100644 --- a/docs/tutorials/wiki/src/models/production.ini +++ b/docs/tutorials/wiki/src/models/production.ini @@ -6,8 +6,10 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm - pyramid_zodbconn +pyramid.includes = + pyramid_tm + pyramid_zodbconn + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini index 47566515c..74781caed 100644 --- a/docs/tutorials/wiki/src/tests/development.ini +++ b/docs/tutorials/wiki/src/tests/development.ini @@ -6,9 +6,11 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_zodbconn + pyramid_tm + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini index 919efce1e..2da493def 100644 --- a/docs/tutorials/wiki/src/tests/production.ini +++ b/docs/tutorials/wiki/src/tests/production.ini @@ -6,8 +6,10 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm - pyramid_zodbconn +pyramid.includes = + pyramid_tm + pyramid_zodbconn + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index 3acff7f6d..5a3dba52a 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -6,9 +6,11 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_zodbconn + pyramid_tm + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini index 919efce1e..2da493def 100644 --- a/docs/tutorials/wiki/src/views/production.ini +++ b/docs/tutorials/wiki/src/views/production.ini @@ -6,8 +6,10 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm - pyramid_zodbconn +pyramid.includes = + pyramid_tm + pyramid_zodbconn + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 2bb74454c..06c51fb12 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index ec6dea135..cefb5c231 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 2bb74454c..06c51fb12 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index ec6dea135..cefb5c231 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index 2bb74454c..06c51fb12 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index ec6dea135..cefb5c231 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 2bb74454c..06c51fb12 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index ec6dea135..cefb5c231 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index 2bb74454c..06c51fb12 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index ec6dea135..cefb5c231 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index 1127aa00f..17ef89856 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/{{project}}.db diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index 9c9335d20..7bce40176 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/{{project}}.db diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index ee53fcf1c..4510074da 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar +pyramid.includes = + pyramid_debugtoolbar [server:main] use = egg:waitress#main diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index 6cffd5657..f24583cbf 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -7,9 +7,11 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_zodbconn + pyramid_tm + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index c0f2fbbf3..b38252d8f 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -7,8 +7,10 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm - pyramid_zodbconn +pyramid.includes = + pyramid_tm + pyramid_zodbconn + tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 -- cgit v1.2.3 From d679fac8a17d3eaf1cca9a4edaf37b4e56f1d010 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 19 Feb 2012 12:55:35 -0500 Subject: - Create a "MakoRendererFactoryHelper" that provides customizable settings key prefixes. Allows settings prefixes other than "mako." to be used to create different factories that don't use the global mako settings. This will be useful for the debug toolbar, which can currently be sabotaged by someone using custom mako configuration settings. --- CHANGES.txt | 9 +++ TODO.txt | 6 -- pyramid/mako_templating.py | 125 ++++++++++++++++++++-------------- pyramid/tests/test_mako_templating.py | 98 +++++++++++++++++--------- 4 files changed, 149 insertions(+), 89 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index feba9156e..f3ba85cc3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -105,6 +105,15 @@ Dependencies - Depend on ``venusian`` >= 1.0a3 to provide scan ``ignore`` support. +Internal +-------- + +- Create a "MakoRendererFactoryHelper" that provides customizable settings + key prefixes. Allows settings prefixes other than "mako." to be used to + create different factories that don't use the global mako settings. This + will be useful for the debug toolbar, which can currently be sabotaged by + someone using custom mako configuration settings. + 1.3a7 (2012-02-07) ================== diff --git a/TODO.txt b/TODO.txt index 7a3b17bc5..90f5f8547 100644 --- a/TODO.txt +++ b/TODO.txt @@ -4,12 +4,6 @@ Pyramid TODOs Nice-to-Have ------------ -- Create a "mako_renderer_factory_factory" that provides searches in settings - for "mako."-prefixed keys but allows other prefixes to be used to create - different factories that don't use the global mako settings. This would be - useful for the debug toolbar, which can currently be sabotaged by someone - using custom mako configuration settings. - - Add docs about upgrading between Pyramid versions (e.g. how to see deprecation warnings). diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 761695220..b2db28ba7 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -65,58 +65,79 @@ class PkgResourceTemplateLookup(TemplateLookup): registry_lock = threading.Lock() -def renderer_factory(info): - path = info.name - registry = info.registry - settings = info.settings - lookup = registry.queryUtility(IMakoLookup) - if lookup is None: - reload_templates = settings.get('reload_templates', False) - directories = settings.get('mako.directories', []) - module_directory = settings.get('mako.module_directory', None) - input_encoding = settings.get('mako.input_encoding', 'utf-8') - error_handler = settings.get('mako.error_handler', None) - default_filters = settings.get('mako.default_filters', 'h') - imports = settings.get('mako.imports', None) - strict_undefined = settings.get('mako.strict_undefined', 'false') - preprocessor = settings.get('mako.preprocessor', None) - if not is_nonstr_iter(directories): - directories = list(filter(None, directories.splitlines())) - directories = [ abspath_from_asset_spec(d) for d in directories ] - if module_directory is not None: - module_directory = abspath_from_asset_spec(module_directory) - if error_handler is not None: - dotted = DottedNameResolver(info.package) - error_handler = dotted.maybe_resolve(error_handler) - if default_filters is not None: - if not is_nonstr_iter(default_filters): - default_filters = list(filter( - None, default_filters.splitlines())) - if imports is not None: - if not is_nonstr_iter(imports): - imports = list(filter(None, imports.splitlines())) - strict_undefined = asbool(strict_undefined) - if preprocessor is not None: - dotted = DottedNameResolver(info.package) - preprocessor = dotted.maybe_resolve(preprocessor) - - - lookup = PkgResourceTemplateLookup(directories=directories, - module_directory=module_directory, - input_encoding=input_encoding, - error_handler=error_handler, - default_filters=default_filters, - imports=imports, - filesystem_checks=reload_templates, - strict_undefined=strict_undefined, - preprocessor=preprocessor) - registry_lock.acquire() - try: - registry.registerUtility(lookup, IMakoLookup) - finally: - registry_lock.release() - - return MakoLookupTemplateRenderer(path, lookup) +class MakoRendererFactoryHelper(object): + def __init__(self, settings_prefix=None): + self.settings_prefix = settings_prefix + + def __call__(self, info): + path = info.name + registry = info.registry + settings = info.settings + settings_prefix = self.settings_prefix + + if settings_prefix is None: + settings_prefix = info.type +'.' + + lookup = registry.queryUtility(IMakoLookup, name=settings_prefix) + + def sget(name, default=None): + return settings.get(settings_prefix + name, default) + + if lookup is None: + reload_templates = settings.get('pyramid.reload_templates', None) + if reload_templates is None: + reload_templates = settings.get('reload_templates', False) + reload_templates = asbool(reload_templates) + directories = sget('directories', []) + module_directory = sget('module_directory', None) + input_encoding = sget('input_encoding', 'utf-8') + error_handler = sget('error_handler', None) + default_filters = sget('default_filters', 'h') + imports = sget('imports', None) + strict_undefined = asbool(sget('strict_undefined', False)) + preprocessor = sget('preprocessor', None) + if not is_nonstr_iter(directories): + directories = list(filter(None, directories.splitlines())) + directories = [ abspath_from_asset_spec(d) for d in directories ] + if module_directory is not None: + module_directory = abspath_from_asset_spec(module_directory) + if error_handler is not None: + dotted = DottedNameResolver(info.package) + error_handler = dotted.maybe_resolve(error_handler) + if default_filters is not None: + if not is_nonstr_iter(default_filters): + default_filters = list(filter( + None, default_filters.splitlines())) + if imports is not None: + if not is_nonstr_iter(imports): + imports = list(filter(None, imports.splitlines())) + if preprocessor is not None: + dotted = DottedNameResolver(info.package) + preprocessor = dotted.maybe_resolve(preprocessor) + + + lookup = PkgResourceTemplateLookup( + directories=directories, + module_directory=module_directory, + input_encoding=input_encoding, + error_handler=error_handler, + default_filters=default_filters, + imports=imports, + filesystem_checks=reload_templates, + strict_undefined=strict_undefined, + preprocessor=preprocessor + ) + + registry_lock.acquire() + try: + registry.registerUtility(lookup, IMakoLookup, + name=settings_prefix) + finally: + registry_lock.release() + + return MakoLookupTemplateRenderer(path, lookup) + +renderer_factory = MakoRendererFactoryHelper('mako.') class MakoRenderingException(Exception): def __init__(self, text): diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index 4c444facf..0726c5250 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -21,8 +21,11 @@ class Test_renderer_factory(Base, unittest.TestCase): from pyramid.mako_templating import renderer_factory return renderer_factory(info) - def test_no_directories(self): + def _getLookup(self, name='mako.'): from pyramid.mako_templating import IMakoLookup + return self.config.registry.getUtility(IMakoLookup, name=name) + + def test_no_directories(self): info = DummyRendererInfo({ 'name':'pyramid.tests:fixtures/helloworld.mak', 'package':None, @@ -30,7 +33,7 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':{}, }) renderer = self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, []) self.assertEqual(lookup.filesystem_checks, False) self.assertEqual(renderer.path, @@ -38,7 +41,6 @@ class Test_renderer_factory(Base, unittest.TestCase): self.assertEqual(renderer.lookup, lookup) def test_no_lookup(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -47,14 +49,13 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) renderer = self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, [self.templates_dir]) self.assertEqual(lookup.filesystem_checks, False) self.assertEqual(renderer.path, 'helloworld.mak') self.assertEqual(renderer.lookup, lookup) def test_composite_directories_path(self): - from pyramid.mako_templating import IMakoLookup twice = '\n' + self.templates_dir + '\n' + self.templates_dir + '\n' settings = {'mako.directories':twice} info = DummyRendererInfo({ @@ -64,13 +65,12 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, [self.templates_dir]*2) def test_directories_list(self): import sys import os.path - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':['a', 'b']} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -79,7 +79,7 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() module_path = os.path.dirname( sys.modules['__main__'].__file__).rstrip('.') # ./setup.py self.assertEqual(lookup.directories, [ @@ -88,7 +88,6 @@ class Test_renderer_factory(Base, unittest.TestCase): def test_with_module_directory_asset_spec(self): import os - from pyramid.mako_templating import IMakoLookup module_directory = 'pyramid.tests:fixtures' settings = {'mako.directories':self.templates_dir, 'mako.module_directory':module_directory} @@ -99,13 +98,12 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') self.assertEqual(lookup.module_directory, fixtures) def test_with_module_directory_asset_abspath(self): import os - from pyramid.mako_templating import IMakoLookup fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') settings = {'mako.directories':self.templates_dir, 'mako.module_directory':fixtures} @@ -116,11 +114,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.module_directory, fixtures) def test_with_input_encoding(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.input_encoding':'utf-16'} info = DummyRendererInfo({ @@ -130,11 +127,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['input_encoding'], 'utf-16') def test_with_error_handler(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.error_handler':'pyramid.tests'} import pyramid.tests @@ -145,11 +141,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['error_handler'], pyramid.tests) def test_with_preprocessor(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.preprocessor':'pyramid.tests'} import pyramid.tests @@ -160,11 +155,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['preprocessor'], pyramid.tests) def test_with_default_filters(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.default_filters':'\nh\ng\n\n'} info = DummyRendererInfo({ @@ -174,11 +168,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) def test_with_default_filters_list(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.default_filters':['h', 'g']} info = DummyRendererInfo({ @@ -188,11 +181,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) def test_with_imports(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.imports':'\none\ntwo\n\n'} info = DummyRendererInfo({ @@ -202,11 +194,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['imports'], ['one', 'two']) def test_with_imports_list(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.imports':['one', 'two']} info = DummyRendererInfo({ @@ -216,11 +207,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['imports'], ['one', 'two']) def test_with_strict_undefined_true(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.strict_undefined':'true'} info = DummyRendererInfo({ @@ -230,11 +220,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['strict_undefined'], True) def test_with_strict_undefined_false(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.strict_undefined':'false'} info = DummyRendererInfo({ @@ -244,13 +233,13 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['strict_undefined'], False) def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() - self.config.registry.registerUtility(lookup, IMakoLookup) + self.config.registry.registerUtility(lookup, IMakoLookup, name='mako.') info = DummyRendererInfo({ 'name':'helloworld.mak', 'package':None, @@ -261,6 +250,53 @@ class Test_renderer_factory(Base, unittest.TestCase): self.assertEqual(renderer.lookup, lookup) self.assertEqual(renderer.path, 'helloworld.mak') +class MakoRendererFactoryHelperTests(Base, unittest.TestCase): + def _getTargetClass(self): + from pyramid.mako_templating import MakoRendererFactoryHelper + return MakoRendererFactoryHelper + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def _getLookup(self, name='mako.'): + from pyramid.mako_templating import IMakoLookup + return self.config.registry.getUtility(IMakoLookup, name=name) + + def test_no_settings_prefix(self): + settings = {'foo.directories':self.templates_dir} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + 'type':'foo', + }) + helper = self._makeOne() + renderer = helper(info) + lookup = self._getLookup('foo.') + self.assertEqual(lookup.directories, [self.templates_dir]) + self.assertEqual(lookup.filesystem_checks, False) + self.assertEqual(renderer.path, 'helloworld.mak') + self.assertEqual(renderer.lookup, lookup) + + def test_custom_settings_prefix(self): + settings = {'bar.directories':self.templates_dir} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + 'type':'foo', + }) + helper = self._makeOne('bar.') + renderer = helper(info) + lookup = self._getLookup('bar.') + self.assertEqual(lookup.directories, [self.templates_dir]) + self.assertEqual(lookup.filesystem_checks, False) + self.assertEqual(renderer.path, 'helloworld.mak') + self.assertEqual(renderer.lookup, lookup) + class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def _getTargetClass(self): from pyramid.mako_templating import MakoLookupTemplateRenderer -- cgit v1.2.3 From 51919e05d9c251f7f80a4736be2b822eafc5d189 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 19 Feb 2012 17:54:27 -0500 Subject: prep for 1.3a8 --- CHANGES.txt | 4 ++-- docs/conf.py | 2 +- setup.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f3ba85cc3..1df924b4c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ -Next release -============ +1.3a8 (2012-02-19) +================== Features -------- diff --git a/docs/conf.py b/docs/conf.py index 0c56f56e7..3e38226c1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -80,7 +80,7 @@ copyright = '%s, Agendaless Consulting' % datetime.datetime.now().year # other places throughout the built documents. # # The short X.Y version. -version = '1.3a7' +version = '1.3a8' # The full version, including alpha/beta/rc tags. release = version diff --git a/setup.py b/setup.py index a6cfa1480..7a5e80c67 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ if not PY3: ]) setup(name='pyramid', - version='1.3a7', + version='1.3a8', description=('The Pyramid web application development framework, a ' 'Pylons project'), long_description=README + '\n\n' + CHANGES, -- cgit v1.2.3