diff options
| author | Paul Everitt <paul@agendaless.com> | 2013-09-24 06:43:47 -0400 |
|---|---|---|
| committer | Paul Everitt <paul@agendaless.com> | 2013-09-24 06:43:47 -0400 |
| commit | 4c08a4cf1d22050527f610f8a0287a8eead522d4 (patch) | |
| tree | 5c33516b2ec37628eb3cb11ee51485bbb8e347fc | |
| parent | 55867d510658e5454e6b73055b944694b69f5668 (diff) | |
| parent | fde65302aee7d6d3ee57af06082fb4ab34e2cda6 (diff) | |
| download | pyramid-4c08a4cf1d22050527f610f8a0287a8eead522d4.tar.gz pyramid-4c08a4cf1d22050527f610f8a0287a8eead522d4.tar.bz2 pyramid-4c08a4cf1d22050527f610f8a0287a8eead522d4.zip | |
Merge branch 'master' of https://github.com/Pylons/pyramid
| -rw-r--r-- | CHANGES.txt | 136 | ||||
| m--------- | docs/_themes | 0 | ||||
| -rw-r--r-- | docs/narr/viewconfig.rst | 8 | ||||
| -rw-r--r-- | docs/whatsnew-1.5.rst | 204 | ||||
| -rw-r--r-- | pyramid/config/views.py | 22 | ||||
| -rw-r--r-- | pyramid/scaffolds/tests.py | 13 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_views.py | 42 | ||||
| -rw-r--r-- | setup.py | 5 |
8 files changed, 381 insertions, 49 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 0f04587ee..4c9ba4863 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ -Next Release -============ +1.5a2 (2013-09-22) +================== Features -------- @@ -18,44 +18,126 @@ Bug Fixes Backwards Incompatibilities --------------------------- -- Pyramid has dropped native support for the Mako and Chameleon templating - system renderers. To re-add support for these renderers into your existing - projects, there are 3 steps: +- Pyramid no longer depends on or configures the Mako and Chameleon templating + system renderers by default. Disincluding these templating systems by + default means that the Pyramid core has fewer dependencies and can run on + future platforms without immediate concern for the compatibility of its + templating add-ons. It also makes maintenance slightly more effective, as + different people can maintain the templating system add-ons that they + understand and care about without needing commit access to the Pyramid core, + and it allows users who just don't want to see any packages they don't use + come along for the ride when they install Pyramid. + + This means that upon upgrading to Pyramid 1.5a2+, projects that use either + of these templating systems will see a traceback that ends something like + this when their application attempts to render a Chameleon or Mako template:: + + ValueError: No such renderer factory .pt + + Or:: + + ValueError: No such renderer factory .mako + + Or:: - - Add ``pyramid_mako`` and/or ``pyramid_chameleon`` as dependencies by - adding them to the `install_requires` section of your package's `setup.py`:: + ValueError: No such renderer factory .mak + + Support for Mako templating has been moved into an add-on package named + ``pyramid_mako``, and support for Chameleon templating has been moved into + an add-on package named ``pyramid_chameleon``. These packages are drop-in + replacements for the old built-in support for these templating langauges. + All you have to do is install them and make them active in your configuration + to register renderer factories for ``.pt`` and/or ``.mako`` (or ``.mak``) to + make your application work again. + + To re-add support for Chameleon and/or Mako template renderers into your + existing projects, follow the below steps. + + If you depend on Mako templates: + + * Make sure the ``pyramid_mako`` package is installed. One way to do this + is by adding ``pyramid_mako`` to the ``install_requires`` section of your + package's ``setup.py`` file and afterwards rerunning ``setup.py develop``:: setup( #... install_requires=[ 'pyramid_mako', # new dependency - 'pyramid_chameleon', # new dependency 'pyramid', #... ], ) - - Update instances of the ``pyramid.config.Configurator`` to ``include`` the - one or the other (or both) required addons:: + * Within the portion of your application which instantiates a Pyramid + ``pyramid.config.Configurator`` (often the ``main()`` function in + your project's ``__init__.py`` file), tell Pyramid to include the + ``pyramid_mako`` includeme:: - config.include('pyramid_chameleon') + config = Configurator(.....) config.include('pyramid_mako') - - If any unit tests are invoking either ``pyramid.renderers.render()`` or - ``pyramid.renderers.render_to_response()`` with either Mako or Chameleon - templates then the ``pyramid.config.Configurator`` instance at the root of - the unit test should be also be updated to include the addons, as shown - above. For example:: + If you depend on Chameleon templates: - config = pyramid.testing.setUp() - config.include('pyramid_mako') + * Make sure the ``pyramid_chameleon`` package is installed. One way to do + this is by adding ``pyramid_chameleon`` to the ``install_requires`` section + of your package's ``setup.py`` file and afterwards rerunning + ``setup.py develop``:: - result = pyramid.renderers.render('mypkg:templates/home.mako', {}) + setup( + #... + install_requires=[ + 'pyramid_chameleon', # new dependency + 'pyramid', + #... + ], + ) + + * Within the portion of your application which instantiates a Pyramid + ``~pyramid.config.Configurator`` (often the ``main()`` function in + your project's ``__init__.py`` file), tell Pyramid to include the + ``pyramid_chameleon`` includeme:: - Note that if you're using the Pyramid debug toolbar, when you upgrade - Pyramid, you'll also need to upgrade the ``pyramid_debugtoolbar`` package to - at least version 1.0.8, as older versions are not compatible with Pyramid - 1.5a2+ due to this change. + config = Configurator(.....) + config.include('pyramid_chameleon') + + Note that it's also fine to install these packages into *older* Pyramids for + forward compatibility purposes. Even if you don't upgrade to Pyramid 1.5 + immediately, performing the above steps in a Pyramid 1.4 installation is + perfectly fine, won't cause any difference, and will give you forward + compatibility when you eventually do upgrade to Pyramid 1.5. + + With the removal of Mako and Chameleon support from the core, some + unit tests that use the ``pyramid.renderers.render*`` methods may begin to + fail. If any of your unit tests are invoking either + ``pyramid.renderers.render()`` or ``pyramid.renderers.render_to_response()`` + with either Mako or Chameleon templates then the + ``pyramid.config.Configurator`` instance in effect during + the unit test should be also be updated to include the addons, as shown + above. For example:: + + class ATest(unittest.TestCase): + def setUp(self): + self.config = pyramid.testing.setUp() + self.config.include('pyramid_mako') + + def test_it(self): + result = pyramid.renderers.render('mypkg:templates/home.mako', {}) + + Or:: + + class ATest(unittest.TestCase): + def setUp(self): + self.config = pyramid.testing.setUp() + self.config.include('pyramid_chameleon') + + def test_it(self): + result = pyramid.renderers.render('mypkg:templates/home.pt', {}) + +- If you're using the Pyramid debug toolbar, when you upgrade Pyramid to + 1.5a2+, you'll also need to upgrade the ``pyramid_debugtoolbar`` package to + at least version 1.0.8, as older toolbar versions are not compatible with + Pyramid 1.5a2+ due to the removal of Mako support from the core. It's + fine to use this newer version of the toolbar code with older Pyramids too. - Removed the ``request.response_*`` varying attributes. These attributes have been deprecated since Pyramid 1.1, and as per the deprecation policy, @@ -84,7 +166,7 @@ Backwards Incompatibilities instead. - Removed the ability to pass the following arguments to - ``pyramid.config.Configurator.add_route``: `view``, ``view_context``. + ``pyramid.config.Configurator.add_route``: ``view``, ``view_context``. ``view_for``, ``view_permission``, ``view_renderer``, and ``view_attr``. Using these arguments had been deprecated since Pyramid 1.1. Instead of passing view-related arguments to ``add_route``, use a separate call to @@ -165,7 +247,7 @@ Features The above example will ensure that the view is called if the request method is not POST (at least if no other view is more specific). - The :class:`pyramid.config.not_` class can be used against any value that is + The ``pyramid.config.not_`` class can be used against any value that is a predicate value passed in any of these contexts: - ``pyramid.config.Configurator.add_view`` @@ -234,9 +316,7 @@ Features In the past, only the most specific type containing views would be checked and if no matching view could be found then a PredicateMismatch would be raised. Now predicate mismatches don't hide valid views registered on - super-types. Here's an example that now works: - - .. code-block:: python + super-types. Here's an example that now works:: class IResource(Interface): diff --git a/docs/_themes b/docs/_themes -Subproject 26732645619b372764097e5e8086f89871d90c0 +Subproject f3acb7cfd1ab69510bc202676dc1d8f32128295 diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 76cf1daac..7c76116f7 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -822,7 +822,7 @@ of this: def delete(self): return Response('delete') - if __name__ == '__main__': + def main(global_config, **settings): config = Configurator() config.add_route('rest', '/rest') config.add_view( @@ -831,9 +831,10 @@ of this: RESTView, route_name='rest', attr='post', request_method='POST') config.add_view( RESTView, route_name='rest', attr='delete', request_method='DELETE') + return config.make_wsgi_app() To reduce the amount of repetition in the ``config.add_view`` statements, we -can move the ``route_name='rest'`` argument to a ``@view_default`` class +can move the ``route_name='rest'`` argument to a ``@view_defaults`` class decorator on the RESTView class: .. code-block:: python @@ -857,12 +858,13 @@ decorator on the RESTView class: def delete(self): return Response('delete') - if __name__ == '__main__': + def main(global_config, **settings): config = Configurator() config.add_route('rest', '/rest') config.add_view(RESTView, attr='get', request_method='GET') config.add_view(RESTView, attr='post', request_method='POST') config.add_view(RESTView, attr='delete', request_method='DELETE') + return config.make_wsgi_app() :class:`pyramid.view.view_defaults` accepts the same set of arguments that :class:`pyramid.view.view_config` does, and they have the same meaning. Each diff --git a/docs/whatsnew-1.5.rst b/docs/whatsnew-1.5.rst index 2a01f43bc..57f93cbff 100644 --- a/docs/whatsnew-1.5.rst +++ b/docs/whatsnew-1.5.rst @@ -7,6 +7,130 @@ incompatibilities between the two versions and deprecations added to :app:`Pyramid` 1.5, as well as software dependency changes and notable documentation additions. +Major Backwards Incompatibilities +--------------------------------- + +- Pyramid no longer depends on or configures the Mako and Chameleon templating + system renderers by default. Disincluding these templating systems by + default means that the Pyramid core has fewer dependencies and can run on + future platforms without immediate concern for the compatibility of its + templating add-ons. It also makes maintenance slightly more effective, as + different people can maintain the templating system add-ons that they + understand and care about without needing commit access to the Pyramid core, + and it allows users who just don't want to see any packages they don't use + come along for the ride when they install Pyramid. + + This means that upon upgrading to Pyramid 1.5a2+, projects that use either + of these templating systems will see a traceback that ends something like + this when their application attempts to render a Chameleon or Mako template:: + + ValueError: No such renderer factory .pt + + Or:: + + ValueError: No such renderer factory .mako + + Or:: + + ValueError: No such renderer factory .mak + + Support for Mako templating has been moved into an add-on package named + ``pyramid_mako``, and support for Chameleon templating has been moved into + an add-on package named ``pyramid_chameleon``. These packages are drop-in + replacements for the old built-in support for these templating langauges. + All you have to do is install them and make them active in your configuration + to register renderer factories for ``.pt`` and/or ``.mako`` (or ``.mak``) to + make your application work again. + + To re-add support for Chameleon and/or Mako template renderers into your + existing projects, follow the below steps. + + If you depend on Mako templates: + + * Make sure the ``pyramid_mako`` package is installed. One way to do this + is by adding ``pyramid_mako`` to the ``install_requires`` section of your + package's ``setup.py`` file and afterwards rerunning ``setup.py develop``:: + + setup( + #... + install_requires=[ + 'pyramid_mako', # new dependency + 'pyramid', + #... + ], + ) + + * Within the portion of your application which instantiates a Pyramid + :class:`~pyramid.config.Configurator` (often the ``main()`` function in + your project's ``__init__.py`` file), tell Pyramid to include the + ``pyramid_mako`` includeme:: + + config = Configurator(.....) + config.include('pyramid_mako') + + If you depend on Chameleon templates: + + * Make sure the ``pyramid_chameleon`` package is installed. One way to do + this is by adding ``pyramid_chameleon`` to the ``install_requires`` section + of your package's ``setup.py`` file and afterwards rerunning + ``setup.py develop``:: + + setup( + #... + install_requires=[ + 'pyramid_chameleon', # new dependency + 'pyramid', + #... + ], + ) + + * Within the portion of your application which instantiates a Pyramid + :class:`~pyramid.config.Configurator` (often the ``main()`` function in + your project's ``__init__.py`` file), tell Pyramid to include the + ``pyramid_chameleon`` includeme:: + + config = Configurator(.....) + config.include('pyramid_chameleon') + + Note that it's also fine to install these packages into *older* Pyramids for + forward compatibility purposes. Even if you don't upgrade to Pyramid 1.5 + immediately, performing the above steps in a Pyramid 1.4 installation is + perfectly fine, won't cause any difference, and will give you forward + compatibility when you eventually do upgrade to Pyramid 1.5. + + With the removal of Mako and Chameleon support from the core, some + unit tests that use the ``pyramid.renderers.render*`` methods may begin to + fail. If any of your unit tests are invoking either + ``pyramid.renderers.render()`` or ``pyramid.renderers.render_to_response()`` + with either Mako or Chameleon templates then the + ``pyramid.config.Configurator`` instance in effect during + the unit test should be also be updated to include the addons, as shown + above. For example:: + + class ATest(unittest.TestCase): + def setUp(self): + self.config = pyramid.testing.setUp() + self.config.include('pyramid_mako') + + def test_it(self): + result = pyramid.renderers.render('mypkg:templates/home.mako', {}) + + Or:: + + class ATest(unittest.TestCase): + def setUp(self): + self.config = pyramid.testing.setUp() + self.config.include('pyramid_chameleon') + + def test_it(self): + result = pyramid.renderers.render('mypkg:templates/home.pt', {}) + +- If you're using the Pyramid debug toolbar, when you upgrade Pyramid to + 1.5a2+, you'll also need to upgrade the ``pyramid_debugtoolbar`` package to + at least version 1.0.8, as older toolbar versions are not compatible with + Pyramid 1.5a2+ due to the removal of Mako support from the core. It's + fine to use this newer version of the toolbar code with older Pyramids too. + Feature Additions ----------------- @@ -181,8 +305,19 @@ The feature additions in Pyramid 1.5 follow. - The ``alchemy`` scaffold tests now provide better coverage. See https://github.com/Pylons/pyramid/pull/1029 -Backwards Incompatibilities ---------------------------- +- Users can now provide dotted Python names to as the ``factory`` argument + the Configurator methods named + :meth:`~pyramid.config.Configurator.add_view_predicate`, + :meth:`~pyramid.config.Configurator.add_route_predicate` and + :meth:`~pyramid.config.Configurator.add_subscriber_predicate`. Instead of + passing the predicate factory directly, you can pass a dotted name which + refers to the factory. + +- :func:`pyramid.path.package_name` no longer thows an exception when resolving + the package name for namespace packages that have no ``__file__`` attribute. + +Other Backwards Incompatibilities +--------------------------------- - Modified the :meth:`~pyramid.request.Reuqest.current_route_url` method. The method previously returned the URL without the query string by default, it @@ -210,6 +345,65 @@ Backwards Incompatibilities attributes: ``virtual_path_tuple`` and ``physical_path_tuple``. These should be the tuple form of the resource's path (physical and virtual). +- Removed the ``request.response_*`` varying attributes (such + as``request.response_headers``) . These attributes had been deprecated + since Pyramid 1.1, and as per the deprecation policy, have now been removed. + +- ``request.response`` will no longer be mutated when using the + :func:`pyramid.renderers.render` API. Almost all renderers mutate the + ``request.response`` response object (for example, the JSON renderer sets + ``request.response.content_type`` to ``application/json``), but this is + only necessary when the renderer is generating a response; it was a bug + when it was done as a side effect of calling + :func:`pyramid.renderers.render`. + +- Removed the ``bfg2pyramid`` fixer script. + +- The :class:`pyramid.events.NewResponse` event is now sent **after** response + callbacks are executed. It previously executed before response callbacks + were executed. Rationale: it's more useful to be able to inspect the response + after response callbacks have done their jobs instead of before. + +- Removed the class named ``pyramid.view.static`` that had been deprecated + since Pyramid 1.1. Instead use :class:`pyramid.static.static_view` with the + ``use_subpath=True`` argument. + +- Removed the ``pyramid.view.is_response`` function that had been deprecated + since Pyramid 1.1. Use the :meth:`pyramid.request.Request.is_response` + method instead. + +- Removed the ability to pass the following arguments to + :meth:`pyramid.config.Configurator.add_route`: ``view``, ``view_context``. + ``view_for``, ``view_permission``, ``view_renderer``, and ``view_attr``. + Using these arguments had been deprecated since Pyramid 1.1. Instead of + passing view-related arguments to ``add_route``, use a separate call to + :meth:`pyramid.config.Configurator.add_view` to associate a view with a route + using its ``route_name`` argument. Note that this impacts the + :meth:`pyramid.config.Configurator.add_static_view` function too, because + it delegates to``add_route``. + +- Removed the ability to influence and query a :class:`pyramid.request.Request` + object as if it were a dictionary. Previously it was possible to use methods + like ``__getitem__``, ``get``, ``items``, and other dictlike methods to + access values in the WSGI environment. This behavior had been deprecated + since Pyramid 1.1. Use methods of ``request.environ`` (a real dictionary) + instead. + +- Removed ancient backwards compatibily hack in + ``pyramid.traversal.DefaultRootFactory`` which populated the ``__dict__`` of + the factory with the matchdict values for compatibility with BFG 0.9. + +- The ``renderer_globals_factory`` argument to the + :class:`pyramid.config.Configurator` constructor and the + coresponding argument to :meth:`~pyramid.config.Configurator.setup_registry` + has been removed. The ``set_renderer_globals_factory`` method of + :class:`~pyramid.config.Configurator` has also been removed. The (internal) + ``pyramid.interfaces.IRendererGlobals`` interface was also removed. These + arguments, methods and interfaces had been deprecated since 1.1. Use a + ``BeforeRender`` event subscriber as documented in the "Hooks" chapter of the + Pyramid narrative documentation instead of providing renderer globals values + to the configurator. + Deprecations ------------ @@ -219,6 +413,10 @@ Deprecations ``foo#defname.mak`` in the view configuration definition and return a dict only. +- The :meth:`pyramid.config.Configurator.set_request_property` method now issues + a deprecation warning when used. It had been docs-deprecated in 1.4 + but did not issue a deprecation warning when used. + Documentation Enhancements -------------------------- @@ -231,5 +429,5 @@ Documentation Enhancements Dependency Changes ------------------ -No dependency changes from Pyramid 1.4.X were made in Pyramid 1.5. +- Pyramid no longer depends upon ``Mako`` or ``Chameleon``. diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 16deee987..233bbac12 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1149,6 +1149,8 @@ class ViewsConfiguratorMixin(object): attr, self.object_description(view)) else: view_desc = self.object_description(view) + + tmpl_intr = None view_intr = self.introspectable('views', discriminator, @@ -1199,7 +1201,8 @@ class ViewsConfiguratorMixin(object): renderer = renderers.RendererHelper( name=None, package=self.package, - registry=self.registry) + registry=self.registry + ) if permission is None: # intent: will be None if no default permission is registered @@ -1330,6 +1333,22 @@ class ViewsConfiguratorMixin(object): multiview, (IExceptionViewClassifier, request_iface, context), IMultiView, name=name) + renderer_type = getattr(renderer, 'type', None) # gard against None + intrspc = self.introspector + if ( + renderer_type is not None and + tmpl_intr is not None and + intrspc is not None and + intrspc.get('renderer factories', renderer_type) is not None + ): + # allow failure of registered template factories to be deferred + # until view execution, like other bad renderer factories; if + # we tried to relate this to an existing renderer factory + # without checking if it the factory actually existed, we'd end + # up with a KeyError at startup time, which is inconsistent + # with how other bad renderer registrations behave (they throw + # a ValueError at view execution time) + tmpl_intr.relate('renderer factories', renderer.type) if mapper: mapper_intr = self.introspectable( @@ -1355,7 +1374,6 @@ class ViewsConfiguratorMixin(object): tmpl_intr['name'] = renderer.name tmpl_intr['type'] = renderer.type tmpl_intr['renderer'] = renderer - tmpl_intr.relate('renderer factories', renderer.type) introspectables.append(tmpl_intr) if permission is not None: # if a permission exists, register a permission introspectable diff --git a/pyramid/scaffolds/tests.py b/pyramid/scaffolds/tests.py index b90e494e9..d913d022a 100644 --- a/pyramid/scaffolds/tests.py +++ b/pyramid/scaffolds/tests.py @@ -9,22 +9,18 @@ import time try: import httplib except ImportError: # pragma: no cover - import http.client as httplib - -from pyramid.compat import PY3 + import http.client as httplib #py3 class TemplateTest(object): def make_venv(self, directory): # pragma: no cover import virtualenv - import sys from virtualenv import Logger logger = Logger([(Logger.level_for_integer(2), sys.stdout)]) virtualenv.logger = logger virtualenv.create_environment(directory, site_packages=False, clear=False, - unzip_setuptools=True, - use_distribute=PY3) + unzip_setuptools=True) def install(self, tmpl_name): # pragma: no cover try: self.old_cwd = os.getcwd() @@ -70,10 +66,7 @@ class TemplateTest(object): os.chdir(self.old_cwd) if __name__ == '__main__': # pragma: no cover - templates = ['starter', 'alchemy',] - - if sys.version_info >= (2, 6) and sys.version_info < (3, 0): - templates.append('zodb') + templates = ['starter', 'alchemy', 'zodb'] for name in templates: test = TemplateTest() diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index d9e0d17a6..be2865d30 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -109,6 +109,37 @@ class TestViewsConfigurationMixin(unittest.TestCase): view = self._getViewCallable(config) self.assertTrue(b'Hello!' in view(None, None).body) + def test_add_view_with_tmpl_renderer_factory_introspector_missing(self): + config = self._makeOne(autocommit=True) + config.introspection = False + config.introspector = None + config.add_view(renderer='dummy.pt') + view = self._getViewCallable(config) + self.assertRaises(ValueError, view, None, None) + + def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self): + config = self._makeOne(autocommit=True) + introspector = DummyIntrospector() + config.introspector = introspector + config.add_view(renderer='dummy.pt') + self.assertFalse(('renderer factories', '.pt') in + introspector.related[-1]) + view = self._getViewCallable(config) + self.assertRaises(ValueError, view, None, None) + + def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self): + config = self._makeOne(autocommit=True) + introspector = DummyIntrospector(True) + config.introspector = introspector + def dummy_factory(helper): + return lambda val, system_vals: 'Hello!' + config.add_renderer('.pt', dummy_factory) + config.add_view(renderer='dummy.pt') + self.assertTrue( + ('renderer factories', '.pt') in introspector.related[-1]) + view = self._getViewCallable(config) + self.assertTrue(b'Hello!' in view(None, None).body) + def test_add_view_wrapped_view_is_decorated(self): def view(request): # request-only wrapper """ """ @@ -3954,3 +3985,14 @@ class DummyPredicate(object): phash = text +class DummyIntrospector(object): + def __init__(self, getval=None): + self.related = [] + self.introspectables = [] + self.getval = getval + def add(self, introspectable): + self.introspectables.append(introspectable) + def get(self, name, discrim): + return self.getval + def relate(self, a, b): + self.related.append((a, b)) @@ -69,9 +69,8 @@ testing_extras = tests_require + [ ] setup(name='pyramid', - version='1.5a1', - description=('The Pyramid Web Framework, a ' - 'Pylons project'), + version='1.5a2', + description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ "Intended Audience :: Developers", |
