From aa7b06b946b4e8e66818da29e64e9cbccb6ccb10 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 2 Sep 2013 01:03:02 -0400 Subject: move docs section to a more appropriate place --- docs/narr/viewconfig.rst | 59 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e09fd83ab..76cf1daac 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -465,6 +465,36 @@ configured view. .. versionadded:: 1.4a1 +Inverting Predicate Values +++++++++++++++++++++++++++ + +You can invert the meaning of any predicate value by wrapping it in a call to +:class:`pyramid.config.not_`. + +.. code-block:: python + :linenos: + + from pyramid.config import not_ + + config.add_view( + 'mypackage.views.my_view', + route_name='ok', + request_method=not_('POST') + ) + +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. + +This technique of wrapping a predicate value in ``not_`` can be used anywhere +predicate values are accepted: + +- :meth:`pyramid.config.Configurator.add_view` + +- :meth:`pyramid.view.view_config` + +.. versionadded:: 1.5 + + .. index:: single: view_config decorator @@ -557,35 +587,6 @@ form of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. -Inverting Predicate Values -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can invert the meaning of any predicate value by wrapping it in a call to -:class:`pyramid.config.not_`. - -.. code-block:: python - :linenos: - - from pyramid.config import not_ - - config.add_view( - 'mypackage.views.my_view', - route_name='ok', - request_method=not_('POST') - ) - -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. - -This technique of wrapping a predicate value in ``not_`` can be used anywhere -predicate values are accepted: - -- :meth:`pyramid.config.Configurator.add_view` - -- :meth:`pyramid.view.view_config` - -.. versionadded:: 1.5 - .. index:: single: view_config placement -- cgit v1.2.3 From 5bc4ad0247dee14e37d28c28b35ab282310be2d6 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 17:32:18 -0600 Subject: Remove the mako templating --- pyramid/mako_templating.py | 252 --------------------------------------------- 1 file changed, 252 deletions(-) delete mode 100644 pyramid/mako_templating.py diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py deleted file mode 100644 index 01456c3d4..000000000 --- a/pyramid/mako_templating.py +++ /dev/null @@ -1,252 +0,0 @@ -import os -import posixpath -import sys -import threading -import warnings - -from zope.interface import ( - implementer, - Interface, - ) - -from pyramid.asset import ( - resolve_asset_spec, - abspath_from_asset_spec, - ) - -from pyramid.compat import ( - is_nonstr_iter, - reraise, - ) - -from pyramid.interfaces import ITemplateRenderer -from pyramid.settings import asbool -from pyramid.util import DottedNameResolver - -def _no_mako(*arg, **kw): # pragma: no cover - raise NotImplementedError( - "'mako' package is not importable (maybe downgrade MarkupSafe to " - "0.16 or below if you're using Python 3.2)" - ) - -try: - from mako.lookup import TemplateLookup -except (ImportError, SyntaxError, AttributeError): #pragma NO COVER - class TemplateLookup(object): - def __init__(self, **kw): - for name in ('adjust_uri', 'get_template', 'filename_to_uri', - 'put_string', 'put_template'): - setattr(self, name, _no_mako) - self.filesystem_checks = False - -try: - from mako.exceptions import TopLevelLookupException -except (ImportError, SyntaxError, AttributeError): #pragma NO COVER - class TopLevelLookupException(Exception): - pass - -try: - from mako.exceptions import text_error_template -except (ImportError, SyntaxError, AttributeError): #pragma NO COVER - def text_error_template(lookup=None): - _no_mako() - - -class IMakoLookup(Interface): - pass - -class PkgResourceTemplateLookup(TemplateLookup): - """TemplateLookup subclass that handles asset specification URIs""" - def adjust_uri(self, uri, relativeto): - """Called from within a Mako template, avoids adjusting the - uri if it looks like an asset specification""" - # Don't adjust asset spec names - isabs = os.path.isabs(uri) - if (not isabs) and (':' in uri): - return uri - if not(isabs) and ('$' in uri): - return uri.replace('$', ':') - if relativeto is not None: - relativeto = relativeto.replace('$', ':') - if not(':' in uri) and (':' in relativeto): - if uri.startswith('/'): - return uri - pkg, relto = relativeto.split(':') - _uri = posixpath.join(posixpath.dirname(relto), uri) - return '{0}:{1}'.format(pkg, _uri) - if not(':' in uri) and not(':' in relativeto): - return posixpath.join(posixpath.dirname(relativeto), uri) - return TemplateLookup.adjust_uri(self, uri, relativeto) - - def get_template(self, uri): - """Fetch a template from the cache, or check the filesystem - for it - - In addition to the basic filesystem lookup, this subclass will - use pkg_resource to load a file using the asset - specification syntax. - - """ - isabs = os.path.isabs(uri) - if (not isabs) and (':' in uri): - # Windows can't cope with colons in filenames, so we replace the - # colon with a dollar sign in the filename mako uses to actually - # store the generated python code in the mako module_directory or - # in the temporary location of mako's modules - adjusted = uri.replace(':', '$') - try: - if self.filesystem_checks: - return self._check(adjusted, self._collection[adjusted]) - else: - return self._collection[adjusted] - except KeyError: - pname, path = resolve_asset_spec(uri) - srcfile = abspath_from_asset_spec(path, pname) - if os.path.isfile(srcfile): - return self._load(srcfile, adjusted) - raise TopLevelLookupException( - "Can not locate template for uri %r" % uri) - return TemplateLookup.get_template(self, uri) - -registry_lock = threading.Lock() - -class MakoRendererFactoryHelper(object): - def __init__(self, settings_prefix=None): - self.settings_prefix = settings_prefix - - def __call__(self, info): - defname = None - asset, ext = info.name.rsplit('.', 1) - if '#' in asset: - asset, defname = asset.rsplit('#', 1) - - path = '%s.%s' % (asset, ext) - 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 - ) - - with registry_lock: - registry.registerUtility(lookup, IMakoLookup, - name=settings_prefix) - - return MakoLookupTemplateRenderer(path, defname, lookup) - -renderer_factory = MakoRendererFactoryHelper('mako.') - -class MakoRenderingException(Exception): - def __init__(self, text): - self.text = text - - def __repr__(self): - return self.text - - __str__ = __repr__ - -@implementer(ITemplateRenderer) -class MakoLookupTemplateRenderer(object): - """ Render a :term:`Mako` template using the template - implied by the ``path`` argument.The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`asset - specification`. If a defname is defined, in the form of - package:path/to/template#defname.mako, a function named ``defname`` - inside the template will then be rendered. - """ - warnings = warnings # for testing - - def __init__(self, path, defname, lookup): - self.path = path - self.defname = defname - self.lookup = lookup - - def implementation(self): - return self.lookup.get_template(self.path) - - def __call__(self, value, system): - context = system.pop('context', None) - if context is not None: - system['_context'] = context - # tuple returned to be deprecated - if isinstance(value, tuple): - self.warnings.warn( - 'Using a tuple in the form (\'defname\', {}) to render a ' - 'Mako partial will be deprecated in the future. Use a ' - 'Mako template renderer as documented in the "Using A ' - 'Mako def name Within a Renderer Name" chapter of the ' - 'Pyramid narrative documentation instead', - DeprecationWarning, - 3) - self.defname, value = value - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - template = self.implementation() - if self.defname is not None: - template = template.get_def(self.defname) - try: - result = template.render_unicode(**system) - except: - try: - exc_info = sys.exc_info() - errtext = text_error_template().render( - error=exc_info[1], - traceback=exc_info[2] - ) - reraise(MakoRenderingException(errtext), None, exc_info[2]) - finally: - del exc_info - - return result -- cgit v1.2.3 From b089c545920100b798c9806796b0c0ebf94db367 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 17:34:55 -0600 Subject: Remove requirement from setup.py --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 6c6f1723f..523dab191 100644 --- a/setup.py +++ b/setup.py @@ -40,7 +40,6 @@ except IOError: install_requires=[ 'setuptools', 'Chameleon >= 1.2.3', - 'Mako >= 0.3.6', # strict_undefined 'WebOb >= 1.2b3', # request.path_info is unicode 'repoze.lru >= 0.4', # py3 compat 'zope.interface >= 3.8.0', # has zope.interface.registry -- cgit v1.2.3 From fb5930b08b70de69bc6ea0d2f6098acefc1706e1 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 17:49:56 -0600 Subject: Remove mako test specific files These files now live in the pyramid_mako git repository... --- pyramid/tests/fixtures/components.mak | 3 - pyramid/tests/fixtures/hello .world.mako | 3 - pyramid/tests/fixtures/hello_inherit_pkg.mak | 2 - pyramid/tests/fixtures/hellocompo.mak | 3 - pyramid/tests/fixtures/helloinherit.mak | 2 - pyramid/tests/fixtures/helloworld.mak | 3 - pyramid/tests/fixtures/helloworld.mako | 3 - pyramid/tests/fixtures/layout.mak | 2 - pyramid/tests/fixtures/nonminimal.mak | 1 - pyramid/tests/test_mako_templating.py | 655 --------------------------- 10 files changed, 677 deletions(-) delete mode 100644 pyramid/tests/fixtures/components.mak delete mode 100644 pyramid/tests/fixtures/hello .world.mako delete mode 100644 pyramid/tests/fixtures/hello_inherit_pkg.mak delete mode 100644 pyramid/tests/fixtures/hellocompo.mak delete mode 100644 pyramid/tests/fixtures/helloinherit.mak delete mode 100644 pyramid/tests/fixtures/helloworld.mak delete mode 100644 pyramid/tests/fixtures/helloworld.mako delete mode 100644 pyramid/tests/fixtures/layout.mak delete mode 100644 pyramid/tests/fixtures/nonminimal.mak delete mode 100644 pyramid/tests/test_mako_templating.py diff --git a/pyramid/tests/fixtures/components.mak b/pyramid/tests/fixtures/components.mak deleted file mode 100644 index cc886805c..000000000 --- a/pyramid/tests/fixtures/components.mak +++ /dev/null @@ -1,3 +0,0 @@ -<%def name="comp()"> -World! - \ No newline at end of file diff --git a/pyramid/tests/fixtures/hello .world.mako b/pyramid/tests/fixtures/hello .world.mako deleted file mode 100644 index 7a06eed97..000000000 --- a/pyramid/tests/fixtures/hello .world.mako +++ /dev/null @@ -1,3 +0,0 @@ -## -*- coding: utf-8 -*- -<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %> -Hello ${text_('föö', 'utf-8')} \ No newline at end of file diff --git a/pyramid/tests/fixtures/hello_inherit_pkg.mak b/pyramid/tests/fixtures/hello_inherit_pkg.mak deleted file mode 100644 index 87d18d0f7..000000000 --- a/pyramid/tests/fixtures/hello_inherit_pkg.mak +++ /dev/null @@ -1,2 +0,0 @@ -Hello World! -<%inherit file="pyramid.tests:fixtures/layout.mak"/> \ No newline at end of file diff --git a/pyramid/tests/fixtures/hellocompo.mak b/pyramid/tests/fixtures/hellocompo.mak deleted file mode 100644 index 142676a11..000000000 --- a/pyramid/tests/fixtures/hellocompo.mak +++ /dev/null @@ -1,3 +0,0 @@ -<%namespace name="comp" file="pyramid.tests:fixtures/components.mak"/> -Namespace -Hello ${comp.comp()} \ No newline at end of file diff --git a/pyramid/tests/fixtures/helloinherit.mak b/pyramid/tests/fixtures/helloinherit.mak deleted file mode 100644 index 53edd71ed..000000000 --- a/pyramid/tests/fixtures/helloinherit.mak +++ /dev/null @@ -1,2 +0,0 @@ -Hello World! -<%inherit file="layout.mak"/> \ No newline at end of file diff --git a/pyramid/tests/fixtures/helloworld.mak b/pyramid/tests/fixtures/helloworld.mak deleted file mode 100644 index 25283a50d..000000000 --- a/pyramid/tests/fixtures/helloworld.mak +++ /dev/null @@ -1,3 +0,0 @@ -## -*- coding: utf-8 -*- -<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %> -Hello ${text_('föö', 'utf-8')} diff --git a/pyramid/tests/fixtures/helloworld.mako b/pyramid/tests/fixtures/helloworld.mako deleted file mode 100644 index 25283a50d..000000000 --- a/pyramid/tests/fixtures/helloworld.mako +++ /dev/null @@ -1,3 +0,0 @@ -## -*- coding: utf-8 -*- -<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %> -Hello ${text_('föö', 'utf-8')} diff --git a/pyramid/tests/fixtures/layout.mak b/pyramid/tests/fixtures/layout.mak deleted file mode 100644 index 3bef88bf8..000000000 --- a/pyramid/tests/fixtures/layout.mak +++ /dev/null @@ -1,2 +0,0 @@ -Layout -${next.body()} \ No newline at end of file diff --git a/pyramid/tests/fixtures/nonminimal.mak b/pyramid/tests/fixtures/nonminimal.mak deleted file mode 100644 index 9de95ec92..000000000 --- a/pyramid/tests/fixtures/nonminimal.mak +++ /dev/null @@ -1 +0,0 @@ -Hello, ${name}! diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py deleted file mode 100644 index 69485ca19..000000000 --- a/pyramid/tests/test_mako_templating.py +++ /dev/null @@ -1,655 +0,0 @@ -## come on python gimme some of that sweet, sweet -*- coding: utf-8 -*- - -import shutil -import tempfile -import unittest - -from pyramid import testing - -from pyramid.compat import ( - text_, - text_type, - ) - -class Base(object): - def setUp(self): - self.config = testing.setUp() - self.config.begin() - import os - here = os.path.abspath(os.path.dirname(__file__)) - self.templates_dir = os.path.join(here, 'fixtures') - - def tearDown(self): - self.config.end() - -def maybe_unittest(): - # The latest release of MarkupSafe (0.17) which is used by Mako is - # incompatible with Python 3.2, so we skip these tests if we cannot - # import a Mako module which ends up importing MarkupSafe. Note that - # this version of MarkupSafe *is* compatible with Python 2.6, 2.7, and 3.3, - # so these tests should not be skipped on those platforms. - try: - import mako.lookup - except (ImportError, SyntaxError, AttributeError): # pragma: no cover - return object - else: - return unittest.TestCase - -class Test_renderer_factory(Base, maybe_unittest()): - def _callFUT(self, info): - from pyramid.mako_templating import renderer_factory - return renderer_factory(info) - - def _getLookup(self, name='mako.'): - from pyramid.mako_templating import IMakoLookup - return self.config.registry.getUtility(IMakoLookup, name=name) - - def test_hyphen_filenames(self): - from pyramid.mako_templating import renderer_factory - - info = DummyRendererInfo({ - 'name':'app:moon-and-world.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type': '' - }) - - result = renderer_factory(info) - self.assertEqual(result.path, 'app:moon-and-world.mak') - - def test_no_directories(self): - info = DummyRendererInfo({ - 'name':'pyramid.tests:fixtures/helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - renderer = self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.directories, []) - self.assertEqual(lookup.filesystem_checks, False) - self.assertEqual(renderer.path, - 'pyramid.tests:fixtures/helloworld.mak') - self.assertEqual(renderer.lookup, lookup) - - def test_no_lookup(self): - settings = {'mako.directories':self.templates_dir} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - renderer = self._callFUT(info) - 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): - twice = '\n' + self.templates_dir + '\n' + self.templates_dir + '\n' - settings = {'mako.directories':twice} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.directories, [self.templates_dir]*2) - - def test_directories_list(self): - import sys - import os.path - settings = {'mako.directories':['a', 'b']} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - module_path = os.path.dirname( - sys.modules['__main__'].__file__).rstrip('.') # ./setup.py - self.assertEqual(lookup.directories, [ - os.path.join(module_path, 'a'), - os.path.join(module_path, 'b')]) - - def test_with_module_directory_asset_spec(self): - import os - module_directory = 'pyramid.tests:fixtures' - settings = {'mako.directories':self.templates_dir, - 'mako.module_directory':module_directory} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - 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 - fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') - settings = {'mako.directories':self.templates_dir, - 'mako.module_directory':fixtures} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.module_directory, fixtures) - - def test_with_input_encoding(self): - settings = {'mako.directories':self.templates_dir, - 'mako.input_encoding':'utf-16'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['input_encoding'], 'utf-16') - - def test_with_error_handler(self): - settings = {'mako.directories':self.templates_dir, - 'mako.error_handler':'pyramid.tests'} - import pyramid.tests - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['error_handler'], pyramid.tests) - - def test_with_preprocessor(self): - settings = {'mako.directories':self.templates_dir, - 'mako.preprocessor':'pyramid.tests'} - import pyramid.tests - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['preprocessor'], pyramid.tests) - - def test_with_default_filters(self): - settings = {'mako.directories':self.templates_dir, - 'mako.default_filters':'\nh\ng\n\n'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) - - def test_with_default_filters_list(self): - settings = {'mako.directories':self.templates_dir, - 'mako.default_filters':['h', 'g']} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) - - def test_with_imports(self): - settings = {'mako.directories':self.templates_dir, - 'mako.imports':'\none\ntwo\n\n'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['imports'], ['one', 'two']) - - def test_with_imports_list(self): - settings = {'mako.directories':self.templates_dir, - 'mako.imports':['one', 'two']} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['imports'], ['one', 'two']) - - def test_with_strict_undefined_true(self): - settings = {'mako.directories':self.templates_dir, - 'mako.strict_undefined':'true'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - lookup = self._getLookup() - self.assertEqual(lookup.template_args['strict_undefined'], True) - - def test_with_strict_undefined_false(self): - settings = {'mako.directories':self.templates_dir, - 'mako.strict_undefined':'false'} - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':settings, - }) - self._callFUT(info) - 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, name='mako.') - info = DummyRendererInfo({ - 'name':'helloworld.mak', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - renderer = self._callFUT(info) - self.assertEqual(renderer.lookup, lookup) - self.assertEqual(renderer.path, 'helloworld.mak') - - def test_space_dot_name(self): - from pyramid.mako_templating import renderer_factory - - info = DummyRendererInfo({ - 'name':'hello .world.mako', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - - result = renderer_factory(info) - self.assertEqual(result.path, 'hello .world.mako') - self.assertTrue(result.defname is None) - - def test_space_dot_name_def(self): - from pyramid.mako_templating import renderer_factory - - info = DummyRendererInfo({ - 'name':'hello .world#comp.mako', - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - }) - - result = renderer_factory(info) - self.assertEqual(result.path, 'hello .world.mako') - self.assertEqual(result.defname, 'comp') - -class MakoRendererFactoryHelperTests(Base, maybe_unittest()): - 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, maybe_unittest()): - def _getTargetClass(self): - from pyramid.mako_templating import MakoLookupTemplateRenderer - return MakoLookupTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITemplateRenderer - verifyObject(ITemplateRenderer, self._makeOne(None, None, None)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_call(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - result = instance({}, {'system':1}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - - def test_call_with_system_context(self): - # lame - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - result = instance({}, {'context':1}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - - def test_call_with_tuple_value(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - warnings = DummyWarnings() - instance.warnings = warnings - result = instance(('fub', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'fub') - self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - self.assertEqual(len(warnings.msgs), 1) - - def test_call_with_defname(self): - lookup = DummyLookup() - instance = self._makeOne('path', 'defname', lookup) - result = instance({}, {'system':1}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - - def test_call_with_defname_with_tuple_value(self): - lookup = DummyLookup() - instance = self._makeOne('path', 'defname', lookup) - warnings = DummyWarnings() - instance.warnings = warnings - result = instance(('defname', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'defname') - self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - self.assertEqual(len(warnings.msgs), 1) - - def test_call_with_defname_with_tuple_value_twice(self): - lookup = DummyLookup() - instance1 = self._makeOne('path', 'defname', lookup) - warnings = DummyWarnings() - instance1.warnings = warnings - result1 = instance1(('defname1', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'defname1') - self.assertEqual(result1, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) - instance2 = self._makeOne('path', 'defname', lookup) - warnings = DummyWarnings() - instance2.warnings = warnings - result2 = instance2(('defname2', {}), {'context':2}) - self.assertNotEqual(lookup.deffed, 'defname1') - self.assertEqual(lookup.deffed, 'defname2') - self.assertEqual(result2, text_('result')) - self.assertEqual(lookup.values, {'_context':2}) - - def test_call_with_nondict_value(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - self.assertRaises(ValueError, instance, None, {}) - - def test_call_render_raises(self): - from pyramid.mako_templating import MakoRenderingException - lookup = DummyLookup(exc=NotImplementedError) - instance = self._makeOne('path', None, lookup) - try: - instance({}, {}) - except MakoRenderingException as e: - self.assertTrue('NotImplementedError' in e.text) - else: # pragma: no cover - raise AssertionError - - def test_implementation(self): - lookup = DummyLookup() - instance = self._makeOne('path', None, lookup) - result = instance.implementation().render_unicode() - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result, text_('result')) - -class TestIntegration(maybe_unittest()): - def setUp(self): - import pyramid.mako_templating - self.config = testing.setUp() - self.config.add_settings({'mako.directories': - 'pyramid.tests:fixtures'}) - self.config.add_renderer('.mak', - pyramid.mako_templating.renderer_factory) - - def tearDown(self): - self.config.end() - - def test_render(self): - from pyramid.renderers import render - result = render('helloworld.mak', {'a':1}).replace('\r','') - self.assertEqual(result, text_('\nHello föö\n', 'utf-8')) - - def test_render_from_fs(self): - from pyramid.renderers import render - self.config.add_settings({'reload_templates': True}) - result = render('helloworld.mak', {'a':1}).replace('\r','') - self.assertEqual(result, text_('\nHello föö\n', 'utf-8')) - - def test_render_inheritance(self): - from pyramid.renderers import render - result = render('helloinherit.mak', {}).replace('\r','') - self.assertEqual(result, text_('Layout\nHello World!\n')) - - def test_render_inheritance_pkg_spec(self): - from pyramid.renderers import render - result = render('hello_inherit_pkg.mak', {}).replace('\r','') - self.assertEqual(result, text_('Layout\nHello World!\n')) - - def test_render_namespace(self): - from pyramid.renderers import render - result = render('hellocompo.mak', {}).replace('\r','') - self.assertEqual(result, text_('\nNamespace\nHello \nWorld!\n')) - - def test_render_to_response(self): - from pyramid.renderers import render_to_response - result = render_to_response('helloworld.mak', {'a':1}) - self.assertEqual(result.ubody.replace('\r',''), - text_('\nHello föö\n', 'utf-8')) - - def test_render_to_response_pkg_spec(self): - from pyramid.renderers import render_to_response - result = render_to_response('pyramid.tests:fixtures/helloworld.mak', - {'a':1}) - self.assertEqual(result.ubody.replace('\r', ''), - text_('\nHello föö\n', 'utf-8')) - - def test_render_with_abs_path(self): - from pyramid.renderers import render - result = render('/helloworld.mak', {'a':1}).replace('\r','') - self.assertEqual(result, text_('\nHello föö\n', 'utf-8')) - - def test_get_renderer(self): - from pyramid.renderers import get_renderer - result = get_renderer('helloworld.mak') - self.assertEqual( - result.implementation().render_unicode().replace('\r',''), - text_('\nHello föö\n', 'utf-8')) - - def test_template_not_found(self): - from pyramid.renderers import render - from mako.exceptions import TemplateLookupException - self.assertRaises(TemplateLookupException, render, - 'helloworld_not_here.mak', {}) - - def test_template_default_escaping(self): - from pyramid.renderers import render - result = render('nonminimal.mak', - {'name':'fred'}).replace('\r','') - self.assertEqual(result, text_('Hello, <b>fred</b>!\n')) - -class TestPkgResourceTemplateLookup(maybe_unittest()): - def _makeOne(self, **kw): - from pyramid.mako_templating import PkgResourceTemplateLookup - return PkgResourceTemplateLookup(**kw) - - def get_fixturedir(self): - import os - import pyramid.tests - return os.path.join(os.path.dirname(pyramid.tests.__file__), 'fixtures') - - def test_adjust_uri_not_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('a', None) - self.assertEqual(result, '/a') - - def test_adjust_uri_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('a:b', None) - self.assertEqual(result, 'a:b') - - def test_adjust_uri_asset_spec_with_modified_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('a$b', None) - self.assertEqual(result, 'a:b') - - def test_adjust_uri_not_asset_spec_with_relativeto_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('c', 'a:b') - self.assertEqual(result, 'a:c') - - def test_adjust_uri_not_asset_spec_with_relativeto_modified_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('c', 'a$b') - self.assertEqual(result, 'a:c') - - def test_adjust_uri_not_asset_spec_with_relativeto_not_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('b', '../a') - self.assertEqual(result, '../b') - - def test_adjust_uri_not_asset_spec_abs_with_relativeto_asset_spec(self): - inst = self._makeOne() - result = inst.adjust_uri('/c', 'a:b') - self.assertEqual(result, '/c') - - def test_adjust_uri_asset_spec_with_relativeto_not_asset_spec_abs(self): - inst = self._makeOne() - result = inst.adjust_uri('a:b', '/c') - self.assertEqual(result, 'a:b') - - def test_get_template_not_asset_spec(self): - fixturedir = self.get_fixturedir() - inst = self._makeOne(directories=[fixturedir]) - result = inst.get_template('helloworld.mak') - self.assertFalse(result is None) - - def test_get_template_asset_spec_with_filesystem_checks(self): - inst = self._makeOne(filesystem_checks=True) - result = inst.get_template('pyramid.tests:fixtures/helloworld.mak') - self.assertFalse(result is None) - - def test_get_template_asset_spec_with_module_dir(self): - tmpdir = tempfile.mkdtemp() - try: - inst = self._makeOne(module_directory=tmpdir) - result = inst.get_template('pyramid.tests:fixtures/helloworld.mak') - self.assertFalse(result is None) - finally: - shutil.rmtree(tmpdir, ignore_errors=True) - - def test_get_template_asset_spec_missing(self): - from mako.exceptions import TopLevelLookupException - fixturedir = self.get_fixturedir() - inst = self._makeOne(filesystem_checks=True, directories=[fixturedir]) - self.assertRaises(TopLevelLookupException, inst.get_template, - 'pyramid.tests:fixtures/notthere.mak') - -class TestMakoRenderingException(unittest.TestCase): - def _makeOne(self, text): - from pyramid.mako_templating import MakoRenderingException - return MakoRenderingException(text) - - def test_repr_and_str(self): - exc = self._makeOne('text') - self.assertEqual(str(exc), 'text') - self.assertEqual(repr(exc), 'text') - -class DummyLookup(object): - def __init__(self, exc=None): - self.exc = exc - - def get_template(self, path): - self.path = path - return self - - def get_def(self, path): - self.deffed = path - return self - - def render_unicode(self, **values): - if self.exc: - raise self.exc - self.values = values - return text_('result') - -class DummyRendererInfo(object): - def __init__(self, kw): - self.__dict__.update(kw) - - -class DummyWarnings(object): - def __init__(self): - self.msgs = [] - def warn(self, msg, typ, level): - self.msgs.append(msg) -- cgit v1.2.3 From 5f2e977ac0052c65c5bc60a9492569e48012b449 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 17:50:31 -0600 Subject: Require the pyramid_mako package This is mainly for backwards compatibility. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 523dab191..f3819dce9 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,7 @@ install_requires=[ 'venusian >= 1.0a3', # ``ignore`` 'translationstring >= 0.4', # py3 compat 'PasteDeploy >= 1.5.0', # py3 compat + 'pyramid_mako', # Backwards compat ... ] tests_require = [ -- cgit v1.2.3 From 90fd4bc7063b6791f2e86be30c10039a011ea2ed Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 17:50:56 -0600 Subject: Import mako from the proper location... --- pyramid/config/rendering.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index 356bf033e..6a456fd61 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -14,7 +14,7 @@ from pyramid import ( chameleon_zpt, ) -from pyramid.mako_templating import renderer_factory as mako_renderer_factory +from pyramid_mako import renderer_factory as mako_renderer_factory DEFAULT_RENDERERS = ( ('.txt', chameleon_text.renderer_factory), -- cgit v1.2.3 From 59801aaeaf431e1b66dee51e3774a5254c84b11c Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 18:02:19 -0600 Subject: Remove last references to mako We remove the default addition of .mak/.mako files in the configuration object, and we remove the test to see if it is has been defined as a renderer. --- pyramid/config/rendering.py | 4 ---- pyramid/tests/test_config/test_init.py | 2 -- setup.py | 1 - 3 files changed, 7 deletions(-) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index 6a456fd61..a46d1f37f 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -14,13 +14,9 @@ from pyramid import ( chameleon_zpt, ) -from pyramid_mako import renderer_factory as mako_renderer_factory - DEFAULT_RENDERERS = ( ('.txt', chameleon_text.renderer_factory), ('.pt', chameleon_zpt.renderer_factory), - ('.mak', mako_renderer_factory), - ('.mako', mako_renderer_factory), ('json', renderers.json_renderer_factory), ('string', renderers.string_renderer_factory), ) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index b8cbbd676..531357e7f 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -72,8 +72,6 @@ class ConfiguratorTests(unittest.TestCase): if not PYPY: self.assertTrue(config.registry.getUtility(IRendererFactory, '.pt')) self.assertTrue(config.registry.getUtility(IRendererFactory,'.txt')) - self.assertTrue(config.registry.getUtility(IRendererFactory, '.mak')) - self.assertTrue(config.registry.getUtility(IRendererFactory, '.mako')) def test_begin(self): from pyramid.config import Configurator diff --git a/setup.py b/setup.py index f3819dce9..523dab191 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,6 @@ install_requires=[ 'venusian >= 1.0a3', # ``ignore`` 'translationstring >= 0.4', # py3 compat 'PasteDeploy >= 1.5.0', # py3 compat - 'pyramid_mako', # Backwards compat ... ] tests_require = [ -- cgit v1.2.3 From f907b59336ffe13d5c7d7898a14f679a6de8779d Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:01:49 -0600 Subject: Remove chameleon as a dependency in setup.py --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 523dab191..544a273e5 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,6 @@ except IOError: install_requires=[ 'setuptools', - 'Chameleon >= 1.2.3', 'WebOb >= 1.2b3', # request.path_info is unicode 'repoze.lru >= 0.4', # py3 compat 'zope.interface >= 3.8.0', # has zope.interface.registry -- cgit v1.2.3 From 749babb5c100d7bd59c7471ebea576d9e66c7dc1 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:12:50 -0600 Subject: Remove the Chameleon renderer from renderers.py --- pyramid/renderers.py | 124 --------------------------------------------------- 1 file changed, 124 deletions(-) diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 602655be8..ae9bc5b7e 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -11,8 +11,6 @@ from zope.interface import ( from zope.interface.registry import Components from pyramid.interfaces import ( - IChameleonLookup, - IChameleonTranslate, IJSONAdapter, IRendererGlobalsFactory, IRendererFactory, @@ -360,128 +358,6 @@ class JSONP(JSON): return body return _render -# utility functions, not API - -@implementer(IChameleonLookup) -class ChameleonRendererLookup(object): - spec_re = re.compile( - r'(?P[\w_.:/-]+)' - r'(?:\#(?P[\w_]+))?' - r'(\.(?P.*))' - ) - - def __init__(self, impl, registry): - self.impl = impl - self.registry = registry - self.lock = threading.Lock() - - def get_spec(self, name, package): - if not package: - # if there's no package, we can't do any conversion - return name - - spec = name - isabspath = os.path.isabs(name) - colon_in_name = ':' in name - isabsspec = colon_in_name and (not isabspath) - isrelspec = (not isabsspec) and (not isabspath) - - # if it's already an absolute spec, we don't need to do anything, - # but if it's a relative spec or an absolute path, we need to try - # to convert it to an absolute spec - - if isrelspec: - # convert relative asset spec to absolute asset spec - pp = package_path(package) - spec = os.path.join(pp, spec) - spec = asset_spec_from_abspath(spec, package) - - elif isabspath: - # convert absolute path to absolute asset spec - spec = asset_spec_from_abspath(spec, package) - - return spec - - @property # wait until completely necessary to look up translator - def translate(self): - return self.registry.queryUtility(IChameleonTranslate) - - @property # wait until completely necessary to look up debug_templates - def debug(self): - settings = self.registry.settings - if settings is None: - return False - return settings.get('debug_templates', False) - - @property # wait until completely necessary to look up reload_templates - def auto_reload(self): - settings = self.registry.settings - if settings is None: - return False - return settings.get('reload_templates', False) - - def _crack_spec(self, spec): - asset, macro, ext = self.spec_re.match(spec).group( - 'asset', 'defname', 'ext' - ) - return asset, macro, ext - - def __call__(self, info): - spec = self.get_spec(info.name, info.package) - registry = info.registry - - if os.path.isabs(spec): - # 'spec' is an absolute filename - if not os.path.exists(spec): - raise ValueError('Missing template file: %s' % spec) - renderer = registry.queryUtility(ITemplateRenderer, name=spec) - if renderer is None: - renderer = self.impl(spec, self, macro=None) - # cache the template - with self.lock: - registry.registerUtility(renderer, - ITemplateRenderer, name=spec) - else: - # spec is a package:relpath asset spec - renderer = registry.queryUtility(ITemplateRenderer, name=spec) - if renderer is None: - asset, macro, ext = self._crack_spec(spec) - spec_without_macro = '%s.%s' % (asset, ext) - try: - package_name, filename = spec_without_macro.split(':', 1) - except ValueError: # pragma: no cover - # somehow we were passed a relative pathname; this - # should die - package_name = caller_package(4).__name__ - filename = spec_without_macro - abspath = pkg_resources.resource_filename(package_name, - filename) - if not pkg_resources.resource_exists(package_name, filename): - raise ValueError( - 'Missing template asset: %s (%s)' % ( - spec_without_macro, abspath) - ) - renderer = self.impl(abspath, self, macro=macro) - settings = info.settings - if not settings.get('reload_assets'): - # cache the template - with self.lock: - registry.registerUtility(renderer, ITemplateRenderer, - name=spec) - - return renderer - -registry_lock = threading.Lock() - -def template_renderer_factory(info, impl, lock=registry_lock): - registry = info.registry - lookup = registry.queryUtility(IChameleonLookup, name=info.type) - if lookup is None: - lookup = ChameleonRendererLookup(impl, registry) - with lock: - registry.registerUtility(lookup, IChameleonLookup, name=info.type) - return lookup(info) - @implementer(IRendererInfo) class RendererHelper(object): def __init__(self, name=None, package=None, registry=None): -- cgit v1.2.3 From 82f9702c9cd8bb16b15d658e6d64c9c31b9fdc57 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 22:34:37 -0500 Subject: update changelog --- CHANGES.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index cdaad5a90..dbf27900f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,25 @@ +Next Release +============ + +Major Backward Incompatibilities +-------------------------------- + +- Pyramid has dropped native support for the Mako and Chameleon renderers. To + re-add support for these renderers into existing projects there are 3 steps: + + - Add `pyramid_mako` and/or `pyramid_chameleon` as dependencies by + adding them to the `install_requires` section of the package's `setup.py`. + + - Update instances of the `Configurator` to include the required addons: + + config.include('pyramid_chameleon') + config.include('pyramid_mako') + + - If any unit tests are invoking either `pyramid.renderers.render()` or + `pyramid.renderers.render_to_response()`, then the `Configurator` instance + at the root of the unit test should be also be updated to include the + addons, as shown above. + 1.5a1 (2013-08-30) ================== -- cgit v1.2.3 From 4315c0d5cf3224b8622c9b00cb6c72c86f1a9518 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 22:38:03 -0500 Subject: fix markup --- CHANGES.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index dbf27900f..5768ae2ea 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,15 +10,16 @@ Major Backward Incompatibilities - Add `pyramid_mako` and/or `pyramid_chameleon` as dependencies by adding them to the `install_requires` section of the package's `setup.py`. - - Update instances of the `Configurator` to include the required addons: + - Update instances of the ``pyramid.config.Configurator`` to include the + required addons: config.include('pyramid_chameleon') config.include('pyramid_mako') - - If any unit tests are invoking either `pyramid.renderers.render()` or - `pyramid.renderers.render_to_response()`, then the `Configurator` instance - at the root of the unit test should be also be updated to include the - addons, as shown above. + - If any unit tests are invoking either ``pyramid.renderers.render()`` or + ``pyramid.renderers.render_to_response()``, 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. 1.5a1 (2013-08-30) ================== -- cgit v1.2.3 From 9ed074e28c256842b902dc7ded8edb1f696e225b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 22:41:46 -0500 Subject: add example of rendering to the changelog --- CHANGES.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5768ae2ea..46e6f7c8b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -17,9 +17,15 @@ Major Backward Incompatibilities config.include('pyramid_mako') - If any unit tests are invoking either ``pyramid.renderers.render()`` or - ``pyramid.renderers.render_to_response()``, 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. + ``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: + + config = pyramid.testing.setUp() + config.include('pyramid_mako') + + result = pyramid.renderers.render('mypkg:templates/home.mako', {}) 1.5a1 (2013-08-30) ================== -- cgit v1.2.3 From ce138c89d9f9aff3f7d949b7f1b909c273e7f0ac Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 22:47:37 -0500 Subject: add install_requires example as well --- CHANGES.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 46e6f7c8b..d8d606530 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -8,10 +8,20 @@ Major Backward Incompatibilities re-add support for these renderers into existing projects there are 3 steps: - Add `pyramid_mako` and/or `pyramid_chameleon` as dependencies by - adding them to the `install_requires` section of the package's `setup.py`. + adding them to the `install_requires` section of the package's `setup.py`:: + + setup( + #... + install_requires=[ + 'pyramid_mako', # new dependency + 'pyramid_chameleon', # new dependency + 'pyramid', + #... + ], + ) - Update instances of the ``pyramid.config.Configurator`` to include the - required addons: + required addons:: config.include('pyramid_chameleon') config.include('pyramid_mako') @@ -20,7 +30,7 @@ Major Backward Incompatibilities ``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: + above. For example:: config = pyramid.testing.setUp() config.include('pyramid_mako') -- cgit v1.2.3 From 3525aaf78c4e6bf5b96d87cbcae28d5f9a6d504f Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:15:10 -0600 Subject: Remove chameleon files --- pyramid/chameleon_text.py | 37 ----------------------------------- pyramid/chameleon_zpt.py | 49 ----------------------------------------------- 2 files changed, 86 deletions(-) delete mode 100644 pyramid/chameleon_text.py delete mode 100644 pyramid/chameleon_zpt.py diff --git a/pyramid/chameleon_text.py b/pyramid/chameleon_text.py deleted file mode 100644 index d2a943a28..000000000 --- a/pyramid/chameleon_text.py +++ /dev/null @@ -1,37 +0,0 @@ -from zope.interface import implementer - -from pyramid.interfaces import ITemplateRenderer - -from pyramid.decorator import reify -from pyramid import renderers - -def renderer_factory(info): - return renderers.template_renderer_factory(info, TextTemplateRenderer) - -@implementer(ITemplateRenderer) -class TextTemplateRenderer(object): - def __init__(self, path, lookup, macro=None): - self.path = path - self.lookup = lookup - # text template renderers have no macros, so we ignore the - # macro arg - - @reify # avoid looking up reload_templates before manager pushed - def template(self): - from chameleon.zpt.template import PageTextTemplateFile - return PageTextTemplateFile(self.path, - auto_reload=self.lookup.auto_reload, - debug=self.lookup.debug, - translate=self.lookup.translate) - - def implementation(self): - return self.template - - def __call__(self, value, system): - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - result = self.template(**system) - return result - diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py deleted file mode 100644 index 4ea5d506d..000000000 --- a/pyramid/chameleon_zpt.py +++ /dev/null @@ -1,49 +0,0 @@ -from zope.interface import implementer - -from pyramid.interfaces import ITemplateRenderer -from pyramid.decorator import reify -from pyramid import renderers - -from chameleon.zpt.template import PageTemplateFile - -def renderer_factory(info): - return renderers.template_renderer_factory(info, ZPTTemplateRenderer) - -class PyramidPageTemplateFile(PageTemplateFile): - def cook(self, body): - PageTemplateFile.cook(self, body) - if self.macro: - # render only the portion of the template included in a - # define-macro named the value of self.macro - macro_renderer = self.macros[self.macro].include - self._render = macro_renderer - -@implementer(ITemplateRenderer) -class ZPTTemplateRenderer(object): - def __init__(self, path, lookup, macro=None): - self.path = path - self.lookup = lookup - self.macro = macro - - @reify # avoid looking up reload_templates before manager pushed - def template(self): - tf = PyramidPageTemplateFile( - self.path, - auto_reload=self.lookup.auto_reload, - debug=self.lookup.debug, - translate=self.lookup.translate, - macro=self.macro, - ) - return tf - - def implementation(self): - return self.template - - def __call__(self, value, system): - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - result = self.template(**system) - return result - -- cgit v1.2.3 From 953b6359cb363d31cc7575c19a44711aa11c5cc3 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:15:26 -0600 Subject: Remove Chameleon specific interfaces --- pyramid/interfaces.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 3f43494a8..1d5688195 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -853,19 +853,6 @@ class IPackageOverrides(IPEP302Loader): # traversalwrapper) VH_ROOT_KEY = 'HTTP_X_VHM_ROOT' -class IChameleonLookup(Interface): - translate = Attribute('IChameleonTranslate object') - debug = Attribute('The ``debug_templates`` setting for this application') - auto_reload = Attribute('The ``reload_templates`` setting for this app') - def __call__(self, info): - """ Return an ITemplateRenderer based on IRendererInfo ``info`` """ - -class IChameleonTranslate(Interface): - """ Internal interface representing a chameleon translate function """ - def __call__(msgid, domain=None, mapping=None, context=None, - target_language=None, default=None): - """ Translate a mess of arguments to a Unicode object """ - class ILocalizer(Interface): """ Localizer for a specific language """ -- cgit v1.2.3 From b4755a79f7318a9100714c1fdabbc2cc57c016b4 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:16:07 -0600 Subject: Remove chameleon from default renderers list --- pyramid/config/rendering.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index a46d1f37f..a14853fdc 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -10,13 +10,9 @@ from pyramid.util import action_method from pyramid import ( renderers, - chameleon_text, - chameleon_zpt, ) DEFAULT_RENDERERS = ( - ('.txt', chameleon_text.renderer_factory), - ('.pt', chameleon_zpt.renderer_factory), ('json', renderers.json_renderer_factory), ('string', renderers.string_renderer_factory), ) -- cgit v1.2.3 From 1eb618a1cefbb95a5bf656b721ac82e50eb3beae Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:31:04 -0600 Subject: Remove traces of Chameleon from tests/fixers --- pyramid/fixers/fix_bfg_imports.py | 220 ----------------------------------- pyramid/tests/test_chameleon_text.py | 145 ----------------------- pyramid/tests/test_chameleon_zpt.py | 175 ---------------------------- 3 files changed, 540 deletions(-) delete mode 100644 pyramid/fixers/fix_bfg_imports.py delete mode 100644 pyramid/tests/test_chameleon_text.py delete mode 100644 pyramid/tests/test_chameleon_zpt.py diff --git a/pyramid/fixers/fix_bfg_imports.py b/pyramid/fixers/fix_bfg_imports.py deleted file mode 100644 index 0046aad30..000000000 --- a/pyramid/fixers/fix_bfg_imports.py +++ /dev/null @@ -1,220 +0,0 @@ -import os -import re -import sys - -from lib2to3.refactor import get_fixers_from_package -from lib2to3.refactor import RefactoringTool -from lib2to3.fixer_util import Name -from lib2to3.fixer_util import attr_chain -from lib2to3 import fixer_base - -MAPPING = {'repoze.bfg':'pyramid'} - -MODULE_NAMES = ( - 'compat', - 'configuration', - 'authentication', - 'authorization', - 'chameleon_text', - 'chameleon_zpt', - 'decorator', - 'encode', - 'events', - 'exceptions', - 'i18n', - 'includes', - 'interfaces', - 'location', - 'log', - 'paster', - 'path', - 'registry', - 'renderers', - 'request', - 'resource', - 'router', - 'scripting', - 'security', - 'settings', - 'static', - 'testing', - 'tests', - 'tests.test_configuration', - 'tests.ccbugapp', - 'tests.exceptionviewapp', - 'tests.exceptionviewapp.models', - 'tests.fixtureapp', - 'tests.fixtureapp.models', - 'tests.grokkedapp', - 'tests.hybridapp', - 'tests.localeapp', - 'tests.restbugapp', - 'tests.routesapp', - 'threadlocal', - 'traversal', - 'urldispatch', - 'url', - 'view', - 'wsgi', - 'zcml', - ) - -for name in MODULE_NAMES: - frm = 'repoze.bfg.' + name - to = 'pyramid.' + name - MAPPING[frm] = to - -def alternates(members): - return "(" + "|".join(map(str, members)) + ")" - -def build_pattern(mapping=MAPPING): - mod_list = [] - - for key in mapping: - splitted = key.split('.') - joined = " '.' ".join(["'%s'" %s for s in splitted]) - mod_list.append(joined) - - mod_list = ' | '.join( - ['module_name=dotted_name< %s >' %s for s in mod_list]) - - yield """name_import=import_name< 'import' ((%s) | - multiple_imports=dotted_as_names< any* (%s) any* >) > - """ % (mod_list, mod_list) - yield """import_from< 'from' (%s) 'import' ['('] - ( any | import_as_name< any 'as' any > | - import_as_names< any* >) [')'] > - """ % mod_list - yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | - multiple_imports=dotted_as_names< - any* dotted_as_name< (%s) 'as' any > any* >) > - """ % (mod_list, mod_list) - - # Find usages of module members in code e.g. ``repoze.bfg`` or - # ``repoze.bfg.configuration`` - # 'repoze' trailer< '.' 'bfg' > trailer< '.' 'configuration' > - bare_names = [] - for key in mapping: - splitted = key.split('.') - tmp = ["'%s'" % splitted[0]] - for thing in splitted[1:]: - tmp.append(" trailer< '.' '%s' > " % thing) - bare_name = ''.join(tmp) - bare_names.append(bare_name) - - names = alternates(bare_names) - yield "power< bare_with_attr=%s >" % names - -class FixBfgImports(fixer_base.BaseFix): - - mapping = MAPPING - run_order = 8 - - def build_pattern(self): - pattern = "|".join(build_pattern(self.mapping)) - return pattern - - def compile_pattern(self): - # We override this, so MAPPING can be pragmatically altered and the - # changes will be reflected in PATTERN. - self.PATTERN = self.build_pattern() - super(FixBfgImports, self).compile_pattern() - - # Don't match the node if it's within another match. - def match(self, node): - match = super(FixBfgImports, self).match - results = match(node) - if results: - # Module usage could be in the trailer of an attribute lookup, so we - # might have nested matches when "bare_with_attr" is present. - if "bare_with_attr" not in results and \ - any(match(obj) for obj in attr_chain(node, "parent")): - return False - return results - return False - - def start_tree(self, tree, filename): - super(FixBfgImports, self).start_tree(tree, filename) - self.replace = {} - - def transform(self, node, results): - # Mostly copied from fix_imports.py - import_mod = results.get("module_name") - if import_mod: - try: - mod_name = import_mod.value - except AttributeError: - # XXX: A hack to remove whitespace prefixes and suffixes - mod_name = str(import_mod).strip() - new_name = self.mapping[mod_name] - import_mod.replace(Name(new_name, prefix=import_mod.prefix)) - if "name_import" in results: - # If it's not a "from x import x, y" or "import x as y" import, - # marked its usage to be replaced. - self.replace[mod_name] = new_name - if "multiple_imports" in results: - # This is a nasty hack to fix multiple imports on a line (e.g., - # "import StringIO, urlparse"). The problem is that I can't - # figure out an easy way to make a pattern recognize the keys of - # MAPPING randomly sprinkled in an import statement. - results = self.match(node) - if results: - self.transform(node, results) - else: - # Replace usage of the module. - bare_name_text = ''.join(map(str,results['bare_with_attr'])).strip() - new_name = self.replace.get(bare_name_text) - bare_name = results["bare_with_attr"][0] - - if new_name: - node.replace(Name(new_name, prefix=bare_name.prefix)) - -MODULE_ALTERNATIVES = [] -for name in MODULE_NAMES: - MODULE_ALTERNATIVES.append(r'\.' + re.escape(name)+r'[\w\.]*?') - -MODULE_ALTERNATIVES = '|'.join(MODULE_ALTERNATIVES) - -BFG_NS_RE = r'xmlns\s*?=\s*?[\'\"]http://namespaces\.repoze\.org/bfg[\'\"]' -BFG_IN_ATTR = r'(repoze\.bfg)(%s)' % MODULE_ALTERNATIVES -BFG_INCLUDE_IN_ATTR = r'repoze\.bfg\.includes' -ATTR = re.compile(BFG_IN_ATTR, re.MULTILINE) -INCLUDE_ATTR = re.compile(BFG_INCLUDE_IN_ATTR, re.MULTILINE) -NS = re.compile(BFG_NS_RE, re.MULTILINE) - -def replace(match): - return 'pyramid%s' % match.group(2) - -def fix_zcml(path): - for root, dirs, files in os.walk(path): - for file in files: - if file.endswith('.zcml'): - absfile = os.path.join(root, file) - f = open(absfile, 'rb') - text = f.read() - f.close() - newt = NS.sub('xmlns="http://pylonshq.com/pyramid"', text) - newt = INCLUDE_ATTR.sub('pyramid_zcml', newt) - newt = ATTR.sub(replace, newt) - if text != newt: - newf = open(absfile, 'wb') - newf.write(newt) - newf.flush() - newf.close() - - for dir in dirs: - if dir.startswith('.'): - dirs.remove(dir) - -def main(argv=None): - if argv is None: - argv = sys.argv - path = argv[1] - fixer_names = get_fixers_from_package('pyramid.fixers') - tool = RefactoringTool(fixer_names) - tool.refactor([path], write=True) - fix_zcml(path) - -if __name__ == '__main__': - main() - diff --git a/pyramid/tests/test_chameleon_text.py b/pyramid/tests/test_chameleon_text.py deleted file mode 100644 index d9f20f241..000000000 --- a/pyramid/tests/test_chameleon_text.py +++ /dev/null @@ -1,145 +0,0 @@ -import sys -import unittest - -from pyramid.compat import binary_type -from pyramid import testing - -class Base(object): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', name) - -class Test_renderer_factory(Base, unittest.TestCase): - def _callFUT(self, info): - from pyramid.chameleon_text import renderer_factory - return renderer_factory(info) - - def test_it(self): - # this test is way too functional - from pyramid.chameleon_text import TextTemplateRenderer - info = DummyInfo() - result = self._callFUT(info) - self.assertEqual(result.__class__, TextTemplateRenderer) - -class TextTemplateRendererTests(Base, unittest.TestCase): - def _getTargetClass(self): - from pyramid.chameleon_text import TextTemplateRenderer - return TextTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITemplateRenderer - path = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - verifyObject(ITemplateRenderer, self._makeOne(path, lookup)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_template_reified(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template, instance.__dict__['template']) - - def test_template_with_ichameleon_translate(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.translate, lookup.translate) - - def test_template_with_debug_templates(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - lookup.debug = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, True) - - def test_template_with_reload_templates(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - lookup.auto_reload = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, True) - - def test_template_without_reload_templates(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - lookup.auto_reload = False - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, False) - - def test_call(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance({}, {}) - self.assertTrue(isinstance(result, binary_type)) - self.assertEqual(result, b'Hello.\n') - - def test_call_with_nondict_value(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertRaises(ValueError, instance, None, {}) - - def test_call_nonminimal(self): - nonminimal = self._getTemplatePath('nonminimal.txt') - lookup = DummyLookup() - instance = self._makeOne(nonminimal, lookup) - result = instance({'name':'Chris'}, {}) - self.assertTrue(isinstance(result, binary_type)) - self.assertEqual(result, b'Hello, Chris!\n') - - def test_implementation(self): - minimal = self._getTemplatePath('minimal.txt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance.implementation()() - self.assertTrue(isinstance(result, binary_type)) - self.assertEqual(result, b'Hello.\n') - -class DummyLookup(object): - auto_reload=True - debug = True - def translate(self, msg): pass - -class DummyRegistry(object): - def queryUtility(self, iface, name): - self.queried = iface, name - return None - - def registerUtility(self, impl, iface, name): - self.registered = impl, iface, name - -class DummyInfo(object): - def __init__(self): - self.registry = DummyRegistry() - self.type = '.pt' - self.name = 'fixtures/minimal.pt' - self.package = sys.modules[__name__] - self.settings = {} - diff --git a/pyramid/tests/test_chameleon_zpt.py b/pyramid/tests/test_chameleon_zpt.py deleted file mode 100644 index d7ca94298..000000000 --- a/pyramid/tests/test_chameleon_zpt.py +++ /dev/null @@ -1,175 +0,0 @@ -import sys -import unittest - -from pyramid import testing -from pyramid.compat import text_type - -class Base(object): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', name) - -class Test_renderer_factory(Base, unittest.TestCase): - def _callFUT(self, info): - from pyramid.chameleon_zpt import renderer_factory - return renderer_factory(info) - - def test_it(self): - # this test is way too functional - from pyramid.chameleon_zpt import ZPTTemplateRenderer - info = DummyInfo() - result = self._callFUT(info) - self.assertEqual(result.__class__, ZPTTemplateRenderer) - -class ZPTTemplateRendererTests(Base, unittest.TestCase): - def _getTargetClass(self): - from pyramid.chameleon_zpt import ZPTTemplateRenderer - return ZPTTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITemplateRenderer - path = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - verifyObject(ITemplateRenderer, self._makeOne(path, lookup)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_call(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance({}, {}) - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result.rstrip('\n'), - '
\n
') - - def test_template_reified(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template, instance.__dict__['template']) - - def test_template_with_ichameleon_translate(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.translate, lookup.translate) - - def test_template_with_debug_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.debug = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, True) - - def test_template_without_debug_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.debug = False - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, False) - - def test_template_with_reload_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.auto_reload = True - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, True) - - def test_template_without_reload_templates(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - lookup.auto_reload = False - instance = self._makeOne(minimal, lookup) - self.assertFalse('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, False) - - def test_call_with_nondict_value(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - self.assertRaises(ValueError, instance, None, {}) - - def test_implementation(self): - minimal = self._getTemplatePath('minimal.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance.implementation()() - self.assertTrue(isinstance(result, text_type)) - self.assertEqual(result.rstrip('\n'), - '
\n
') - - def test_macro_supplied(self): - minimal = self._getTemplatePath('withmacro.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup, macro='foo') - result = instance.implementation()() - self.assertEqual(result, '\n Hello!\n') - - def test_macro_notsupplied(self): - minimal = self._getTemplatePath('withmacro.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup) - result = instance.implementation()() - self.assertEqual(result, - '\nOutside macro\n\n Hello!\n\n\n\n') - - def test_macro_template_reload(self): - minimal = self._getTemplatePath('withmacro.pt') - lookup = DummyLookup() - instance = self._makeOne(minimal, lookup, macro='foo') - result = instance.implementation()() - self.assertEqual(result, '\n Hello!\n') - instance.template.cook( - '\nOutside macro\n\n Hello!\n\n\n\n' - ) - result = instance.implementation()() - self.assertEqual(result, '\n Hello!\n') - -class DummyLookup(object): - auto_reload=True - debug = True - def translate(self, msg): pass - -class DummyRegistry(object): - def queryUtility(self, iface, name): - self.queried = iface, name - return None - - def registerUtility(self, impl, iface, name): - self.registered = impl, iface, name - -class DummyInfo(object): - def __init__(self): - self.registry = DummyRegistry() - self.type = '.pt' - self.name = 'fixtures/minimal.pt' - self.package = sys.modules[__name__] - self.settings = {} - -- cgit v1.2.3 From ccd4d40ed6ab6ce02f99bcd6de2e7f96f732ff99 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:31:39 -0600 Subject: Remove bfg fixers script from entry points --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 544a273e5..36f0b1303 100644 --- a/setup.py +++ b/setup.py @@ -109,7 +109,6 @@ setup(name='pyramid', zodb=pyramid.scaffolds:ZODBProjectTemplate alchemy=pyramid.scaffolds:AlchemyProjectTemplate [console_scripts] - bfg2pyramid = pyramid.fixers.fix_bfg_imports:main pcreate = pyramid.scripts.pcreate:main pserve = pyramid.scripts.pserve:main pshell = pyramid.scripts.pshell:main -- cgit v1.2.3 From 6ca99b5b42ca13a25a22474c927733d2d16d7cbe Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 23:32:43 -0500 Subject: remove some mako/chameleon renderer docs --- docs/narr/renderers.rst | 179 ++++++------------------------------------------ 1 file changed, 21 insertions(+), 158 deletions(-) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index a2811dbae..212832474 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -365,136 +365,6 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. -.. index:: - pair: renderer; chameleon - -.. _chameleon_template_renderers: - -``*.pt`` or ``*.txt``: Chameleon Template Renderers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Two built-in renderers exist for :term:`Chameleon` templates. - -If the ``renderer`` attribute of a view configuration is an absolute path, a -relative path or :term:`asset specification` which has a final path element -with a filename extension of ``.pt``, the Chameleon ZPT renderer is used. -See :ref:`chameleon_zpt_templates` for more information about ZPT templates. - -If the ``renderer`` attribute of a view configuration is an absolute path or -a :term:`asset specification` which has a final path element with a filename -extension of ``.txt``, the :term:`Chameleon` text renderer is used. See -:ref:`chameleon_text_templates` for more information about Chameleon text -templates. - -The behavior of these renderers is the same, except for the engine -used to render the template. - -When a ``renderer`` attribute that names a template path or :term:`asset -specification` (e.g. ``myproject:templates/foo.pt`` or -``myproject:templates/foo.txt``) is used, the view must return a -:term:`Response` object or a Python *dictionary*. If the view callable with -an associated template returns a Python dictionary, the named template will -be passed the dictionary as its keyword arguments, and the template renderer -implementation will return the resulting rendered template in a response to -the user. If the view callable returns anything but a Response object or a -dictionary, an error will be raised. - -Before passing keywords to the template, the keyword arguments derived from -the dictionary returned by the view are augmented. The callable object -- -whatever object was used to define the view -- will be automatically inserted -into the set of keyword arguments passed to the template as the ``view`` -keyword. If the view callable was a class, the ``view`` keyword will be an -instance of that class. Also inserted into the keywords passed to the -template are ``renderer_name`` (the string used in the ``renderer`` attribute -of the directive), ``renderer_info`` (an object containing renderer-related -information), ``context`` (the context resource of the view used to render -the template), and ``request`` (the request passed to the view used to render -the template). ``request`` is also available as ``req`` in Pyramid 1.3+. - -Here's an example view configuration which uses a Chameleon ZPT renderer: - -.. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='myproject:templates/foo.pt') - -Here's an example view configuration which uses a Chameleon text renderer: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='myproject:templates/foo.txt') - -Views which use a Chameleon renderer can vary response attributes by using -the API of the ``request.response`` attribute. See -:ref:`request_response_attr`. - -.. index:: - pair: renderer; mako - -.. _mako_template_renderers: - -``*.mak`` or ``*.mako``: Mako Template Renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``Mako`` template renderer renders views using a Mako template. When -used, the view must return a Response object or a Python *dictionary*. The -dictionary items will then be used in the global template space. If the view -callable returns anything but a Response object or a dictionary, an error -will be raised. - -When using a ``renderer`` argument to a :term:`view configuration` to specify -a Mako template, the value of the ``renderer`` may be a path relative to the -``mako.directories`` setting (e.g. ``some/template.mak``) or, alternately, -it may be a :term:`asset specification` -(e.g. ``apackage:templates/sometemplate.mak``). Mako templates may -internally inherit other Mako templates using a relative filename or a -:term:`asset specification` as desired. - -Here's an example view configuration which uses a relative path: - -.. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='foo.mak') - -It's important to note that in Mako's case, the 'relative' path name -``foo.mak`` above is not relative to the package, but is relative to the -directory (or directories) configured for Mako via the ``mako.directories`` -configuration file setting. - -The renderer can also be provided in :term:`asset specification` -format. Here's an example view configuration which uses one: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='mypackage:templates/foo.mak') - -The above configuration will use the file named ``foo.mak`` in the -``templates`` directory of the ``mypackage`` package. - -The ``Mako`` template renderer can take additional arguments beyond the -standard ``pyramid.reload_templates`` setting, see the -:ref:`environment_chapter` for additional -:ref:`mako_template_renderer_settings`. - .. index:: single: response headers (from a renderer) single: renderer response headers @@ -739,44 +609,37 @@ ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed to the ``MyJinja2Renderer`` constructor will be the full value that was set as ``renderer=`` in the view configuration. -.. index:: - pair: renderer; changing +Adding a Default Renderer +~~~~~~~~~~~~~~~~~~~~~~~~~ -Changing an Existing Renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can associate more than one filename extension with the same existing -renderer implementation as necessary if you need to use a different file -extension for the same kinds of templates. For example, to associate the -``.zpt`` extension with the Chameleon ZPT renderer factory, use the -:meth:`pyramid.config.Configurator.add_renderer` method: +To associate a *default* renderer with *all* view configurations (even +ones which do not possess a ``renderer`` attribute), pass ``None`` as +the ``name`` attribute to the renderer tag: .. code-block:: python - config.add_renderer('.zpt', 'pyramid.chameleon_zpt.renderer_factory') - -After you do this, :app:`Pyramid` will treat templates ending in both the -``.pt`` and ``.zpt`` filename extensions as Chameleon ZPT templates. - -To change the default mapping in which files with a ``.pt`` extension are -rendered via a Chameleon ZPT page template renderer, use a variation on the -following in your application's startup code: - -.. code-block:: python + config.add_renderer(None, 'mypackage.json_renderer_factory') - config.add_renderer('.pt', 'mypackage.pt_renderer') +.. index:: + pair: renderer; changing -After you do this, the :term:`renderer factory` in -``mypackage.pt_renderer`` will be used to render templates which end -in ``.pt``, replacing the default Chameleon ZPT renderer. +Changing an Existing Renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To associate a *default* renderer with *all* view configurations (even -ones which do not possess a ``renderer`` attribute), pass ``None`` as -the ``name`` attribute to the renderer tag: +Pyramid supports overriding almost every aspect of its setup through its +:ref:`Conflict Resolution ` mechanism. This +means that in most cases overriding a renderer is as simple as using the +:meth:`pyramid.config.Configurator.add_renderer` method to re-define the +template extension. For example, if we'd like to override the ``json`` +extension to specify a new renderer we could do the following: .. code-block:: python - config.add_renderer(None, 'mypackage.json_renderer_factory') + json_renderer = pyramid.renderers.JSON() + config.add_renderer('json', json_renderer) + +After you do this, any views registered with the ``json`` renderer will use +the new renderer. .. index:: pair: renderer; overriding at runtime -- cgit v1.2.3 From 5cbaf17adf8207349b139e2b57811a3e5da0837f Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:33:48 -0600 Subject: Remove fixes sub-package --- pyramid/fixers/__init__.py | 1 - 1 file changed, 1 deletion(-) delete mode 100644 pyramid/fixers/__init__.py diff --git a/pyramid/fixers/__init__.py b/pyramid/fixers/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/pyramid/fixers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package -- cgit v1.2.3 From b56a6ee9c0c58992df67cdeb021f69d51bcfd26d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 23:36:01 -0500 Subject: change focus from we to you --- docs/narr/renderers.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 212832474..bc96f3d7b 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -630,15 +630,15 @@ Pyramid supports overriding almost every aspect of its setup through its :ref:`Conflict Resolution ` mechanism. This means that in most cases overriding a renderer is as simple as using the :meth:`pyramid.config.Configurator.add_renderer` method to re-define the -template extension. For example, if we'd like to override the ``json`` -extension to specify a new renderer we could do the following: +template extension. For example, if you would like to override the ``.txt`` +extension to specify a new renderer you could do the following: .. code-block:: python json_renderer = pyramid.renderers.JSON() config.add_renderer('json', json_renderer) -After you do this, any views registered with the ``json`` renderer will use +After doing this, any views registered with the ``json`` renderer will use the new renderer. .. index:: -- cgit v1.2.3 From 1449c2f043e25a76deaa1f91fb60365209694e10 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:37:18 -0600 Subject: Remove Chameleon specific support in i18n --- pyramid/config/i18n.py | 11 ----------- pyramid/tests/test_config/test_i18n.py | 18 ------------------ 2 files changed, 29 deletions(-) diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 9eb59e1c7..1296f4913 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -1,10 +1,7 @@ import os import sys -from translationstring import ChameleonTranslate - from pyramid.interfaces import ( - IChameleonTranslate, ILocaleNegotiator, ITranslationDirectories, ) @@ -108,14 +105,6 @@ class I18NConfiguratorMixin(object): tdirs.insert(0, directory) - if directories: - # We actually only need an IChameleonTranslate function - # utility to be registered zero or one times. We register the - # same function once for each added translation directory, - # which does too much work, but has the same effect. - ctranslate = ChameleonTranslate(translator) - self.registry.registerUtility(ctranslate, IChameleonTranslate) - self.action(None, register, introspectables=introspectables) def translator(msg): diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py index fdee0416f..71c68af8a 100644 --- a/pyramid/tests/test_config/test_i18n.py +++ b/pyramid/tests/test_config/test_i18n.py @@ -42,13 +42,10 @@ class TestI18NConfiguratorMixin(unittest.TestCase): def test_add_translation_dirs_no_specs(self): from pyramid.interfaces import ITranslationDirectories - from pyramid.interfaces import IChameleonTranslate config = self._makeOne() config.add_translation_dirs() self.assertEqual(config.registry.queryUtility(ITranslationDirectories), None) - self.assertEqual(config.registry.queryUtility(IChameleonTranslate), - None) def test_add_translation_dirs_asset_spec(self): from pyramid.interfaces import ITranslationDirectories @@ -83,21 +80,6 @@ class TestI18NConfiguratorMixin(unittest.TestCase): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale3, locale, locale2]) - def test_add_translation_dirs_registers_chameleon_translate(self): - from pyramid.interfaces import IChameleonTranslate - from pyramid.threadlocal import manager - from pyramid.request import Request - config = self._makeOne(autocommit=True) - request = Request.blank('/') - request.registry = config.registry - manager.push({'request':request, 'registry':config.registry}) - try: - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - translate = config.registry.getUtility(IChameleonTranslate) - self.assertEqual(translate('Approve'), 'Approve') - finally: - manager.pop() - def test_add_translation_dirs_abspath(self): from pyramid.interfaces import ITranslationDirectories config = self._makeOne(autocommit=True) -- cgit v1.2.3 From 9732ccd60209669ad6693b5abf693b2bac37efc9 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:38:10 -0600 Subject: Comment out tests that require Chameleon These tests should be rewritten to use the JSON or string renderer instead. --- pyramid/tests/test_config/test_views.py | 78 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 94bc497ba..a80ea23fb 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1840,45 +1840,45 @@ class TestViewsConfigurationMixin(unittest.TestCase): result = view(None, request) self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2') - def test_add_notfound_view_with_renderer(self): - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.httpexceptions import HTTPNotFound - config = self._makeOne(autocommit=True) - view = lambda *arg: {} - config.add_notfound_view( - view, - renderer='pyramid.tests.test_config:files/minimal.pt') - config.begin() - try: # chameleon depends on being able to find a threadlocal registry - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPNotFound), - request_iface=IRequest) - result = view(None, request) - finally: - config.end() - self.assertTrue(b'div' in result.body) - - def test_add_forbidden_view_with_renderer(self): - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.httpexceptions import HTTPForbidden - config = self._makeOne(autocommit=True) - view = lambda *arg: {} - config.add_forbidden_view( - view, - renderer='pyramid.tests.test_config:files/minimal.pt') - config.begin() - try: # chameleon requires a threadlocal registry - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPForbidden), - request_iface=IRequest) - result = view(None, request) - finally: - config.end() - self.assertTrue(b'div' in result.body) +# def test_add_notfound_view_with_renderer(self): +# from zope.interface import implementedBy +# from pyramid.interfaces import IRequest +# from pyramid.httpexceptions import HTTPNotFound +# config = self._makeOne(autocommit=True) +# view = lambda *arg: {} +# config.add_notfound_view( +# view, +# renderer='pyramid.tests.test_config:files/minimal.pt') +# config.begin() +# try: # chameleon depends on being able to find a threadlocal registry +# request = self._makeRequest(config) +# view = self._getViewCallable(config, +# ctx_iface=implementedBy(HTTPNotFound), +# request_iface=IRequest) +# result = view(None, request) +# finally: +# config.end() +# self.assertTrue(b'div' in result.body) +# +# def test_add_forbidden_view_with_renderer(self): +# from zope.interface import implementedBy +# from pyramid.interfaces import IRequest +# from pyramid.httpexceptions import HTTPForbidden +# config = self._makeOne(autocommit=True) +# view = lambda *arg: {} +# config.add_forbidden_view( +# view, +# renderer='pyramid.tests.test_config:files/minimal.pt') +# config.begin() +# try: # chameleon requires a threadlocal registry +# request = self._makeRequest(config) +# view = self._getViewCallable(config, +# ctx_iface=implementedBy(HTTPForbidden), +# request_iface=IRequest) +# result = view(None, request) +# finally: +# config.end() +# self.assertTrue(b'div' in result.body) def test_set_view_mapper(self): from pyramid.interfaces import IViewMapperFactory -- cgit v1.2.3 From b9457d7af7b998cf33209b090247124458f4c1a4 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:38:47 -0600 Subject: Remove Chameleon specific renderer tests --- pyramid/tests/test_renderers.py | 339 ++-------------------------------------- 1 file changed, 9 insertions(+), 330 deletions(-) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index befb714bd..42c267fd8 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -10,18 +10,18 @@ class TestTemplateRendererFactory(unittest.TestCase): def tearDown(self): cleanUp() - + def _callFUT(self, info, impl): from pyramid.renderers import template_renderer_factory return template_renderer_factory(info, impl) def test_lookup_found(self): - from pyramid.interfaces import IChameleonLookup + from pyramid.interfaces import IJSONAdapter L = [] def dummy(info): L.append(info) return True - self.config.registry.registerUtility(dummy, IChameleonLookup, + self.config.registry.registerUtility(dummy, IJSONAdapter, name='abc') class DummyInfo(object): pass @@ -49,327 +49,6 @@ class TestTemplateRendererFactory(unittest.TestCase): result = self._callFUT(info, None) self.assertTrue(result is renderer) -class TestChameleonRendererLookup(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, impl): - from pyramid.renderers import ChameleonRendererLookup - return ChameleonRendererLookup(impl, self.config.registry) - - def _registerTemplateRenderer(self, renderer, name): - from pyramid.interfaces import ITemplateRenderer - self.config.registry.registerUtility( - renderer, ITemplateRenderer, name=name) - - def test_get_spec_not_abspath_no_colon_no_package(self): - lookup = self._makeOne(None) - result = lookup.get_spec('foo', None) - self.assertEqual(result, 'foo') - - def test_get_spec_not_abspath_no_colon_with_package(self): - from pyramid import tests - lookup = self._makeOne(None) - result = lookup.get_spec('foo', tests) - self.assertEqual(result, 'pyramid.tests:foo') - - def test_get_spec_not_abspath_with_colon_no_package(self): - lookup = self._makeOne(None) - result = lookup.get_spec('fudge:foo', None) - self.assertEqual(result, 'fudge:foo') - - def test_get_spec_not_abspath_with_colon_with_package(self): - from pyramid import tests - lookup = self._makeOne(None) - result = lookup.get_spec('fudge:foo', tests) - self.assertEqual(result, 'fudge:foo') - - def test_get_spec_is_abspath_no_colon_no_package(self): - import os - lookup = self._makeOne(None) - spec = os.path.abspath(__file__) - result = lookup.get_spec(spec, None) - self.assertEqual(result, spec) - - def test_get_spec_is_abspath_no_colon_with_path_in_package(self): - from pyramid import tests - import os - lookup = self._makeOne(None) - f = __file__ - spec = os.path.abspath(f) - result = lookup.get_spec(spec, tests) - self.assertEqual(result, 'pyramid.tests:%s' % os.path.split(f)[-1]) - - def test_get_spec_is_abspath_no_colon_with_path_outside_package(self): - import venusian # used only because it's outside of pyramid.tests - import os - lookup = self._makeOne(None) - f = __file__ - spec = os.path.abspath(f) - result = lookup.get_spec(spec, venusian) - self.assertEqual(result, spec) - - def test_get_spec_is_abspath_with_colon_no_package(self): - import os - lookup = self._makeOne(None) - spec = os.path.join(os.path.abspath(__file__), ':foo') - result = lookup.get_spec(spec, None) - self.assertEqual(result, spec) - - def test_get_spec_is_abspath_with_colon_with_path_in_package(self): - from pyramid import tests - import os - lookup = self._makeOne(None) - f = os.path.abspath(__file__) - spec = os.path.join(f, ':foo') - result = lookup.get_spec(spec, tests) - tail = spec.split(os.sep)[-2:] - self.assertEqual(result, 'pyramid.tests:%s/%s' % tuple(tail)) - - def test_get_spec_is_abspath_with_colon_with_path_outside_package(self): - import venusian # used only because it's outside of pyramid.tests - import os - lookup = self._makeOne(None) - spec = os.path.join(os.path.abspath(__file__), ':foo') - result = lookup.get_spec(spec, venusian) - self.assertEqual(result, spec) - - def test_translate(self): - from pyramid.interfaces import IChameleonTranslate - def t(): pass - self.config.registry.registerUtility(t, IChameleonTranslate) - lookup = self._makeOne(None) - self.assertEqual(lookup.translate, t) - - def test_debug_settings_None(self): - self.config.registry.settings = None - lookup = self._makeOne(None) - self.assertEqual(lookup.debug, False) - - def test_debug_settings_not_None(self): - self.config.registry.settings = {'debug_templates':True} - lookup = self._makeOne(None) - self.assertEqual(lookup.debug, True) - - def test_auto_reload_settings_None(self): - self.config.registry.settings = None - lookup = self._makeOne(None) - self.assertEqual(lookup.auto_reload, False) - - def test_auto_reload_settings_not_None(self): - self.config.registry.settings = {'reload_templates':True} - lookup = self._makeOne(None) - self.assertEqual(lookup.auto_reload, True) - - def test___call__abspath_path_notexists(self): - abspath = '/wont/exist' - self._registerTemplateRenderer({}, abspath) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - self.assertRaises(ValueError, lookup.__call__, info) - - def test___call__abspath_alreadyregistered(self): - import os - abspath = os.path.abspath(__file__) - renderer = {} - self._registerTemplateRenderer(renderer, abspath) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(result is renderer) - - def test___call__abspath_notyetregistered(self): - import os - abspath = os.path.abspath(__file__) - renderer = {} - factory = DummyFactory(renderer) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertEqual(result, renderer) - - def test___call__relpath_path_registered(self): - renderer = {} - spec = 'foo/bar' - self._registerTemplateRenderer(renderer, spec) - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(renderer is result) - - def test___call__relpath_has_package_registered(self): - renderer = {} - import pyramid.tests - spec = 'bar/baz' - self._registerTemplateRenderer(renderer, 'pyramid.tests:bar/baz') - info = DummyRendererInfo({ - 'name':spec, - 'package':pyramid.tests, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(renderer is result) - - def test___call__spec_notfound(self): - spec = 'pyramid.tests:wont/exist' - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(None) - self.assertRaises(ValueError, lookup.__call__, info) - - def test___call__spec_alreadyregistered(self): - from pyramid import tests - module_name = tests.__name__ - relpath = 'test_renderers.py' - spec = '%s:%s' % (module_name, relpath) - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - renderer = {} - self._registerTemplateRenderer(renderer, spec) - lookup = self._makeOne(None) - result = lookup(info) - self.assertTrue(result is renderer) - - def test___call__spec_notyetregistered(self): - import os - from pyramid import tests - module_name = tests.__name__ - relpath = 'test_renderers.py' - renderer = {} - factory = DummyFactory(renderer) - spec = '%s:%s' % (module_name, relpath) - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - path = os.path.abspath(__file__).split('$')[0] # jython - if path.endswith('.pyc'): # pragma: no cover - path = path[:-1] - self.assertTrue(factory.path.startswith(path)) - self.assertEqual(factory.kw, {'macro':None}) - - def test___call__spec_withmacro(self): - from pyramid.interfaces import ITemplateRenderer - import os - from pyramid import tests - module_name = tests.__name__ - relpath = 'fixtures/withmacro#foo.pt' - renderer = {} - factory = DummyFactory(renderer) - spec = '%s:%s' % (module_name, relpath) - reg = self.config.registry - info = DummyRendererInfo({ - 'name':spec, - 'package':None, - 'registry':reg, - 'settings':{}, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - 'fixtures', - 'withmacro.pt') - self.assertTrue(factory.path.startswith(path)) - self.assertEqual(factory.kw, {'macro':'foo'}) - self.assertTrue( - reg.getUtility(ITemplateRenderer, name=spec) is renderer - ) - - def test___call__reload_assets_true(self): - import pyramid.tests - from pyramid.interfaces import ISettings - from pyramid.interfaces import ITemplateRenderer - settings = {'reload_assets':True} - self.config.registry.registerUtility(settings, ISettings) - renderer = {} - factory = DummyFactory(renderer) - spec = 'test_renderers.py' - reg = self.config.registry - info = DummyRendererInfo({ - 'name':spec, - 'package':pyramid.tests, - 'registry':reg, - 'settings':settings, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - spec = '%s:%s' % ('pyramid.tests', 'test_renderers.py') - self.assertEqual(reg.queryUtility(ITemplateRenderer, name=spec), - None) - - def test___call__reload_assets_false(self): - import pyramid.tests - from pyramid.interfaces import ITemplateRenderer - settings = {'reload_assets':False} - renderer = {} - factory = DummyFactory(renderer) - spec = 'test_renderers.py' - reg = self.config.registry - info = DummyRendererInfo({ - 'name':spec, - 'package':pyramid.tests, - 'registry':reg, - 'settings':settings, - 'type':'type', - }) - lookup = self._makeOne(factory) - result = lookup(info) - self.assertTrue(result is renderer) - spec = '%s:%s' % ('pyramid.tests', 'test_renderers.py') - self.assertNotEqual(reg.queryUtility(ITemplateRenderer, name=spec), - None) - class TestJSON(unittest.TestCase): def setUp(self): self.config = testing.setUp() @@ -470,7 +149,7 @@ class Test_string_renderer_factory(unittest.TestCase): value = text_('La Pe\xc3\xb1a', 'utf-8') result = renderer(value, {}) self.assertEqual(result, value) - + def test_it_str(self): renderer = self._callFUT(None) value = 'La Pe\xc3\xb1a' @@ -680,7 +359,7 @@ class TestRendererHelper(unittest.TestCase): helper = self._makeOne('loo.foo') response = helper._make_response(None, request) self.assertEqual(response.body, b'abc') - + def test__make_response_with_content_type(self): from pyramid.response import Response request = testing.DummyRequest() @@ -873,7 +552,7 @@ class Test_render(unittest.TestCase): self.assertEqual(result, 'abc') renderer.assert_(a=1) renderer.assert_(request=None) - + def test_it_with_request(self): renderer = self.config.testing_add_renderer( 'pyramid.tests:abc/def.pt') @@ -917,7 +596,7 @@ class Test_render_to_response(unittest.TestCase): self.assertEqual(response.body, b'abc') renderer.assert_(a=1) renderer.assert_(request=None) - + def test_it_with_request(self): renderer = self.config.testing_add_renderer( 'pyramid.tests:abc/def.pt') @@ -1007,9 +686,9 @@ class DummyFactory: self.path = path self.kw = kw return self.renderer - + class DummyRendererInfo(object): def __init__(self, kw): self.__dict__.update(kw) - + -- cgit v1.2.3 From a257ebbe3b71305b4ef644de4b8495f904f4cf40 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:56:21 -0600 Subject: Remove Chameleon only fixtures files. --- pyramid/tests/fixtures/minimal.pt | 3 --- pyramid/tests/fixtures/pp.pt | 3 --- pyramid/tests/fixtures/withmacro.pt | 7 ------- 3 files changed, 13 deletions(-) delete mode 100644 pyramid/tests/fixtures/minimal.pt delete mode 100644 pyramid/tests/fixtures/pp.pt delete mode 100644 pyramid/tests/fixtures/withmacro.pt diff --git a/pyramid/tests/fixtures/minimal.pt b/pyramid/tests/fixtures/minimal.pt deleted file mode 100644 index 693d155ef..000000000 --- a/pyramid/tests/fixtures/minimal.pt +++ /dev/null @@ -1,3 +0,0 @@ -
-
diff --git a/pyramid/tests/fixtures/pp.pt b/pyramid/tests/fixtures/pp.pt deleted file mode 100644 index 9df7d22da..000000000 --- a/pyramid/tests/fixtures/pp.pt +++ /dev/null @@ -1,3 +0,0 @@ -

WRAPPED

diff --git a/pyramid/tests/fixtures/withmacro.pt b/pyramid/tests/fixtures/withmacro.pt deleted file mode 100644 index 6fa654645..000000000 --- a/pyramid/tests/fixtures/withmacro.pt +++ /dev/null @@ -1,7 +0,0 @@ - -Outside macro - - Hello! - - - -- cgit v1.2.3 From a18f3060e3f77c791baa9151e9c80eac6f8e339e Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 4 Sep 2013 22:56:41 -0600 Subject: Remove TestTemplateRenderFactory which is Chameleon only --- pyramid/tests/test_renderers.py | 45 ----------------------------------------- 1 file changed, 45 deletions(-) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 42c267fd8..7cc2486a9 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -4,51 +4,6 @@ from pyramid.testing import cleanUp from pyramid import testing from pyramid.compat import text_ -class TestTemplateRendererFactory(unittest.TestCase): - def setUp(self): - self.config = cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, info, impl): - from pyramid.renderers import template_renderer_factory - return template_renderer_factory(info, impl) - - def test_lookup_found(self): - from pyramid.interfaces import IJSONAdapter - L = [] - def dummy(info): - L.append(info) - return True - self.config.registry.registerUtility(dummy, IJSONAdapter, - name='abc') - class DummyInfo(object): - pass - info = DummyInfo() - info.registry = self.config.registry - info.type = 'abc' - result = self._callFUT(info, None) - self.assertEqual(result, True) - self.assertEqual(L, [info]) - - def test_lookup_miss(self): - from pyramid.interfaces import ITemplateRenderer - import os - abspath = os.path.abspath(__file__) - renderer = {} - self.config.registry.registerUtility( - renderer, ITemplateRenderer, name=abspath) - info = DummyRendererInfo({ - 'name':abspath, - 'package':None, - 'registry':self.config.registry, - 'settings':{}, - 'type':'type', - }) - result = self._callFUT(info, None) - self.assertTrue(result is renderer) - class TestJSON(unittest.TestCase): def setUp(self): self.config = testing.setUp() -- cgit v1.2.3 From 004d847fe87424f187a920086cb8b9baa8b41b42 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 00:02:51 -0500 Subject: more chameleon builtin references --- docs/narr/renderers.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index bc96f3d7b..dd67c779c 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -67,9 +67,8 @@ When this configuration is added to an application, the ``myproject.views.my_view`` view callable will now use a ``json`` renderer, which renders view return values to a :term:`JSON` response serialization. -Other built-in renderers include renderers which use the :term:`Chameleon` -templating language to render a dictionary to a response. Additional -renderers can be added by developers to the system as necessary. +Pyramid defines several :ref:`built_in_renderers`, and additional renderers +can be added by developers to the system as necessary. See :ref:`adding_and_overriding_renderers`. Views which use a renderer and return a non-Response value can vary non-body -- cgit v1.2.3 From 6f2d0468856b2a3ca84cb22c379196298b2399ea Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 00:35:41 -0500 Subject: add a section mentioning external template bindings --- docs/narr/renderers.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index dd67c779c..21c59c06a 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -364,6 +364,31 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. +Available Add-On Template System Bindings +----------------------------------------- + +The Pylons Project maintains several packages providing bindings to different +templating languages including the following: + ++------------------------------+------------------------------+ +| Template Language | Pyramid Bindings | ++==============================+==============================+ +| Chameleon_ | pyramid_chameleon_ | ++------------------------------+------------------------------+ +| Jinja2_ | pyramid_jinja2_ | ++------------------------------+------------------------------+ +| Mako_ | pyramid_mako_ | ++------------------------------+------------------------------+ + +.. _Chameleon: http://chameleon.readthedocs.org/en/latest/ +.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon + +.. _Jinja2: http://jinja.pocoo.org/docs/ +.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 + +.. _Mako: http://www.makotemplates.org/ +.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako + .. index:: single: response headers (from a renderer) single: renderer response headers -- cgit v1.2.3 From 3803d92fc0da5282656d4229e063a1908ec5522a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:26:42 -0500 Subject: update render() to preserve the original response object --- CHANGES.txt | 12 ++++++++++++ pyramid/renderers.py | 18 +++++++++++++++++- pyramid/tests/test_renderers.py | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index cdaad5a90..3c953e728 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,15 @@ +Next Release +============ + +Backwards Incompatibilities +--------------------------- + +- Almost all renderers affect properties on the ``request.response`` response + object. For example, setting the content-type in the JSON renderer to + 'application/json'. These mutations will no longer affect + ``request.response`` when using the ``pyramid.renderers.render()`` API as + its only expected output is a rendered string object. + 1.5a1 (2013-08-30) ================== diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 602655be8..4b192f37d 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -85,7 +85,23 @@ def render(renderer_name, value, request=None, package=None): package = caller_package() helper = RendererHelper(name=renderer_name, package=package, registry=registry) - return helper.render(value, None, request=request) + + saved_response = None + # save the current response, preventing the renderer from affecting it + attrs = request.__dict__ if request is not None else {} + if 'response' in attrs: + saved_response = attrs['response'] + del attrs['response'] + + result = helper.render(value, None, request=request) + + # restore the original response, overwriting any changes + if saved_response is not None: + attrs['response'] = saved_response + elif 'response' in attrs: + del attrs['response'] + + return result def render_to_response(renderer_name, value, request=None, package=None): """ Using the renderer ``renderer_name`` (a template diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index befb714bd..e9d8dec68 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -897,6 +897,14 @@ class Test_render(unittest.TestCase): renderer.assert_(a=1) renderer.assert_(request=request) + def test_it_preserves_response(self): + request = testing.DummyRequest() + response = object() # should error if mutated + request.response = response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertEqual(request.response, response) + class Test_render_to_response(unittest.TestCase): def setUp(self): self.config = testing.setUp() -- cgit v1.2.3 From f6f1d1685f09f1ecd3717c90e687a6e3652b4fdc Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:32:41 -0500 Subject: remove the deprecated request.response_* attributes --- CHANGES.txt | 10 +++++ docs/api/request.rst | 18 --------- docs/narr/renderers.rst | 34 ----------------- pyramid/renderers.py | 20 ---------- pyramid/request.py | 82 ----------------------------------------- pyramid/tests/test_renderers.py | 57 ---------------------------- 6 files changed, 10 insertions(+), 211 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index cdaad5a90..80578d539 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,13 @@ +Next Release +============ + +Backwards Incompatibilities +--------------------------- + +- Removed the ``request.response_*`` varying attributes. These attributes + have been deprecated since Pyramid 1.1, and as per the deprecation policy, + have now been removed. + 1.5a1 (2013-08-30) ================== diff --git a/docs/api/request.rst b/docs/api/request.rst index 02290eaf3..ef41ba4c8 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -235,24 +235,6 @@ .. automethod:: resource_path - .. attribute:: response_* - - In Pyramid 1.0, you could set attributes on a - :class:`pyramid.request.Request` which influenced the behavior of - *rendered* responses (views which use a :term:`renderer` and which - don't directly return a response). These attributes began with - ``response_``, such as ``response_headerlist``. If you needed to - influence response values from a view that uses a renderer (such as the - status code, a header, the content type, etc) you would set these - attributes. See :ref:`response_prefixed_attrs` for further discussion. - As of Pyramid 1.1, assignment to ``response_*`` attrs is deprecated. - Assigning to one is still supported but will cause a deprecation - warning to be emitted, and eventually the feature will be removed. For - new code, instead of assigning ``response_*`` attributes to the - request, use API of the :attr:`pyramid.request.Request.response` - object (exposed to view code as ``request.response``) to influence - rendered response behavior. - .. attribute:: json_body This property will return the JSON-decoded variant of the request diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index a2811dbae..9132606b3 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -556,40 +556,6 @@ For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of ``request.response``, see :attr:`pyramid.request.Request.response`. -.. _response_prefixed_attrs: - -Deprecated Mechanism to Vary Attributes of Rendered Responses -------------------------------------------------------------- - -In previous releases of Pyramid (1.0 and before), the ``request.response`` -attribute did not exist. Instead, Pyramid required users to set special -``response_`` -prefixed attributes of the request to influence response -behavior. As of Pyramid 1.1, those request attributes are deprecated and -their use will cause a deprecation warning to be issued when used. Until -their existence is removed completely, we document them below, for benefit of -people with older code bases. - -``response_content_type`` - Defines the content-type of the resulting response, - e.g. ``text/xml``. - -``response_headerlist`` - A sequence of tuples describing header values that should be set in the - response, e.g. ``[('Set-Cookie', 'abc=123'), ('X-My-Header', 'foo')]``. - -``response_status`` - A WSGI-style status code (e.g. ``200 OK``) describing the status of the - response. - -``response_charset`` - The character set (e.g. ``UTF-8``) of the response. - -``response_cache_for`` - A value in seconds which will influence ``Cache-Control`` and ``Expires`` - headers in the returned response. The same can also be achieved by - returning various values in the ``response_headerlist``, this is purely a - convenience. - .. _adding_and_overriding_renderers: Adding and Changing Renderers diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 602655be8..a647d273c 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -576,26 +576,6 @@ class RendererHelper(object): else: response.body = result - if request is not None: - # deprecated mechanism to set up request.response_* attrs, see - # pyramid.request.Request - attrs = request.__dict__ - content_type = attrs.get('_response_content_type', None) - if content_type is not None: - response.content_type = content_type - headerlist = attrs.get('_response_headerlist', None) - if headerlist is not None: - for k, v in headerlist: - response.headers.add(k, v) - status = attrs.get('_response_status', None) - if status is not None: - response.status = status - charset = attrs.get('_response_charset', None) - if charset is not None: - response.charset = charset - cache_for = attrs.get('_response_cache_for', None) - if cache_for is not None: - response.cache_expires = cache_for return response def clone(self, name=None, package=None, registry=None): diff --git a/pyramid/request.py b/pyramid/request.py index 9b62bee00..5c064d3ef 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -111,88 +111,6 @@ class DeprecatedRequestMethodsMixin(object): def values(self): return self.environ.values() - # 1.0 deprecated bw compat code for using response_* values - - rr_dep = ('Accessing and setting "request.response_%s" is ' - 'deprecated as of Pyramid 1.1; access or set ' - '"request.response.%s" instead.') - - # response_content_type - def _response_content_type_get(self): - return self._response_content_type - def _response_content_type_set(self, value): - self._response_content_type = value - def _response_content_type_del(self): - del self._response_content_type - response_content_type = property(_response_content_type_get, - _response_content_type_set, - _response_content_type_del) - response_content_type = deprecated( - response_content_type, - rr_dep % ('content_type', 'content_type')) - - # response_headerlist - def _response_headerlist_get(self): - return self._response_headerlist - def _response_headerlist_set(self, value): - self._response_headerlist = value - def _response_headerlist_del(self): - del self._response_headerlist - response_headerlist = property(_response_headerlist_get, - _response_headerlist_set, - _response_headerlist_del) - - hl_dep = ('Accessing and setting "request.response_headerlist" is ' - 'deprecated as of Pyramid 1.1; access the headerlist via ' - '"request.response.headerlist" and extend headers via ' - '"request.response.headerlist.extend(alist)" instead of ' - '"request.response_headerlist = alist"') - - response_headerlist = deprecated(response_headerlist, hl_dep) - - # response_status - def _response_status_get(self): - return self._response_status - def _response_status_set(self, value): - self._response_status = value - def _response_status_del(self): - del self._response_status - response_status = property(_response_status_get, - _response_status_set, - _response_status_del) - - response_status = deprecated( - response_status, - rr_dep % ('status', 'status')) - - # response_charset - def _response_charset_get(self): - return self._response_charset - def _response_charset_set(self, value): - self._response_charset = value - def _response_charset_del(self): - del self._response_charset - response_charset = property(_response_charset_get, - _response_charset_set, - _response_charset_del) - response_charset = deprecated( - response_charset, - rr_dep % ('charset', 'charset')) - - # response_cache_for - def _response_cache_for_get(self): - return self._response_cache_for - def _response_cache_for_set(self, value): - self._response_cache_for = value - def _response_cache_for_del(self): - del self._response_cache_for - response_cache_for = property(_response_cache_for_get, - _response_cache_for_set, - _response_cache_for_del) - response_cache_for = deprecated( - response_cache_for, - rr_dep % ('cache_for', 'cache_expires')) - class CallbackMethodsMixin(object): response_callbacks = () finished_callbacks = () diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index befb714bd..078373f2e 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -680,63 +680,6 @@ class TestRendererHelper(unittest.TestCase): helper = self._makeOne('loo.foo') response = helper._make_response(None, request) self.assertEqual(response.body, b'abc') - - def test__make_response_with_content_type(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_content_type':'text/nonsense'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.content_type, 'text/nonsense') - self.assertEqual(response.body, b'abc') - - def test__make_response_with_headerlist(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_headerlist':[('a', '1'), ('b', '2')]} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.headerlist, - [('Content-Type', 'text/html; charset=UTF-8'), - ('Content-Length', '3'), - ('a', '1'), - ('b', '2')]) - self.assertEqual(response.body, b'abc') - - def test__make_response_with_status(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_status':'406 You Lose'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.status, '406 You Lose') - self.assertEqual(response.body, b'abc') - - def test__make_response_with_charset(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_charset':'UTF-16'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.charset, 'UTF-16') - - def test__make_response_with_cache_for(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_cache_for':100} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.cache_control.max_age, 100) def test_with_alternate_response_factory(self): from pyramid.interfaces import IResponseFactory -- cgit v1.2.3 From bc0a26ac2b75de362a4bf8142b3385788f318f47 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:50:15 -0500 Subject: add index for custom template engines --- docs/narr/renderers.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 21c59c06a..8de3cd29d 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -364,6 +364,14 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. +.. index:: + single: template system bindings + single: Chameleon + single: Jinja2 + single: Mako + +.. _available_template_system_bindings: + Available Add-On Template System Bindings ----------------------------------------- -- cgit v1.2.3 From 7b5becddb6ff1347a2a1a4e5b63fdde1e506bcc3 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 21:21:54 -0600 Subject: Replace .txt renderer with JSON Update tests expected results so that they now correctly look for the return value returned from the JSON renderer. --- pyramid/tests/test_config/test_init.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index 531357e7f..ccecdc0fd 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -69,9 +69,6 @@ class ConfiguratorTests(unittest.TestCase): config.commit() self.assertTrue(config.registry.getUtility(IRendererFactory, 'json')) self.assertTrue(config.registry.getUtility(IRendererFactory, 'string')) - if not PYPY: - self.assertTrue(config.registry.getUtility(IRendererFactory, '.pt')) - self.assertTrue(config.registry.getUtility(IRendererFactory,'.txt')) def test_begin(self): from pyramid.config import Configurator @@ -1324,11 +1321,11 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): self._registerRenderer(config) view = lambda *arg: 'OK' config.add_route('name', 'path', view=view, - view_renderer='files/minimal.txt') + view_renderer='json') request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, b'Hello!') + self.assertEqual(wrapper(None, None).body, b'"OK"') def test_add_route_with_view_attr(self): from pyramid.renderers import null_renderer @@ -1352,11 +1349,11 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): self._registerRenderer(config) view = lambda *arg: 'OK' config.add_route('name', 'path', view=view, - renderer='files/minimal.txt') + renderer='json') request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, b'Hello!') + self.assertEqual(wrapper(None, None).body, b'"OK"') def test_add_route_with_view_permission(self): from pyramid.interfaces import IAuthenticationPolicy -- cgit v1.2.3 From 13b1871878932091e56b01bb27eef7033521a83f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 5 Sep 2013 23:23:27 -0400 Subject: update HACKING --- HACKING.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/HACKING.txt b/HACKING.txt index abfed6dab..684a42ee6 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -78,7 +78,7 @@ In order to add a feature to Pyramid: documentation (in ``docs/``). - The feature must work fully on the following CPython versions: 2.6, - 2.7, and 3.2 on both UNIX and Windows. + 2.7, 3.2, and 3.3 on both UNIX and Windows. - The feature must work on the latest version of PyPy. @@ -104,7 +104,9 @@ Coding Style - PEP8 compliance. Whitespace rules are relaxed: not necessary to put 2 newlines between classes. But 80-column lines, in particular, are - mandatory. + mandatory. See + http://docs.pylonsproject.org/en/latest/community/codestyle.html for more + information. - Please do not remove trailing whitespace. Configure your editor to reduce diff noise. See https://github.com/Pylons/pyramid/issues/788 for more. @@ -112,13 +114,15 @@ Coding Style Running Tests -------------- -- To run all tests for Pyramid on a single Python version, run ``nosetests`` from - your development virtualenv (See *Using a Development Checkout* above). +- To run all tests for Pyramid on a single Python version, run ``nosetests`` + from your development virtualenv (See *Using a Development Checkout* above). - To run individual tests (i.e. during development) you can use a regular expression with the ``-t`` parameter courtesy of the `nose-selecttests - `_ plugin that's been installed (along with nose itself) via ``python setup.py dev``. The easiest usage is to - simply provide the verbatim name of the test you're working on. + `_ plugin that's been + installed (along with nose itself) via ``python setup.py dev``. The + easiest usage is to simply provide the verbatim name of the test you're + working on. - To run the full set of Pyramid tests on all platforms, install ``tox`` (http://codespeak.net/~hpk/tox/) into a system Python. The ``tox`` console -- cgit v1.2.3 From 22d7411ccb0161b251403c84eb932437a4c1f348 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 21:27:58 -0600 Subject: Remove Chameleon templates --- pyramid/tests/pkgs/rendererscanapp/__init__.py | 2 +- pyramid/tests/pkgs/rendererscanapp/one.pt | 4 ---- pyramid/tests/pkgs/rendererscanapp/two/__init__.py | 2 +- pyramid/tests/pkgs/rendererscanapp/two/two.pt | 4 ---- 4 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 pyramid/tests/pkgs/rendererscanapp/one.pt delete mode 100644 pyramid/tests/pkgs/rendererscanapp/two/two.pt diff --git a/pyramid/tests/pkgs/rendererscanapp/__init__.py b/pyramid/tests/pkgs/rendererscanapp/__init__.py index 1baec0940..f3276a063 100644 --- a/pyramid/tests/pkgs/rendererscanapp/__init__.py +++ b/pyramid/tests/pkgs/rendererscanapp/__init__.py @@ -1,6 +1,6 @@ from pyramid.view import view_config -@view_config(name='one', renderer='one.pt') +@view_config(name='one', renderer='json') def one(request): return {'name':'One!'} diff --git a/pyramid/tests/pkgs/rendererscanapp/one.pt b/pyramid/tests/pkgs/rendererscanapp/one.pt deleted file mode 100644 index 42114d94f..000000000 --- a/pyramid/tests/pkgs/rendererscanapp/one.pt +++ /dev/null @@ -1,4 +0,0 @@ -
- ${name} -
diff --git a/pyramid/tests/pkgs/rendererscanapp/two/__init__.py b/pyramid/tests/pkgs/rendererscanapp/two/__init__.py index be0077fcb..6f575dd83 100644 --- a/pyramid/tests/pkgs/rendererscanapp/two/__init__.py +++ b/pyramid/tests/pkgs/rendererscanapp/two/__init__.py @@ -1,6 +1,6 @@ from pyramid.view import view_config -@view_config(name='two', renderer='two.pt') +@view_config(name='two', renderer='json') def two(request): return {'nameagain':'Two!'} diff --git a/pyramid/tests/pkgs/rendererscanapp/two/two.pt b/pyramid/tests/pkgs/rendererscanapp/two/two.pt deleted file mode 100644 index 7eff97c22..000000000 --- a/pyramid/tests/pkgs/rendererscanapp/two/two.pt +++ /dev/null @@ -1,4 +0,0 @@ -
- ${nameagain} -
-- cgit v1.2.3 From 7e726a0574cb4b17e7926f2b555493088d7c422a Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 21:29:54 -0600 Subject: Remove Chameleon templates from viewdecoratorapp --- pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt | 3 --- pyramid/tests/pkgs/viewdecoratorapp/views/views.py | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt diff --git a/pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt b/pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt deleted file mode 100644 index 6a2f701b6..000000000 --- a/pyramid/tests/pkgs/viewdecoratorapp/views/templates/foo.pt +++ /dev/null @@ -1,3 +0,0 @@ - -${result} - diff --git a/pyramid/tests/pkgs/viewdecoratorapp/views/views.py b/pyramid/tests/pkgs/viewdecoratorapp/views/views.py index 2b7d7e928..18ec78847 100644 --- a/pyramid/tests/pkgs/viewdecoratorapp/views/views.py +++ b/pyramid/tests/pkgs/viewdecoratorapp/views/views.py @@ -1,11 +1,11 @@ from pyramid.view import view_config -@view_config(renderer='templates/foo.pt', name='first') +@view_config(renderer='json', name='first') def first(request): return {'result':'OK1'} @view_config( - renderer='pyramid.tests.pkgs.viewdecoratorapp.views:templates/foo.pt', + renderer='json', name='second') def second(request): return {'result':'OK2'} -- cgit v1.2.3 From 2a104a48baef863ce299ff5564e4594ff704340c Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 21:34:12 -0600 Subject: Remove chameleon templates from fixtureapp --- pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt | 2 -- pyramid/tests/pkgs/fixtureapp/templates/fixture.pt | 6 ------ 2 files changed, 8 deletions(-) delete mode 100644 pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt delete mode 100644 pyramid/tests/pkgs/fixtureapp/templates/fixture.pt diff --git a/pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt b/pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt deleted file mode 100644 index 90531a4b3..000000000 --- a/pyramid/tests/pkgs/fixtureapp/subpackage/templates/bar.pt +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/pyramid/tests/pkgs/fixtureapp/templates/fixture.pt b/pyramid/tests/pkgs/fixtureapp/templates/fixture.pt deleted file mode 100644 index 06dd4e2b1..000000000 --- a/pyramid/tests/pkgs/fixtureapp/templates/fixture.pt +++ /dev/null @@ -1,6 +0,0 @@ - - - - - -- cgit v1.2.3 From b368d7d88518226a3a55f0f31e96be7c57e01bc8 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 21:44:19 -0600 Subject: Fix remaining tests/remove last traces of Chameleon --- pyramid/tests/test_config/files/minimal.pt | 3 --- pyramid/tests/test_config/files/minimal.txt | 1 + .../test_config/pkgs/asset/subpackage/templates/bar.pt | 2 -- pyramid/tests/test_config/pkgs/asset/templates/fixture.pt | 6 ------ pyramid/tests/test_config/test_views.py | 6 ++++-- pyramid/tests/test_integration.py | 14 +++++++------- 6 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 pyramid/tests/test_config/files/minimal.pt create mode 100644 pyramid/tests/test_config/files/minimal.txt delete mode 100644 pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt delete mode 100644 pyramid/tests/test_config/pkgs/asset/templates/fixture.pt diff --git a/pyramid/tests/test_config/files/minimal.pt b/pyramid/tests/test_config/files/minimal.pt deleted file mode 100644 index 693d155ef..000000000 --- a/pyramid/tests/test_config/files/minimal.pt +++ /dev/null @@ -1,3 +0,0 @@ -
-
diff --git a/pyramid/tests/test_config/files/minimal.txt b/pyramid/tests/test_config/files/minimal.txt new file mode 100644 index 000000000..19fe66dfa --- /dev/null +++ b/pyramid/tests/test_config/files/minimal.txt @@ -0,0 +1 @@ +
diff --git a/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt b/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt deleted file mode 100644 index 90531a4b3..000000000 --- a/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/pyramid/tests/test_config/pkgs/asset/templates/fixture.pt b/pyramid/tests/test_config/pkgs/asset/templates/fixture.pt deleted file mode 100644 index 06dd4e2b1..000000000 --- a/pyramid/tests/test_config/pkgs/asset/templates/fixture.pt +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index a80ea23fb..02afc38cd 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1029,6 +1029,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config = self._makeOne(autocommit=True) renderer = self._registerRenderer(config) fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.introspection = False config.add_view(view=view, renderer=fixture) wrapper = self._getViewCallable(config) request = self._makeRequest(config) @@ -1069,6 +1070,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config = self._makeOne(autocommit=True) renderer = self._registerRenderer(config) fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.introspection = False config.add_view(view=None, renderer=fixture) wrapper = self._getViewCallable(config) request = self._makeRequest(config) @@ -1687,8 +1689,8 @@ class TestViewsConfigurationMixin(unittest.TestCase): wrapped = config.registry.adapters.lookup( (IViewClassifier, request_type, Interface), IView, name='') from pyramid.request import Request - request = Request.blank('/static/minimal.pt') - request.subpath = ('minimal.pt', ) + request = Request.blank('/static/minimal.txt') + request.subpath = ('minimal.txt', ) result = wrapped(None, request) self.assertEqual(result.status, '200 OK') self.assertTrue(result.body.startswith(b' Date: Thu, 5 Sep 2013 22:46:40 -0500 Subject: remove chameleon and mako template-specific documentation --- docs/narr/templates.rst | 337 +----------------------------------------------- 1 file changed, 1 insertion(+), 336 deletions(-) diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 26bb6b6cd..24973f253 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -8,10 +8,6 @@ dynamic data provided by a :term:`view`. :app:`Pyramid` offers a number of ways to perform templating tasks out of the box, and provides add-on templating support through a set of bindings packages. -Out of the box, :app:`Pyramid` provides templating via the :term:`Chameleon` -and :term:`Mako` templating libraries. :term:`Chameleon` provides support for -two different types of templates: :term:`ZPT` templates, and text templates. - Before discussing how built-in templates are used in detail, we'll discuss two ways to render templates within :app:`Pyramid` in general: directly, and via renderer @@ -32,7 +28,7 @@ given templating engine to do so. :app:`Pyramid` provides various APIs that allow you to render templates directly from within a view callable. For example, if there is a -:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named +:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named ``templates`` in your application, you can render the template from within the body of a view callable like so: @@ -383,236 +379,6 @@ The same set of system values are provided to templates rendered via a renderer view configuration as those provided to templates rendered imperatively. See :ref:`renderer_system_values`. - -.. index:: - single: Chameleon ZPT templates - single: ZPT templates (Chameleon) - -.. _chameleon_zpt_templates: - -:term:`Chameleon` ZPT Templates -------------------------------- - -Like :term:`Zope`, :app:`Pyramid` uses :term:`ZPT` (Zope Page -Templates) as its default templating language. However, -:app:`Pyramid` uses a different implementation of the :term:`ZPT` -specification than Zope does: the :term:`Chameleon` templating -engine. The Chameleon engine complies largely with the `Zope Page -Template `_ template -specification. However, it is significantly faster. - -The language definition documentation for Chameleon ZPT-style -templates is available from `the Chameleon website -`_. - -Given a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory -in your application named ``templates``, you can render the template as -a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='templates/foo.pt') - def my_view(request): - return {'foo':1, 'bar':2} - -See also :ref:`built_in_renderers` for more general information about -renderers, including Chameleon ZPT renderers. - -.. index:: - single: ZPT template (sample) - -A Sample ZPT Template -~~~~~~~~~~~~~~~~~~~~~ - -Here's what a simple :term:`Chameleon` ZPT template used under -:app:`Pyramid` might look like: - -.. code-block:: xml - :linenos: - - - - - - ${project} Application - - -

Welcome to ${project}, an - application generated by the pyramid web - application framework.

- - - -Note the use of :term:`Genshi` -style ``${replacements}`` above. This -is one of the ways that :term:`Chameleon` ZPT differs from standard -ZPT. The above template expects to find a ``project`` key in the set -of keywords passed in to it via :func:`~pyramid.renderers.render` or -:func:`~pyramid.renderers.render_to_response`. Typical ZPT -attribute-based syntax (e.g. ``tal:content`` and ``tal:replace``) also -works in these templates. - -.. index:: - single: ZPT macros - single: Chameleon ZPT macros - -Using ZPT Macros in :app:`Pyramid` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When a :term:`renderer` is used to render a template, :app:`Pyramid` makes at -least two top-level names available to the template by default: ``context`` -and ``request``. One of the common needs in ZPT-based templates is to use -one template's "macros" from within a different template. In Zope, this is -typically handled by retrieving the template from the ``context``. But the -context in :app:`Pyramid` is a :term:`resource` object, and templates cannot -usually be retrieved from resources. To use macros in :app:`Pyramid`, you -need to make the macro template itself available to the rendered template by -passing the macro template, or even the macro itself, *into* the rendered -template. To do this you can use the :func:`pyramid.renderers.get_renderer` -API to retrieve the macro template, and pass it into the template being -rendered via the dictionary returned by the view. For example, using a -:term:`view configuration` via a :class:`~pyramid.view.view_config` decorator -that uses a :term:`renderer`: - -.. code-block:: python - :linenos: - - from pyramid.renderers import get_renderer - from pyramid.view import view_config - - @view_config(renderer='templates/mytemplate.pt') - def my_view(request): - main = get_renderer('templates/master.pt').implementation() - return {'main':main} - -Where ``templates/master.pt`` might look like so: - -.. code-block:: xml - :linenos: - - - -

- Hello Fred! -

-
- - -And ``templates/mytemplate.pt`` might look like so: - -.. code-block:: xml - :linenos: - - - - Chris - - - - -Using A Chameleon Macro Name Within a Renderer Name -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -At times, you may want to render a macro inside of a Chameleon ZPT template -instead of the full Chameleon ZPT template. To render the content of a -``define-macro`` field inside a Chameleon ZPT template, given a Chameleon -template file named ``foo.pt`` and a macro named ``bar`` defined within it -(e.g. ``
...
``), you can configure the -template as a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='foo#bar.pt') - def my_view(request): - return {'project':'my project'} - -The above will render only the ``bar`` macro defined within the ``foo.pt`` -template instead of the entire template. - -.. versionadded:: 1.4 - -.. index:: - single: Chameleon text templates - -.. _chameleon_text_templates: - -Templating with :term:`Chameleon` Text Templates ------------------------------------------------- - -:app:`Pyramid` also allows for the use of templates which are -composed entirely of non-XML text via :term:`Chameleon`. To do so, -you can create templates that are entirely composed of text except for -``${name}`` -style substitution points. - -Here's an example usage of a Chameleon text template. Create a file -on disk named ``mytemplate.txt`` in your project's ``templates`` -directory with the following contents: - -.. code-block:: text - - Hello, ${name}! - -Then in your project's ``views.py`` module, you can create a view -which renders this template: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='templates/mytemplate.txt') - def my_view(request): - return {'name':'world'} - -When the template is rendered, it will show: - -.. code-block:: text - - Hello, world! - -See also :ref:`built_in_renderers` for more general information about -renderers, including Chameleon text renderers. - -.. index:: - single: template renderer side effects - -Side Effects of Rendering a Chameleon Template ----------------------------------------------- - -When a Chameleon template is rendered from a file, the templating -engine writes a file in the same directory as the template file itself -as a kind of cache, in order to do less work the next time the -template needs to be read from disk. If you see "strange" ``.py`` -files showing up in your ``templates`` directory (or otherwise -directly "next" to your templates), it is due to this feature. - -If you're using a version control system such as Subversion, you -should configure it to ignore these files. Here's the contents of the -author's ``svn propedit svn:ignore .`` in each of my ``templates`` -directories. - -.. code-block:: text - - *.pt.py - *.txt.py - -Note that I always name my Chameleon ZPT template files with a ``.pt`` -extension and my Chameleon text template files with a ``.txt`` -extension so that these ``svn:ignore`` patterns work. - .. index:: pair: debugging; templates @@ -643,107 +409,6 @@ undefined variable (e.g. ``${wrong}``) might end up looking like this: The output tells you which template the error occurred in, as well as displaying the arguments passed to the template itself. -.. index:: - single: template internationalization - single: internationalization (of templates) - -:term:`Chameleon` Template Internationalization ------------------------------------------------ - -See :ref:`chameleon_translation_strings` for information about -supporting internationalized units of text within :term:`Chameleon` -templates. - -.. index:: - single: Mako - -.. _mako_templates: - -Templating With Mako Templates ------------------------------- - -:term:`Mako` is a templating system written by Mike Bayer. :app:`Pyramid` -has built-in bindings for the Mako templating system. The language -definition documentation for Mako templates is available from `the Mako -website `_. - -To use a Mako template, given a :term:`Mako` template file named ``foo.mak`` -in the ``templates`` subdirectory in your application package named -``mypackage``, you can configure the template as a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='foo.mak') - def my_view(request): - return {'project':'my project'} - -For the above view callable to work, the following setting needs to be -present in the application stanza of your configuration's ``ini`` file: - -.. code-block:: ini - - mako.directories = mypackage:templates - -This lets the Mako templating system know that it should look for templates -in the ``templates`` subdirectory of the ``mypackage`` Python package. See -:ref:`mako_template_renderer_settings` for more information about the -``mako.directories`` setting and other Mako-related settings that can be -placed into the application's ``ini`` file. - -.. index:: - single: Mako template (sample) - -A Sample Mako Template -~~~~~~~~~~~~~~~~~~~~~~ - -Here's what a simple :term:`Mako` template used under :app:`Pyramid` might -look like: - -.. code-block:: xml - :linenos: - - - - ${project} Application - - -

Welcome to ${project}, an - application generated by the pyramid web framework.

- - - -This template doesn't use any advanced features of Mako, only the -``${}`` replacement syntax for names that are passed in as -:term:`renderer globals`. See the `the Mako documentation -`_ to use more advanced features. - -Using A Mako def name Within a Renderer Name -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Sometimes you'd like to render a ``def`` inside of a Mako template instead of -the full Mako template. To render a def inside a Mako template, given a -:term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can -configure the template as a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='foo#bar.mak') - def my_view(request): - return {'project':'my project'} - -The above will render the ``bar`` def from within the ``foo.mak`` template -instead of the entire template. - -.. versionadded:: 1.4 - .. index:: single: automatic reloading of templates single: template automatic reload -- cgit v1.2.3 From 7a60e44961309f5453fba84c7f606af6b19ab096 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 22:57:37 -0500 Subject: whitespace fixes --- docs/narr/templates.rst | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 24973f253..46d836813 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -318,7 +318,9 @@ template renderer: def my_view(request): return {'foo':1, 'bar':2} -.. note:: You do not need to supply the ``request`` value as a key +.. note:: + + You do not need to supply the ``request`` value as a key in the dictionary result returned from a renderer-configured view callable. :app:`Pyramid` automatically supplies this value for you so that the "most correct" system values are provided to @@ -424,9 +426,11 @@ appear immediately without needing to restart the application process. environment so that a change to a template will be automatically detected, and the template will be reloaded on the next rendering. -.. warning:: Auto-template-reload behavior is not recommended for - production sites as it slows rendering slightly; it's - usually only desirable during development. +.. warning:: + + Auto-template-reload behavior is not recommended for + production sites as it slows rendering slightly; it's + usually only desirable during development. In order to turn on automatic reloading of templates, you can use an environment variable, or a configuration file setting. @@ -437,18 +441,18 @@ variable set to ``1``, For example: .. code-block:: text - $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini + $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini To use a setting in the application ``.ini`` file for the same purpose, set the ``pyramid.reload_templates`` key to ``true`` within the application's configuration section, e.g.: .. code-block:: ini - :linenos: + :linenos: - [app:main] - use = egg:MyProject - pyramid.reload_templates = true + [app:main] + use = egg:MyProject + pyramid.reload_templates = true .. index:: single: template system bindings -- cgit v1.2.3 From b9ce00bee0b6f1f5b0174960f2087a418c1488a7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 22:57:46 -0500 Subject: move templating bindings back into the templating chapter --- docs/narr/renderers.rst | 38 +++++--------------------------------- docs/narr/templates.rst | 27 ++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 8de3cd29d..8afc9c4ab 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -128,6 +128,11 @@ Built-In Renderers Several built-in renderers exist in :app:`Pyramid`. These renderers can be used in the ``renderer`` attribute of view configurations. +.. note:: + + Bindings for officially supported templating languages can be found + at :ref:`available_template_system_bindings`. + .. index:: pair: renderer; string @@ -364,39 +369,6 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. -.. index:: - single: template system bindings - single: Chameleon - single: Jinja2 - single: Mako - -.. _available_template_system_bindings: - -Available Add-On Template System Bindings ------------------------------------------ - -The Pylons Project maintains several packages providing bindings to different -templating languages including the following: - -+------------------------------+------------------------------+ -| Template Language | Pyramid Bindings | -+==============================+==============================+ -| Chameleon_ | pyramid_chameleon_ | -+------------------------------+------------------------------+ -| Jinja2_ | pyramid_jinja2_ | -+------------------------------+------------------------------+ -| Mako_ | pyramid_mako_ | -+------------------------------+------------------------------+ - -.. _Chameleon: http://chameleon.readthedocs.org/en/latest/ -.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon - -.. _Jinja2: http://jinja.pocoo.org/docs/ -.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 - -.. _Mako: http://www.makotemplates.org/ -.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako - .. index:: single: response headers (from a renderer) single: renderer response headers diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 46d836813..af8f9150a 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -456,16 +456,33 @@ application's configuration section, e.g.: .. index:: single: template system bindings + single: Chameleon single: Jinja2 + single: Mako .. _available_template_system_bindings: Available Add-On Template System Bindings ----------------------------------------- -Jinja2 template bindings are available for :app:`Pyramid` in the -``pyramid_jinja2`` package. You can get the latest release of -this package from the -`Python package index `_ -(pypi). +The Pylons Project maintains several packages providing bindings to different +templating languages including the following: ++------------------------------+------------------------------+ +| Template Language | Pyramid Bindings | ++==============================+==============================+ +| Chameleon_ | pyramid_chameleon_ | ++------------------------------+------------------------------+ +| Jinja2_ | pyramid_jinja2_ | ++------------------------------+------------------------------+ +| Mako_ | pyramid_mako_ | ++------------------------------+------------------------------+ + +.. _Chameleon: http://chameleon.readthedocs.org/en/latest/ +.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon + +.. _Jinja2: http://jinja.pocoo.org/docs/ +.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 + +.. _Mako: http://www.makotemplates.org/ +.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako -- cgit v1.2.3 From 5fc89304910fb3bdacae8674c71ae37843f2d001 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 21:58:44 -0600 Subject: Re-enable two tests using JSON renderer instead of Chameleon --- pyramid/tests/test_config/test_views.py | 95 +++++++++++++++++---------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 02afc38cd..876145b8a 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1842,45 +1842,47 @@ class TestViewsConfigurationMixin(unittest.TestCase): result = view(None, request) self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2') -# def test_add_notfound_view_with_renderer(self): -# from zope.interface import implementedBy -# from pyramid.interfaces import IRequest -# from pyramid.httpexceptions import HTTPNotFound -# config = self._makeOne(autocommit=True) -# view = lambda *arg: {} -# config.add_notfound_view( -# view, -# renderer='pyramid.tests.test_config:files/minimal.pt') -# config.begin() -# try: # chameleon depends on being able to find a threadlocal registry -# request = self._makeRequest(config) -# view = self._getViewCallable(config, -# ctx_iface=implementedBy(HTTPNotFound), -# request_iface=IRequest) -# result = view(None, request) -# finally: -# config.end() -# self.assertTrue(b'div' in result.body) -# -# def test_add_forbidden_view_with_renderer(self): -# from zope.interface import implementedBy -# from pyramid.interfaces import IRequest -# from pyramid.httpexceptions import HTTPForbidden -# config = self._makeOne(autocommit=True) -# view = lambda *arg: {} -# config.add_forbidden_view( -# view, -# renderer='pyramid.tests.test_config:files/minimal.pt') -# config.begin() -# try: # chameleon requires a threadlocal registry -# request = self._makeRequest(config) -# view = self._getViewCallable(config, -# ctx_iface=implementedBy(HTTPForbidden), -# request_iface=IRequest) -# result = view(None, request) -# finally: -# config.end() -# self.assertTrue(b'div' in result.body) + def test_add_notfound_view_with_renderer(self): + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.httpexceptions import HTTPNotFound + config = self._makeOne(autocommit=True) + view = lambda *arg: {} + config.introspection = False + config.add_notfound_view( + view, + renderer='json') + config.begin() + try: # chameleon depends on being able to find a threadlocal registry + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPNotFound), + request_iface=IRequest) + result = view(None, request) + finally: + config.end() + self.assertEqual("{}", result.body) + + def test_add_forbidden_view_with_renderer(self): + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.httpexceptions import HTTPForbidden + config = self._makeOne(autocommit=True) + view = lambda *arg: {} + config.introspection = False + config.add_forbidden_view( + view, + renderer='json') + config.begin() + try: # chameleon requires a threadlocal registry + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPForbidden), + request_iface=IRequest) + result = view(None, request) + finally: + config.end() + self.assertEqual("{}", result.body) def test_set_view_mapper(self): from pyramid.interfaces import IViewMapperFactory @@ -3847,9 +3849,18 @@ class Test_view_description(unittest.TestCase): class DummyRegistry: pass +from zope.interface import implementer +from pyramid.interfaces import IResponse +@implementer(IResponse) +class DummyResponse(object): + content_type = None + default_content_type = None + class DummyRequest: subpath = () matchdict = None + response = DummyResponse() + def __init__(self, environ=None): if environ is None: environ = {} @@ -3860,12 +3871,6 @@ class DummyRequest: class DummyContext: pass -from zope.interface import implementer -from pyramid.interfaces import IResponse -@implementer(IResponse) -class DummyResponse(object): - pass - class DummyAccept(object): def __init__(self, *matches): self.matches = list(matches) -- cgit v1.2.3 From 89917f6e0323777bf8fa2c94ae81c7ebf6ad7a6d Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 22:02:44 -0600 Subject: Remove unnecessary try/finally --- pyramid/tests/test_config/test_views.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 876145b8a..5ae97215e 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1853,14 +1853,11 @@ class TestViewsConfigurationMixin(unittest.TestCase): view, renderer='json') config.begin() - try: # chameleon depends on being able to find a threadlocal registry - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPNotFound), - request_iface=IRequest) - result = view(None, request) - finally: - config.end() + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPNotFound), + request_iface=IRequest) + result = view(None, request) self.assertEqual("{}", result.body) def test_add_forbidden_view_with_renderer(self): @@ -1873,15 +1870,11 @@ class TestViewsConfigurationMixin(unittest.TestCase): config.add_forbidden_view( view, renderer='json') - config.begin() - try: # chameleon requires a threadlocal registry - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPForbidden), - request_iface=IRequest) - result = view(None, request) - finally: - config.end() + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPForbidden), + request_iface=IRequest) + result = view(None, request) self.assertEqual("{}", result.body) def test_set_view_mapper(self): -- cgit v1.2.3 From fbdc3a01842e9067478dbf95ba8cde4e31bbb174 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:22:35 -0500 Subject: s/view execution machinery/generating a response/ --- CHANGES.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7d06999d6..6392c7b3b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,11 +10,10 @@ Backwards Incompatibilities - ``request.response`` will no longer be mutated when using the ``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 called by the view execution machinery; it was a bug when it was - done as a side effect of calling ``pyramid.renderers.render()``. + ``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 ``pyramid.renderers.render()``. 1.5a1 (2013-08-30) ================== -- cgit v1.2.3 From f1aaf1577dfeb9e094a5a9d7130984b95531d5cb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:40:27 -0500 Subject: remove some more mako/chameleon references --- docs/narr/templates.rst | 50 ++++++++++++++----------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index af8f9150a..3e19f7198 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -56,19 +56,8 @@ In this case, this is the directory containing the file that defines the ``sample_view`` function. Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive letter -prefix on Windows. - -.. warning:: - - Only :term:`Chameleon` templates support defining a renderer for a - template relative to the location of the module where the view callable is - defined. Mako templates, and other templating system bindings work - differently. In particular, Mako templates use a "lookup path" as defined - by the ``mako.directories`` configuration file instead of treating - relative paths as relative to the current view module. See - :ref:`mako_templates`. - -The path can alternately be a :term:`asset specification` in the form +prefix on Windows. The path can alternately be a +:term:`asset specification` in the form ``some.dotted.package_name:relative/path``. This makes it possible to address template assets which live in another package. For example: @@ -86,16 +75,9 @@ An asset specification points at a file within a Python *package*. In this case, it points at a file named ``foo.pt`` within the ``templates`` directory of the ``mypackage`` package. Using a asset specification instead of a relative template name is usually -a good idea, because calls to ``render_to_response`` using asset -specifications will continue to work properly if you move the code -containing them around. - -.. note:: - - Mako templating system bindings also respect absolute asset - specifications as an argument to any of the ``render*`` commands. If a - template name defines a ``:`` (colon) character and is not an absolute - path, it is treated as an absolute asset specification. +a good idea, because calls to :func:`~pyramid.renderers.render_to_response` +using asset specifications will continue to work properly if you move the +code containing them around. In the examples above we pass in a keyword argument named ``request`` representing the current :app:`Pyramid` request. Passing a request @@ -143,8 +125,8 @@ import its API functions into your views module, use those APIs to generate a string, then return that string as the body of a :app:`Pyramid` :term:`Response` object. -For example, here's an example of using "raw" `Mako -`_ from within a :app:`Pyramid` :term:`view`: +For example, here's an example of using "raw" Mako_ from within a +:app:`Pyramid` :term:`view`: .. code-block:: python :linenos: @@ -159,10 +141,10 @@ For example, here's an example of using "raw" `Mako return response You probably wouldn't use this particular snippet in a project, because it's -easier to use the Mako renderer bindings which already exist in -:app:`Pyramid`. But if your favorite templating system is not supported as a -renderer extension for :app:`Pyramid`, you can create your own simple -combination as shown above. +easier to use the supported +:ref:`Mako bindings `. But if your +favorite templating system is not supported as a renderer extension for +:app:`Pyramid`, you can create your own simple combination as shown above. .. note:: @@ -277,8 +259,8 @@ You can define more values which will be passed to every template executed as a result of rendering by defining :term:`renderer globals`. What any particular renderer does with these system values is up to the -renderer itself, but most template renderers, including Chameleon and Mako -renderers, make these names available as top-level template variables. +renderer itself, but most template renderers make these names available as +top-level template variables. .. index:: pair: renderer; templates @@ -348,11 +330,7 @@ it possible to address template assets which live in another package. Not just any template from any arbitrary templating system may be used as a renderer. Bindings must exist specifically for :app:`Pyramid` to use a -templating language template as a renderer. Currently, :app:`Pyramid` has -built-in support for two Chameleon templating languages: ZPT and text, and -the Mako templating system. See :ref:`built_in_renderers` for a discussion -of their details. :app:`Pyramid` also supports the use of :term:`Jinja2` -templates as renderers. See :ref:`available_template_system_bindings`. +templating language template as a renderer. .. sidebar:: Why Use A Renderer via View Configuration -- cgit v1.2.3 From f7d60e437bec1d8a63d477732c0058f3e4ebb697 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 6 Sep 2013 00:46:50 -0400 Subject: shorten test output in travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 00c293046..9d4324ff8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ python: - pypy - 3.2 -script: python setup.py test +script: python setup.py test -q notifications: email: -- cgit v1.2.3 From 2207ed5c82dfd8c259f6032ff84eb8998be40fa8 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:51:03 -0500 Subject: update the MyProject example app to use pyramid_chameleon --- docs/narr/MyProject/myproject/__init__.py | 1 + docs/narr/MyProject/setup.py | 1 + docs/narr/project.rst | 17 ++++++++++------- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py index 6c512f52f..ad5ecbc6f 100644 --- a/docs/narr/MyProject/myproject/__init__.py +++ b/docs/narr/MyProject/myproject/__init__.py @@ -5,6 +5,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index 6969c73e7..a23f46c91 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_debugtoolbar', 'waitress', ] diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 52f13d5a8..f3050f805 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -570,8 +570,8 @@ adding more settings to this section. The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a :app:`Pyramid` -specific setting which is passed into the framework. If it -exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako` -template changes will not require an application restart to be detected. See +exists, and its value is ``true``, supported template changes will not +require an application restart to be detected. See :ref:`reload_templates_section` for more information. .. warning:: The ``pyramid.reload_templates`` option should be turned off for @@ -818,7 +818,7 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. @@ -826,17 +826,20 @@ also informs Python that the directory which contains it is a *package*. Line 7 creates an instance of a :term:`Configurator`. - Line 8 registers a static view, which will serve up the files from the + Line 8 adds support for Chameleon templating bindings, allowing us to + specify renderers with the ``.pt`` extension. + + Line 9 registers a static view, which will serve up the files from the ``myproject:static`` :term:`asset specification` (the ``static`` directory of the ``myproject`` package). - Line 9 adds a :term:`route` to the configuration. This route is later + Line 10 adds a :term:`route` to the configuration. This route is later used by a view in the ``views`` module. - Line 10 calls ``config.scan()``, which picks up view registrations declared + Line 11 calls ``config.scan()``, which picks up view registrations declared elsewhere in the package (in this case, in the ``views.py`` module). - Line 11 returns a :term:`WSGI` application to the caller of the function + Line 12 returns a :term:`WSGI` application to the caller of the function (Pyramid's pserve). .. index:: -- cgit v1.2.3 From ac681bc83778443bcb70b9c1ea370368044614fb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:56:46 -0500 Subject: remove chameleon refs from asset specs --- docs/narr/assets.rst | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 26b3e3a92..b0a8d18b0 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -227,14 +227,14 @@ API to generate them for you. For example: .. code-block:: python :linenos: - from pyramid.chameleon_zpt import render_template_to_response + from pyramid.renderers import render_to_response def my_view(request): css_url = request.static_url('mypackage:assets/1/foo.css') js_url = request.static_url('mypackage:assets/2/foo.js') - return render_template_to_response('templates/my_template.pt', - css_url = css_url, - js_url = js_url) + return render_to_response('templates/my_template.pt', + dict(css_url=css_url, js_url=js_url), + request=request) If the request "application URL" of the running system is ``http://example.com``, the ``css_url`` generated above would be: @@ -336,7 +336,9 @@ your application root as below. from pyramid.static import static_view static_view = static_view('/path/to/static/dir', use_subpath=True) -.. note:: For better cross-system flexibility, use an :term:`asset +.. note:: + + For better cross-system flexibility, use an :term:`asset specification` as the argument to :class:`~pyramid.static.static_view` instead of a physical absolute filesystem path, e.g. ``mypackage:static`` instead of ``/path/to/mypackage/static``. @@ -432,9 +434,9 @@ feature, a :term:`Configurator` API exists named :meth:`pyramid.config.Configurator.override_asset`. This API allows you to *override* the following kinds of assets defined in any Python package: -- Individual :term:`Chameleon` templates. +- Individual template files. -- A directory containing multiple Chameleon templates. +- A directory containing multiple template files. - Individual static files served up by an instance of the ``pyramid.static.static_view`` helper class. @@ -460,8 +462,8 @@ can override a single asset. For example: :linenos: config.override_asset( - to_override='some.package:templates/mytemplate.pt', - override_with='another.package:othertemplates/anothertemplate.pt') + to_override='some.package:templates/mytemplate.pt', + override_with='another.package:othertemplates/anothertemplate.pt') The string value passed to both ``to_override`` and ``override_with`` sent to the ``override_asset`` API is called an :term:`asset specification`. The -- cgit v1.2.3 From 6ef10d66720c0965764cca1a743db3997621392a Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 23:05:41 -0600 Subject: Fix DummyRequest so that response is created each time Due to only creating the DummyRequest once various mutations were bleeding across various different tests. With hilarious results. --- pyramid/tests/test_config/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 5ae97215e..00d04de7c 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -3852,7 +3852,6 @@ class DummyResponse(object): class DummyRequest: subpath = () matchdict = None - response = DummyResponse() def __init__(self, environ=None): if environ is None: @@ -3860,6 +3859,7 @@ class DummyRequest: self.environ = environ self.params = {} self.cookies = {} + self.response = DummyResponse() class DummyContext: pass -- cgit v1.2.3 From 42afb08e143871feb847635d559400a60239c850 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 5 Sep 2013 23:14:06 -0600 Subject: Fix tests on Python 3.x --- pyramid/tests/test_config/test_views.py | 68 ++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 00d04de7c..88f740323 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -47,7 +47,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): def __init__(self, info): self.__class__.info = info def __call__(self, *arg): - return 'Hello!' + return b'Hello!' config.registry.registerUtility(Renderer, IRendererFactory, name=name) return Renderer @@ -264,7 +264,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') - + def test_add_view_as_instance_requestonly(self): from pyramid.renderers import null_renderer class AView: @@ -994,7 +994,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): pass foo = Foo() bar = Bar() - + from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier @@ -1056,7 +1056,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): def __init__(self, *arg, **kw): pass def __call__(self, *arg, **kw): - return 'moo' + return b'moo' config.add_renderer(None, moo) config.add_view(view=view) wrapper = self._getViewCallable(config) @@ -1200,7 +1200,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): request = self._makeRequest(config) request.method = 'HEAD' self.assertEqual(wrapper(None, request), 'OK') - + def test_add_view_with_request_param_noval_true(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' @@ -1587,7 +1587,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): context = DummyContext() request = self._makeRequest(config) self.assertRaises(PredicateMismatch, wrapper, context, request) - + def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self): from pyramid.renderers import null_renderer class view(object): @@ -1665,7 +1665,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): def __init__(self, view): pass def __call__(self, *arg, **kw): - return 'foo' + return b'foo' def view(request): return 'OK' config = self._makeOne() @@ -1727,7 +1727,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config.add_static_view('static', static_path) self.assertEqual(info.added, [(config, 'static', static_path, {})]) - + def test_add_forbidden_view(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy @@ -1821,7 +1821,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): config = self._makeOne(autocommit=True) self.assertRaises(ConfigurationError, config.add_notfound_view, http_cache='foo') - + def test_add_notfound_view_append_slash(self): from pyramid.response import Response from pyramid.renderers import null_renderer @@ -1841,7 +1841,15 @@ class TestViewsConfigurationMixin(unittest.TestCase): request_iface=IRequest) result = view(None, request) self.assertEqual(result.location, '/scriptname/foo/?a=1&b=2') - + + # Since Python 3 has to be all cool and fancy and different... + def _assertBody(self, response, value): + from pyramid.compat import text_type + if isinstance(value, text_type): + self.assertEqual(response.text, value) + else: + self.assertEqual(response.body, value) + def test_add_notfound_view_with_renderer(self): from zope.interface import implementedBy from pyramid.interfaces import IRequest @@ -1852,13 +1860,12 @@ class TestViewsConfigurationMixin(unittest.TestCase): config.add_notfound_view( view, renderer='json') - config.begin() request = self._makeRequest(config) view = self._getViewCallable(config, ctx_iface=implementedBy(HTTPNotFound), request_iface=IRequest) result = view(None, request) - self.assertEqual("{}", result.body) + self._assertBody(result, '{}') def test_add_forbidden_view_with_renderer(self): from zope.interface import implementedBy @@ -1875,7 +1882,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): ctx_iface=implementedBy(HTTPForbidden), request_iface=IRequest) result = view(None, request) - self.assertEqual("{}", result.body) + self._assertBody(result, '{}') def test_set_view_mapper(self): from pyramid.interfaces import IViewMapperFactory @@ -2225,12 +2232,12 @@ class TestViewDeriver(unittest.TestCase): def tearDown(self): self.config = None - + def _makeOne(self, **kw): kw['registry'] = self.config.registry from pyramid.config.views import ViewDeriver return ViewDeriver(**kw) - + def _makeRequest(self): request = DummyRequest() request.registry = self.config.registry @@ -2259,7 +2266,7 @@ class TestViewDeriver(unittest.TestCase): result(None, None) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], 'Could not convert return value of the view callable function ' 'pyramid.tests.test_config.test_views.view into a response ' 'object. The value returned was None. You may have forgotten ' @@ -2278,7 +2285,7 @@ class TestViewDeriver(unittest.TestCase): result(None, None) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], "Could not convert return value of the view callable function " "pyramid.tests.test_config.test_views.view into a response " "object. The value returned was {'a': 1}. You may have " @@ -2286,7 +2293,7 @@ class TestViewDeriver(unittest.TestCase): ) else: # pragma: no cover raise AssertionError - + def test_instance_returns_non_adaptable(self): class AView(object): def __call__(self, request): @@ -2345,7 +2352,7 @@ class TestViewDeriver(unittest.TestCase): result(None, request) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], 'Could not convert return value of the view callable ' 'method __call__ of ' 'class pyramid.tests.test_config.test_views.AView into a ' @@ -2369,7 +2376,7 @@ class TestViewDeriver(unittest.TestCase): result(None, request) except ValueError as e: self.assertEqual( - e.args[0], + e.args[0], 'Could not convert return value of the view callable ' 'method theviewmethod of ' 'class pyramid.tests.test_config.test_views.AView into a ' @@ -2378,7 +2385,7 @@ class TestViewDeriver(unittest.TestCase): ) else: # pragma: no cover raise AssertionError - + def test_requestonly_function(self): response = DummyResponse() def view(request): @@ -2412,7 +2419,7 @@ class TestViewDeriver(unittest.TestCase): self.assertEqual(value, 'OK') self.assertEqual(system['request'], request) self.assertEqual(system['context'], context) - return 'moo' + return b'moo' return inner def view(request): return 'OK' @@ -2929,7 +2936,7 @@ class TestViewDeriver(unittest.TestCase): 'predicate mismatch for view myview (pred2)') else: # pragma: no cover raise AssertionError - + def test_with_predicates_all(self): response = DummyResponse() view = lambda *arg: response @@ -3240,7 +3247,7 @@ class TestViewDeriver(unittest.TestCase): expires = parse_httpdate(headers['Expires']) assert_similar_datetime(expires, when) self.assertEqual(headers['Cache-Control'], 'max-age=3600') - + def test_http_cached_view_timedelta(self): import datetime from pyramid.response import Response @@ -3336,7 +3343,7 @@ class TestViewDeriver(unittest.TestCase): class TestDefaultViewMapper(unittest.TestCase): def setUp(self): self.config = testing.setUp() - self.registry = self.config.registry + self.registry = self.config.registry def tearDown(self): del self.registry @@ -3598,7 +3605,7 @@ class TestStaticURLInfo(unittest.TestCase): def _getTargetClass(self): from pyramid.config.views import StaticURLInfo return StaticURLInfo - + def _makeOne(self): return self._getTargetClass()() @@ -3825,19 +3832,19 @@ class Test_view_description(unittest.TestCase): def _callFUT(self, view): from pyramid.config.views import view_description return view_description(view) - + def test_with_text(self): def view(): pass view.__text__ = 'some text' result = self._callFUT(view) self.assertEqual(result, 'some text') - + def test_without_text(self): def view(): pass result = self._callFUT(view) - self.assertEqual(result, + self.assertEqual(result, 'function pyramid.tests.test_config.test_views.view') - + class DummyRegistry: pass @@ -3848,6 +3855,7 @@ from pyramid.interfaces import IResponse class DummyResponse(object): content_type = None default_content_type = None + body = None class DummyRequest: subpath = () -- cgit v1.2.3 From 404b28ba2efb02d93777a3e01fd602c96af8c077 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 6 Sep 2013 00:02:46 -0500 Subject: update the code in the wiki and wiki2 tutorials to use pyramid_chameleon --- docs/tutorials/wiki/basiclayout.rst | 9 ++++++--- docs/tutorials/wiki/src/authorization/setup.py | 1 + .../tutorials/wiki/src/authorization/tutorial/__init__.py | 1 + docs/tutorials/wiki/src/basiclayout/setup.py | 1 + docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py | 1 + docs/tutorials/wiki/src/models/setup.py | 1 + docs/tutorials/wiki/src/models/tutorial/__init__.py | 1 + docs/tutorials/wiki/src/tests/setup.py | 1 + docs/tutorials/wiki/src/tests/tutorial/__init__.py | 1 + docs/tutorials/wiki/src/views/setup.py | 1 + docs/tutorials/wiki/src/views/tutorial/__init__.py | 1 + docs/tutorials/wiki/tests.rst | 4 ++-- docs/tutorials/wiki2/authorization.rst | 4 ++-- docs/tutorials/wiki2/basiclayout.rst | 15 +++++++++++---- docs/tutorials/wiki2/definingviews.rst | 4 ++-- docs/tutorials/wiki2/src/authorization/setup.py | 5 +++-- .../wiki2/src/authorization/tutorial/__init__.py | 1 + docs/tutorials/wiki2/src/basiclayout/setup.py | 5 +++-- docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py | 1 + docs/tutorials/wiki2/src/models/setup.py | 5 +++-- docs/tutorials/wiki2/src/models/tutorial/__init__.py | 1 + docs/tutorials/wiki2/src/tests/setup.py | 5 +++-- docs/tutorials/wiki2/src/tests/tutorial/__init__.py | 1 + docs/tutorials/wiki2/src/views/setup.py | 5 +++-- docs/tutorials/wiki2/src/views/tutorial/__init__.py | 1 + docs/tutorials/wiki2/tests.rst | 4 ++-- 26 files changed, 55 insertions(+), 25 deletions(-) diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst index 25ac9aabd..cdf52b73e 100644 --- a/docs/tutorials/wiki/basiclayout.rst +++ b/docs/tutorials/wiki/basiclayout.rst @@ -34,7 +34,10 @@ point happens to be the ``main`` function within the file named factory` and the settings keywords parsed by :term:`PasteDeploy`. The root factory is named ``root_factory``. -#. *Line 15*. Register a "static view" which answers requests whose URL path +#. *Line 15*. Include support for the :term:`Chameleon` template rendering + bindings, allowing us to use the ``.pt`` templates. + +#. *Line 16*. Register a "static view" which answers requests whose URL path start with ``/static`` using the :meth:`pyramid.config.Configurator.add_static_view` method. This statement registers a view that will serve up static assets, such as CSS @@ -47,7 +50,7 @@ point happens to be the ``main`` function within the file named package. Alternatively the scaffold could have used an *absolute* asset specification as the path (``tutorial:static``). -#. *Line 16*. Perform a :term:`scan`. A scan will find :term:`configuration +#. *Line 17*. Perform a :term:`scan`. A scan will find :term:`configuration decoration`, such as view configuration decorators (e.g., ``@view_config``) in the source code of the ``tutorial`` package and will take actions based on these decorators. We don't pass any arguments to @@ -56,7 +59,7 @@ point happens to be the ``main`` function within the file named The scaffold could have equivalently said ``config.scan('tutorial')``, but it chose to omit the package name argument. -#. *Line 17*. Use the +#. *Line 18*. Use the :meth:`pyramid.config.Configurator.make_wsgi_app` method to return a :term:`WSGI` application. diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py index 5d87fedbf..5ab4f73cd 100644 --- a/docs/tutorials/wiki/src/authorization/setup.py +++ b/docs/tutorials/wiki/src/authorization/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_zodbconn', 'transaction', 'pyramid_tm', diff --git a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py index 8ea8f8fa3..39b94abd1 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py @@ -21,6 +21,7 @@ def main(global_config, **settings): config = Configurator(root_factory=root_factory, settings=settings) config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py index 75ba02611..da79881ab 100644 --- a/docs/tutorials/wiki/src/basiclayout/setup.py +++ b/docs/tutorials/wiki/src/basiclayout/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_zodbconn', 'transaction', 'pyramid_tm', diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py index c3bb87a62..f2a86df47 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py @@ -12,6 +12,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=root_factory, settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py index 75ba02611..da79881ab 100644 --- a/docs/tutorials/wiki/src/models/setup.py +++ b/docs/tutorials/wiki/src/models/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_zodbconn', 'transaction', 'pyramid_tm', diff --git a/docs/tutorials/wiki/src/models/tutorial/__init__.py b/docs/tutorials/wiki/src/models/tutorial/__init__.py index c3bb87a62..f2a86df47 100644 --- a/docs/tutorials/wiki/src/models/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/models/tutorial/__init__.py @@ -12,6 +12,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=root_factory, settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py index 5ff7b545c..2e7ed2398 100644 --- a/docs/tutorials/wiki/src/tests/setup.py +++ b/docs/tutorials/wiki/src/tests/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_zodbconn', 'transaction', 'pyramid_tm', diff --git a/docs/tutorials/wiki/src/tests/tutorial/__init__.py b/docs/tutorials/wiki/src/tests/tutorial/__init__.py index 8ea8f8fa3..bd3c5619f 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/tests/tutorial/__init__.py @@ -19,6 +19,7 @@ def main(global_config, **settings): 'sosecret', callback=groupfinder, hashalg='sha512') authz_policy = ACLAuthorizationPolicy() config = Configurator(root_factory=root_factory, settings=settings) + config.include('pyramid_chameleon') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) config.add_static_view('static', 'static', cache_max_age=3600) diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py index 5d87fedbf..5ab4f73cd 100644 --- a/docs/tutorials/wiki/src/views/setup.py +++ b/docs/tutorials/wiki/src/views/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_zodbconn', 'transaction', 'pyramid_tm', diff --git a/docs/tutorials/wiki/src/views/tutorial/__init__.py b/docs/tutorials/wiki/src/views/tutorial/__init__.py index c3bb87a62..f2a86df47 100644 --- a/docs/tutorials/wiki/src/views/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/views/tutorial/__init__.py @@ -12,6 +12,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=root_factory, settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index e40dc286b..e724f3e18 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -59,8 +59,8 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``. .. literalinclude:: src/tests/setup.py :linenos: :language: python - :lines: 11-21 - :emphasize-lines: 10 + :lines: 11-22 + :emphasize-lines: 11 After we've added a dependency on WebTest in ``setup.py``, we need to rerun ``setup.py develop`` to get WebTest installed into our virtualenv. Assuming diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 01c301e74..df2e9e149 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -203,7 +203,7 @@ Go back to ``tutorial/tutorial/__init__.py`` and add these two routes: .. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 30-31 + :lines: 31-32 :linenos: :language: python @@ -329,7 +329,7 @@ when we're done: .. literalinclude:: src/authorization/tutorial/__init__.py :linenos: - :emphasize-lines: 2-3,7,21-23,25-27,30-31 + :emphasize-lines: 2-3,7,21-23,25-27,31-32 :language: python (Only the highlighted lines need to be added.) diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 0193afab4..c8e6723b3 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -82,11 +82,18 @@ dictionary of settings parsed from the ``.ini`` file, which contains deployment-related values such as ``pyramid.reload_templates``, ``db_string``, etc. +Next, include :term:`Chameleon` templating bindings so that we can use +renderers with the ``.pt`` extension within our project. + + .. literalinclude:: src/basiclayout/tutorial/__init__.py + :lines: 17 + :language: py + ``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with two arguments: ``static`` (the name), and ``static`` (the path): .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 17 + :lines: 18 :language: py This registers a static resource view which will match any URL that starts @@ -104,7 +111,7 @@ via the :meth:`pyramid.config.Configurator.add_route` method that will be used when the URL is ``/``: .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 18 + :lines: 19 :language: py Since this route has a ``pattern`` equalling ``/`` it is the route that will @@ -118,7 +125,7 @@ view configuration will be registered, which will allow one of our application URLs to be mapped to some code. .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 19 + :lines: 20 :language: py Finally, ``main`` is finished configuring things, so it uses the @@ -126,7 +133,7 @@ Finally, ``main`` is finished configuring things, so it uses the :term:`WSGI` application: .. literalinclude:: src/basiclayout/tutorial/__init__.py - :lines: 20 + :lines: 21 :language: py View Declarations via ``views.py`` diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index a1e2313f3..ea49d4733 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -30,7 +30,7 @@ Open ``tutorial/setup.py`` and edit it to look like the following: .. literalinclude:: src/views/setup.py :linenos: :language: python - :emphasize-lines: 19 + :emphasize-lines: 20 (Only the highlighted line needs to be added.) @@ -335,7 +335,7 @@ something like: .. literalinclude:: src/views/tutorial/__init__.py :linenos: :language: python - :emphasize-lines: 18-21 + :emphasize-lines: 19-22 (The highlighted lines are the ones that need to be added or edited.) diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index e8fa8f396..09bd63d33 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index d08e55bf9..2ada42171 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -25,6 +25,7 @@ def main(global_config, **settings): root_factory='tutorial.models.RootFactory') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index e7d318128..15e7e5923 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', ] diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py index aac7c5e69..867049e4f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py @@ -14,6 +14,7 @@ def main(global_config, **settings): DBSession.configure(bind=engine) Base.metadata.bind = engine config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py index e7d318128..15e7e5923 100644 --- a/docs/tutorials/wiki2/src/models/setup.py +++ b/docs/tutorials/wiki2/src/models/setup.py @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', ] diff --git a/docs/tutorials/wiki2/src/models/tutorial/__init__.py b/docs/tutorials/wiki2/src/models/tutorial/__init__.py index aac7c5e69..867049e4f 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/models/tutorial/__init__.py @@ -14,6 +14,7 @@ def main(global_config, **settings): DBSession.configure(bind=engine) Base.metadata.bind = engine config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py index c3da36b39..d8486e462 100644 --- a/docs/tutorials/wiki2/src/tests/setup.py +++ b/docs/tutorials/wiki2/src/tests/setup.py @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py index d08e55bf9..cee89184b 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py @@ -23,6 +23,7 @@ def main(global_config, **settings): authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, root_factory='tutorial.models.RootFactory') + config.include('pyramid_chameleon') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) config.add_static_view('static', 'static', cache_max_age=3600) diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py index e8fa8f396..09bd63d33 100644 --- a/docs/tutorials/wiki2/src/views/setup.py +++ b/docs/tutorials/wiki2/src/views/setup.py @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki2/src/views/tutorial/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/__init__.py index c95bfdbf8..37cae1997 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/views/tutorial/__init__.py @@ -14,6 +14,7 @@ def main(global_config, **settings): DBSession.configure(bind=engine) Base.metadata.bind = engine config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('view_page', '/{pagename}') diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index 33b5d35c1..9aca0c5b7 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -54,8 +54,8 @@ Change the ``requires`` list in ``setup.py`` to include ``WebTest``. .. literalinclude:: src/tests/setup.py :linenos: :language: python - :lines: 11-21 - :emphasize-lines: 10 + :lines: 11-22 + :emphasize-lines: 11 After we've added a dependency on WebTest in ``setup.py``, we need to rerun ``setup.py develop`` to get WebTest installed into our virtualenv. Assuming -- cgit v1.2.3 From 70784a80c07cc831ab20c2e22e82b14afe834feb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 6 Sep 2013 00:38:30 -0500 Subject: fix some more broken references --- docs/quick_tour.rst | 7 ++++--- docs/tutorials/wiki/definingviews.rst | 4 ++-- docs/tutorials/wiki2/definingviews.rst | 4 ++-- docs/whatsnew-1.0.rst | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index e55730a0d..9a354b009 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -250,8 +250,9 @@ Python, but instead, will use a templating language. Pyramid doesn't mandate a particular database system, form library, etc. It encourages replaceability. This applies equally to templating, which is fortunate: developers have strong views about template -languages. That said, Pyramid bundles Chameleon and Mako, -so in this step, let's use Chameleon as an example: +languages. That said, the Pylons Project officially supports bindings for +Chameleon, Jinja2 and Mako, so in this step, let's use Chameleon as an +example: .. literalinclude:: quick_tour/templating/views.py :start-after: Start View 1 @@ -271,7 +272,7 @@ we can use ``name`` as a variable in our template via .. seealso:: See Also: :doc:`../narr/templates`, :ref:`debugging_templates`, and - :ref:`mako_templates` + :ref:`available_template_system_bindings` Templating With ``jinja2`` ========================== diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index 23ee142af..e06468267 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -306,9 +306,9 @@ by the view (row 45). The view will use the ``body`` and none of our tutorial views return in their dictionary. ``request`` is one of several names that are available "by default" in a template when a template - renderer is used. See :ref:`chameleon_template_renderers` for + renderer is used. See :ref:`renderer_system_values` for information about other names that are available by default - when a Chameleon template is used as a renderer. + when a template is used as a renderer. Static Assets ------------- diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index ea49d4733..49dbed50f 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -272,9 +272,9 @@ by the view (row 45). The view will use the ``body`` and none of our tutorial views return in their dictionary. ``request`` is one of several names that are available "by default" in a template when a template - renderer is used. See :ref:`chameleon_template_renderers` for + renderer is used. See :ref:`renderer_system_values` for information about other names that are available by default - when a Chameleon template is used as a renderer. + when a template is used as a renderer. Static Assets ------------- diff --git a/docs/whatsnew-1.0.rst b/docs/whatsnew-1.0.rst index d1f3046ca..de24838fb 100644 --- a/docs/whatsnew-1.0.rst +++ b/docs/whatsnew-1.0.rst @@ -203,8 +203,8 @@ Mako ~~~~ In addition to Chameleon templating, Pyramid now also provides built-in -support for :term:`Mako` templating. See :ref:`mako_templates` for more -information. +support for :term:`Mako` templating. See +:ref:`available_template_system_bindings` for more information. URL Dispatch ~~~~~~~~~~~~ -- cgit v1.2.3 From b28964373f60cc1e3a07a6a48d6056eef836ff4b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 6 Sep 2013 00:47:04 -0500 Subject: update scaffolds to require pyramid_chameleon --- pyramid/scaffolds/alchemy/+package+/__init__.py | 1 + pyramid/scaffolds/alchemy/setup.py_tmpl | 5 +++-- pyramid/scaffolds/starter/+package+/__init__.py | 1 + pyramid/scaffolds/starter/setup.py_tmpl | 1 + pyramid/scaffolds/zodb/+package+/__init__.py | 1 + pyramid/scaffolds/zodb/setup.py_tmpl | 5 +++-- 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pyramid/scaffolds/alchemy/+package+/__init__.py b/pyramid/scaffolds/alchemy/+package+/__init__.py index aac7c5e69..867049e4f 100644 --- a/pyramid/scaffolds/alchemy/+package+/__init__.py +++ b/pyramid/scaffolds/alchemy/+package+/__init__.py @@ -14,6 +14,7 @@ def main(global_config, **settings): DBSession.configure(bind=engine) Base.metadata.bind = engine config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/pyramid/scaffolds/alchemy/setup.py_tmpl b/pyramid/scaffolds/alchemy/setup.py_tmpl index 69b5faea9..9496b9948 100644 --- a/pyramid/scaffolds/alchemy/setup.py_tmpl +++ b/pyramid/scaffolds/alchemy/setup.py_tmpl @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', ] diff --git a/pyramid/scaffolds/starter/+package+/__init__.py b/pyramid/scaffolds/starter/+package+/__init__.py index 6c512f52f..ad5ecbc6f 100644 --- a/pyramid/scaffolds/starter/+package+/__init__.py +++ b/pyramid/scaffolds/starter/+package+/__init__.py @@ -5,6 +5,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/pyramid/scaffolds/starter/setup.py_tmpl b/pyramid/scaffolds/starter/setup.py_tmpl index c0908d96f..3802c3e23 100644 --- a/pyramid/scaffolds/starter/setup.py_tmpl +++ b/pyramid/scaffolds/starter/setup.py_tmpl @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_debugtoolbar', 'waitress', ] diff --git a/pyramid/scaffolds/zodb/+package+/__init__.py b/pyramid/scaffolds/zodb/+package+/__init__.py index c3bb87a62..f2a86df47 100644 --- a/pyramid/scaffolds/zodb/+package+/__init__.py +++ b/pyramid/scaffolds/zodb/+package+/__init__.py @@ -12,6 +12,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=root_factory, settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/pyramid/scaffolds/zodb/setup.py_tmpl b/pyramid/scaffolds/zodb/setup.py_tmpl index 02789657d..3a6032429 100644 --- a/pyramid/scaffolds/zodb/setup.py_tmpl +++ b/pyramid/scaffolds/zodb/setup.py_tmpl @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'pyramid_zodbconn', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'ZODB3', 'waitress', ] -- cgit v1.2.3 From bd5a7ff20d9bdeaf36ef4154cbb0322696a46e2b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 6 Sep 2013 00:48:24 -0500 Subject: apostrophe --- docs/quick_tour.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 9a354b009..4b23f7858 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -18,7 +18,7 @@ snippets of code to illustrate major concepts. Python Setup ============ -First things first: we need our Python environment in ship-shape. +First thing's first: we need our Python environment in ship-shape. Pyramid encourages standard Python development practices (virtual environments, packaging tools, logging, etc.) so let's get our working area in place. For Python 3.3: -- cgit v1.2.3 From c062d5ace6adedcf0f6434cffc07fb24cc608733 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Thu, 5 Sep 2013 18:09:31 -0400 Subject: Update package_name() to work with namespace pkgs The logic in pyramid.path.package_name() should take into account the fact that namespace packages created by setuptools do not have __init__.py[c] files, and so they have no __file__ attribute. This resolves an issue with WSME (https://bugs.launchpad.net/wsme/+bug/1221201) Change-Id: I39bc32a9c38fa11c4cef22a041077ed9001091be --- CHANGES.txt | 6 ++++++ CONTRIBUTORS.txt | 2 ++ pyramid/path.py | 6 +++++- pyramid/tests/test_path.py | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6392c7b3b..5c058a9c5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,12 @@ Next Release ============ +Bug Fixes +--------- + +- Fix an exception in ``package_name()`` when resolving the package + name for namespace packages. + Backwards Incompatibilities --------------------------- diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 0ddaebf15..1a5b975d7 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -220,3 +220,5 @@ Contributors - Matthew Wilkes, 2013/08/23 - Takahiro Fujiwara, 2013/08/28 + +- Doug Hellmann, 2013/09/06 diff --git a/pyramid/path.py b/pyramid/path.py index eb92ea62b..470e766f8 100644 --- a/pyramid/path.py +++ b/pyramid/path.py @@ -33,8 +33,12 @@ def package_name(pkg_or_module): name of the package itself.""" if pkg_or_module is None or pkg_or_module.__name__ == '__main__': return '__main__' - pkg_filename = pkg_or_module.__file__ pkg_name = pkg_or_module.__name__ + pkg_filename = getattr(pkg_or_module, '__file__', None) + if pkg_filename is None: + # Namespace packages do not have __init__.py* files, + # and so have no __file__ attribute + return pkg_name splitted = os.path.split(pkg_filename) if splitted[-1] in init_names: # it's a package diff --git a/pyramid/tests/test_path.py b/pyramid/tests/test_path.py index a07ebeffa..fd927996a 100644 --- a/pyramid/tests/test_path.py +++ b/pyramid/tests/test_path.py @@ -154,6 +154,12 @@ class TestPackageName(unittest.TestCase): package = DummyPackageOrModule(tests) result = self._callFUT(package) self.assertEqual(result, 'pyramid.tests') + + def test_it_namespace_package(self): + from pyramid import tests + package = DummyNamespacePackage(tests) + result = self._callFUT(package) + self.assertEqual(result, 'pyramid.tests') def test_it_module(self): from pyramid.tests import test_path @@ -558,3 +564,13 @@ class DummyPackageOrModule: if self.raise_exc is not None: raise self.raise_exc self.__dict__[key] = val + +class DummyNamespacePackage: + """Has no __file__ attribute. + """ + + def __init__(self, real_package_or_module): + self.__name__ = real_package_or_module.__name__ + import os + self.package_path = os.path.dirname( + os.path.abspath(real_package_or_module.__file__)) -- cgit v1.2.3 From 816703b7e3a76ed86386e7033b14d2a76b62783b Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 17:58:29 -0600 Subject: Add test to verify renders don't add response to Request We already added a test that verified that a renderer no longer mutated request.response, now we also have a test that verifies that if no response exists, then it won't be touched either. --- pyramid/tests/test_renderers.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index a41345b87..4d40189a5 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -482,6 +482,16 @@ class Test_render(unittest.TestCase): self.assertEqual(result, '{"a": 1}') self.assertEqual(request.response, response) + def test_it_deletes_response(self): + request = testing.DummyRequest() + try: + delattr(request, 'response') + except AttributeError: + pass + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertFalse(hasattr(request, 'request')) + class Test_render_to_response(unittest.TestCase): def setUp(self): self.config = testing.setUp() -- cgit v1.2.3 From c330c17dd3d26eba3667151128d7e0cc2dbc7dd0 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 18:06:59 -0600 Subject: Remove useless function that was used only for Chameleon --- pyramid/config/i18n.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 1296f4913..f08cfb9a8 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -9,7 +9,6 @@ from pyramid.interfaces import ( from pyramid.exceptions import ConfigurationError from pyramid.i18n import get_localizer from pyramid.path import package_path -from pyramid.threadlocal import get_current_request from pyramid.util import action_method class I18NConfiguratorMixin(object): @@ -107,8 +106,3 @@ class I18NConfiguratorMixin(object): self.action(None, register, introspectables=introspectables) -def translator(msg): - request = get_current_request() - localizer = get_localizer(request) - return localizer.translate(msg) - -- cgit v1.2.3 From 8c3a3bfb5b8679b16f36c9fd0f5ec8cb3b89d37f Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 18:12:37 -0600 Subject: Remove _registerRenderer function from tests It is no longer used, and thus wasn't covered. --- pyramid/tests/test_config/test_init.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index ccecdc0fd..4c6fd3ab9 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -1220,19 +1220,6 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): (classifier, request_iface, ctx_iface), IView, name=name, default=None) - def _registerRenderer(self, config, name='.txt'): - from pyramid.interfaces import IRendererFactory - from pyramid.interfaces import ITemplateRenderer - from zope.interface import implementer - @implementer(ITemplateRenderer) - class Renderer: - def __init__(self, info): - self.__class__.info = info - def __call__(self, *arg): - return 'Hello!' - config.registry.registerUtility(Renderer, IRendererFactory, name=name) - return Renderer - def _assertRoute(self, config, name, path, num_predicates=0): from pyramid.interfaces import IRoutesMapper mapper = config.registry.getUtility(IRoutesMapper) @@ -1318,7 +1305,6 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): def test_add_route_with_view_renderer(self): config = self._makeOne(autocommit=True) - self._registerRenderer(config) view = lambda *arg: 'OK' config.add_route('name', 'path', view=view, view_renderer='json') @@ -1330,7 +1316,6 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): def test_add_route_with_view_attr(self): from pyramid.renderers import null_renderer config = self._makeOne(autocommit=True) - self._registerRenderer(config) class View(object): def __init__(self, context, request): pass @@ -1346,7 +1331,6 @@ class TestConfiguratorDeprecatedFeatures(unittest.TestCase): def test_add_route_with_view_renderer_alias(self): config = self._makeOne(autocommit=True) - self._registerRenderer(config) view = lambda *arg: 'OK' config.add_route('name', 'path', view=view, renderer='json') -- cgit v1.2.3 From 9df28a2a52f41a76cb37acc0d02aff0bd55eeac7 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 18:13:49 -0600 Subject: Add pragma: nocover due to Py3x/Py2x differences --- pyramid/tests/test_config/test_views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 88f740323..618ac2bf4 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1845,9 +1845,9 @@ class TestViewsConfigurationMixin(unittest.TestCase): # Since Python 3 has to be all cool and fancy and different... def _assertBody(self, response, value): from pyramid.compat import text_type - if isinstance(value, text_type): + if isinstance(value, text_type): # pragma: nocover self.assertEqual(response.text, value) - else: + else: # pragma: nocover self.assertEqual(response.body, value) def test_add_notfound_view_with_renderer(self): -- cgit v1.2.3 From 8e8fc1306b4ee2d1107cf62a8272778f154d53dc Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 18:16:09 -0600 Subject: Remove un-used Dummies: DummyFactory/DummyRendererInfo --- pyramid/tests/test_renderers.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 4d40189a5..05d9f3861 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -594,17 +594,3 @@ class DummyResponse: app_iter = () body = '' -class DummyFactory: - def __init__(self, renderer): - self.renderer = renderer - - def __call__(self, path, lookup, **kw): - self.path = path - self.kw = kw - return self.renderer - - -class DummyRendererInfo(object): - def __init__(self, kw): - self.__dict__.update(kw) - -- cgit v1.2.3 From 4ead1210a1f98faf224f19e9382e1cea6b1dd9f9 Mon Sep 17 00:00:00 2001 From: "sergey.volobuev" Date: Fri, 29 Mar 2013 07:31:42 +1000 Subject: removed __init__ methods from SQLAlchemy models in the documentation because the latter generates a default constructor --- docs/tutorials/wiki2/src/authorization/tutorial/models.py | 3 --- docs/tutorials/wiki2/src/basiclayout/tutorial/models.py | 4 ---- docs/tutorials/wiki2/src/models/tutorial/models.py | 4 ---- docs/tutorials/wiki2/src/tests/tutorial/models.py | 3 --- docs/tutorials/wiki2/src/views/tutorial/models.py | 4 ---- 5 files changed, 18 deletions(-) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py index 91e5a0019..4f7e1e024 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py @@ -29,9 +29,6 @@ class Page(Base): name = Column(Text, unique=True) data = Column(Text) - def __init__(self, name, data): - self.name = name - self.data = data class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py index aeeb9df64..0cdd4bbc3 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py @@ -22,7 +22,3 @@ class MyModel(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value diff --git a/docs/tutorials/wiki2/src/models/tutorial/models.py b/docs/tutorials/wiki2/src/models/tutorial/models.py index 9a078d757..f028c917a 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models.py @@ -23,7 +23,3 @@ class Page(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) data = Column(Text) - - def __init__(self, name, data): - self.name = name - self.data = data diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models.py b/docs/tutorials/wiki2/src/tests/tutorial/models.py index 91e5a0019..4f7e1e024 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models.py @@ -29,9 +29,6 @@ class Page(Base): name = Column(Text, unique=True) data = Column(Text) - def __init__(self, name, data): - self.name = name - self.data = data class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), diff --git a/docs/tutorials/wiki2/src/views/tutorial/models.py b/docs/tutorials/wiki2/src/views/tutorial/models.py index 9a078d757..f028c917a 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models.py @@ -23,7 +23,3 @@ class Page(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) data = Column(Text) - - def __init__(self, name, data): - self.name = name - self.data = data -- cgit v1.2.3 From db51d27579d5177c415643707abf3108dc209923 Mon Sep 17 00:00:00 2001 From: "sergey.volobuev" Date: Fri, 29 Mar 2013 07:45:13 +1000 Subject: changed the explanation of the (now missing) __init__ method --- docs/tutorials/wiki2/basiclayout.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 0193afab4..4b78b30d1 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -225,10 +225,11 @@ To give a simple example of a model class, we define one named ``MyModel``: :linenos: :language: py -Our example model has an ``__init__`` method that takes two arguments -(``name``, and ``value``). It stores these values as ``self.name`` and -``self.value`` on the instance created by the ``__init__`` function itself. -The ``MyModel`` class also has a ``__tablename__`` attribute. This informs +Our example model does not require an ``__init__`` method because SQLAlchemy +supplies for us a default constructor if one is not already present, +which accepts keyword arguments of the same name as that of the mapped attributes. + +The ``MyModel`` class has a ``__tablename__`` attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. -- cgit v1.2.3 From ab085ab7466d5100d045194fbd75cc2662fc6520 Mon Sep 17 00:00:00 2001 From: "sergey.volobuev" Date: Fri, 29 Mar 2013 07:48:42 +1000 Subject: removed MyModel.__init__ from the scaffolds --- pyramid/scaffolds/alchemy/+package+/models.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pyramid/scaffolds/alchemy/+package+/models.py b/pyramid/scaffolds/alchemy/+package+/models.py index db1fee832..a0d3e7b71 100644 --- a/pyramid/scaffolds/alchemy/+package+/models.py +++ b/pyramid/scaffolds/alchemy/+package+/models.py @@ -24,8 +24,4 @@ class MyModel(Base): name = Column(Text) value = Column(Integer) - def __init__(self, name, value): - self.name = name - self.value = value - Index('my_index', MyModel.name, unique=True, mysql_length=255) -- cgit v1.2.3 From ca51e11d86f9b4cb24f35e28fa3ab801fc6a49ec Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 19:07:22 -0600 Subject: Add small note showing example usage of MyModel --- docs/tutorials/wiki2/basiclayout.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 4b78b30d1..1f3d630c7 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -229,6 +229,12 @@ Our example model does not require an ``__init__`` method because SQLAlchemy supplies for us a default constructor if one is not already present, which accepts keyword arguments of the same name as that of the mapped attributes. +.. note:: Example usage of MyModel: + + .. code-block:: python + + johnny = MyModel(name="John Doe", value=10) + The ``MyModel`` class has a ``__tablename__`` attribute. This informs SQLAlchemy which table to use to store the data representing instances of this class. -- cgit v1.2.3 From 24ac1ff6b4fbed346c18c759790ae1656a5fdcb3 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 6 Sep 2013 21:19:59 -0600 Subject: Update line numbers as appropriate Removing __init__ moved some code around, update the line numbers as appropriate so that the right sections of code get highlighted. --- docs/tutorials/wiki2/authorization.rst | 4 ++-- docs/tutorials/wiki2/definingmodels.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 01c301e74..2af56868c 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -83,7 +83,7 @@ statement at the head: Add the following class definition: .. literalinclude:: src/authorization/tutorial/models.py - :lines: 36-40 + :lines: 33-37 :linenos: :language: python @@ -339,7 +339,7 @@ when we're done: .. literalinclude:: src/authorization/tutorial/models.py :linenos: - :emphasize-lines: 1-4,36-40 + :emphasize-lines: 1-4,33-37 :language: python (Only the highlighted lines need to be added.) diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 60427a911..e30af12b2 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -24,7 +24,7 @@ following: .. literalinclude:: src/models/tutorial/models.py :linenos: :language: py - :emphasize-lines: 20-22,25,27,29 + :emphasize-lines: 20-22,25 (The highlighted lines are the ones that need to be changed.) -- cgit v1.2.3 From f504ccc216a6d6058ed9228b07f7d1d9a9e5945e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 7 Sep 2013 01:54:10 -0400 Subject: add change notes --- CHANGES.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5c058a9c5..668a696f1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,8 +4,8 @@ Next Release Bug Fixes --------- -- Fix an exception in ``package_name()`` when resolving the package - name for namespace packages. +- Fix an exception in ``pyramid.path.package_name`` when resolving the package + name for namespace packages that had no ``__file__`` attribute. Backwards Incompatibilities --------------------------- @@ -21,6 +21,12 @@ Backwards Incompatibilities only necessary when the renderer is generating a response; it was a bug when it was done as a side effect of calling ``pyramid.renderers.render()``. +- The Mako and Chameleon renderers have been removed from Pyramid. Their + functionality has been moved to the ``pyramid_mako`` and + ``pyramid_chameleon`` distributions respectively. + +- Removed the ``bfg2pyramid`` fixer script. + 1.5a1 (2013-08-30) ================== -- cgit v1.2.3 From 3db6c07ad2653c2a04c61f4cdad059b2f8de237b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 7 Sep 2013 06:21:53 -0400 Subject: make the right assertions about this case --- pyramid/tests/test_renderers.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 05d9f3861..0b67462bb 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -442,19 +442,21 @@ class Test_render(unittest.TestCase): from pyramid.renderers import render return render(renderer_name, value, request=request, package=package) - def test_it_no_request(self): + def _registerRenderer(self): renderer = self.config.testing_add_renderer( 'pyramid.tests:abc/def.pt') renderer.string_response = 'abc' + return renderer + + def test_it_no_request(self): + renderer = self._registerRenderer() result = self._callFUT('abc/def.pt', dict(a=1)) self.assertEqual(result, 'abc') renderer.assert_(a=1) renderer.assert_(request=None) def test_it_with_request(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' + renderer = self._registerRenderer() request = testing.DummyRequest() result = self._callFUT('abc/def.pt', dict(a=1), request=request) @@ -464,9 +466,7 @@ class Test_render(unittest.TestCase): def test_it_with_package(self): import pyramid.tests - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' + renderer = self._registerRenderer() request = testing.DummyRequest() result = self._callFUT('abc/def.pt', dict(a=1), request=request, package=pyramid.tests) @@ -474,23 +474,29 @@ class Test_render(unittest.TestCase): renderer.assert_(a=1) renderer.assert_(request=request) - def test_it_preserves_response(self): + def test_response_preserved(self): request = testing.DummyRequest() response = object() # should error if mutated request.response = response + # use a json renderer, which will mutate the response result = self._callFUT('json', dict(a=1), request=request) self.assertEqual(result, '{"a": 1}') self.assertEqual(request.response, response) - def test_it_deletes_response(self): - request = testing.DummyRequest() - try: - delattr(request, 'response') - except AttributeError: - pass + def test_no_response_to_preserve(self): + from pyramid.decorator import reify + class DummyRequestWithClassResponse(object): + _response = DummyResponse() + _response.content_type = None + _response.default_content_type = None + @reify + def response(self): + return self._response + request = DummyRequestWithClassResponse() + # use a json renderer, which will mutate the response result = self._callFUT('json', dict(a=1), request=request) self.assertEqual(result, '{"a": 1}') - self.assertFalse(hasattr(request, 'request')) + self.assertFalse('response' in request.__dict__) class Test_render_to_response(unittest.TestCase): def setUp(self): -- cgit v1.2.3 From fb9641334e78fa488fa24e8473174cd1620485fc Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 7 Sep 2013 06:23:28 -0400 Subject: unused imports --- pyramid/renderers.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 58b930f94..6f088a54f 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -1,8 +1,5 @@ import json import os -import re -import pkg_resources -import threading from zope.interface import ( implementer, @@ -15,12 +12,9 @@ from pyramid.interfaces import ( IRendererGlobalsFactory, IRendererFactory, IResponseFactory, - ITemplateRenderer, IRendererInfo, ) -from pyramid.asset import asset_spec_from_abspath - from pyramid.compat import ( string_types, text_type, @@ -30,10 +24,7 @@ from pyramid.decorator import reify from pyramid.events import BeforeRender -from pyramid.path import ( - caller_package, - package_path, - ) +from pyramid.path import caller_package from pyramid.response import Response from pyramid.threadlocal import get_current_registry -- cgit v1.2.3 From 2291238b72b6603b475a8551f3b4f2c178e2ba81 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 7 Sep 2013 06:28:37 -0400 Subject: single line import --- pyramid/config/rendering.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index a14853fdc..a301b9c43 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -7,10 +7,7 @@ from pyramid.interfaces import ( ) from pyramid.util import action_method - -from pyramid import ( - renderers, - ) +from pyramid import renderers DEFAULT_RENDERERS = ( ('json', renderers.json_renderer_factory), -- cgit v1.2.3 From fc477b2e4b20ae2788e468e45b2831e774be8ced Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 7 Sep 2013 21:59:41 -0400 Subject: - The ``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. Closes #1116. --- CHANGES.txt | 5 +++++ docs/api/request.rst | 6 +++--- docs/narr/hooks.rst | 2 +- docs/narr/subrequest.rst | 6 +++--- pyramid/router.py | 9 +++++---- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 668a696f1..64b269f80 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -27,6 +27,11 @@ Backwards Incompatibilities - Removed the ``bfg2pyramid`` fixer script. +- The ``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. + 1.5a1 (2013-08-30) ================== diff --git a/docs/api/request.rst b/docs/api/request.rst index ef41ba4c8..72abddb68 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -199,13 +199,13 @@ - Ensures that the user implied by the request passed has the necessary authorization to invoke view callable before calling it. - - causes a :class:`~pyramid.events.NewResponse` event to be sent when - the Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the request's lifetime if a response is obtained from the Pyramid application. + - causes a :class:`~pyramid.events.NewResponse` event to be sent if a + response is obtained. + - Calls any :term:`finished callback` functions defined within the request's lifetime. diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 3a2568775..8ffda1a5f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -514,7 +514,7 @@ callback will be an exception object instead of its default value of ``None``. Response callbacks are called in the order they're added -(first-to-most-recently-added). All response callbacks are called *after* +(first-to-most-recently-added). All response callbacks are called *before* the :class:`~pyramid.events.NewResponse` event is sent. Errors raised by response callbacks are not handled specially. They will be propagated to the caller of the :app:`Pyramid` router application. diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 6437bd0fa..4b4e99d41 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -232,12 +232,12 @@ unconditionally: - Ensures that the user implied by the request passed has the necessary authorization to invoke view callable before calling it. -- causes a :class:`~pyramid.events.NewResponse` event to be sent when the - Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the subrequest's lifetime if a response is obtained from the Pyramid application. +- causes a :class:`~pyramid.events.NewResponse` event to be sent if a response + is obtained. + - Calls any :term:`finished callback` functions defined within the subrequest's lifetime. diff --git a/pyramid/router.py b/pyramid/router.py index 1a991648b..6239f3980 100644 --- a/pyramid/router.py +++ b/pyramid/router.py @@ -212,13 +212,13 @@ class Router(object): - causes a :class:`~pyramid.event.ContextFound` event to be sent when a context resource is found. - - causes a :class:`~pyramid.event.NewResponse` event to be sent when - the Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the request's lifetime if a response is obtained from the Pyramid application. + - causes a :class:`~pyramid.event.NewResponse` event to be sent if a + response is obtained. + - Calls any :term:`finished callback` functions defined within the request's lifetime. @@ -245,11 +245,12 @@ class Router(object): if extensions is not None: request._set_extensions(extensions) response = handle_request(request) - has_listeners and notify(NewResponse(request, response)) if request.response_callbacks: request._process_response_callbacks(response) + has_listeners and notify(NewResponse(request, response)) + return response finally: -- cgit v1.2.3 From f74033f797b82e7368c4e10eba22e0704bc32973 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 05:31:35 -0400 Subject: remove bfg conversion chapter --- docs/index.rst | 1 - docs/latexindex.rst | 1 - docs/tutorials/bfg/index.rst | 204 ------------------------------------------- 3 files changed, 206 deletions(-) delete mode 100644 docs/tutorials/bfg/index.rst diff --git a/docs/index.rst b/docs/index.rst index d2a0008a8..b0bda383f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -126,7 +126,6 @@ platforms. tutorials/wiki2/index.rst tutorials/wiki/index.rst - tutorials/bfg/index.rst tutorials/modwsgi/index.rst .. _html_api_documentation: diff --git a/docs/latexindex.rst b/docs/latexindex.rst index eb14f5076..c4afff212 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -78,7 +78,6 @@ Tutorials tutorials/wiki2/index.rst tutorials/wiki/index.rst - tutorials/bfg/index.rst tutorials/modwsgi/index.rst .. _api_documentation: diff --git a/docs/tutorials/bfg/index.rst b/docs/tutorials/bfg/index.rst deleted file mode 100644 index 1abb26466..000000000 --- a/docs/tutorials/bfg/index.rst +++ /dev/null @@ -1,204 +0,0 @@ -.. index:: - single: converting a BFG app - single: bfg2pyramid - -.. _converting_a_bfg_app: - -Converting a :mod:`repoze.bfg` Application to :app:`Pyramid` -============================================================ - -Prior iterations of :app:`Pyramid` were released as a package named -:mod:`repoze.bfg`. :mod:`repoze.bfg` users are encouraged to upgrade -their deployments to :app:`Pyramid`, as, after the first final release -of :app:`Pyramid`, further feature development on :mod:`repoze.bfg` -will cease. - -Most existing :mod:`repoze.bfg` applications can be converted to a -:app:`Pyramid` application in a completely automated fashion. -However, if your application depends on packages which are not "core" -parts of :mod:`repoze.bfg` but which nonetheless have ``repoze.bfg`` -in their names (e.g. ``repoze.bfg.skins``, -``repoze.bfg.traversalwrapper``, ``repoze.bfg.jinja2``), you will need -to find an analogue for each. For example, by the time you read this, -there will be a ``pyramid_jinja2`` package, which can be used instead -of ``repoze.bfg.jinja2``. If an analogue does not seem to exist for a -``repoze.bfg`` add-on package that your application uses, please email -the `Pylons-devel `_ -maillist; we'll convert the package to a :app:`Pyramid` analogue for -you. - -Here's how to convert a :mod:`repoze.bfg` application to a -:app:`Pyramid` application: - -#. Ensure that your application works under :mod:`repoze.bfg` *version - 1.3 or better*. See - `http://docs.repoze.org/bfg/1.3/narr/install.html - `_ for - :mod:`repoze.bfg` 1.3 installation instructions. If your - application has an automated test suite, run it while your - application is using :mod:`repoze.bfg` 1.3+. Otherwise, test it - manually. It is only safe to proceed to the next step once your - application works under :mod:`repoze.bfg` 1.3+. - - If your application has a proper set of dependencies, and a - standard automated test suite, you might test your - :mod:`repoze.bfg` application against :mod:`repoze.bfg` 1.3 like - so: - - .. code-block:: bash - - $ $VENV/bin/python setup.py test - - ``bfgenv`` above will be the virtualenv into which you've installed - :mod:`repoze.bfg` 1.3. - -#. Install :app:`Pyramid` into a *separate* virtualenv as per the - instructions in :ref:`installing_chapter`. The :app:`Pyramid` - virtualenv should be separate from the one you've used to install - :mod:`repoze.bfg`. A quick way to do this: - - .. code-block:: bash - - $ cd ~ - $ virtualenv pyramidenv - $ cd pyramidenv - $ $VENV/bin/easy_install pyramid - -#. Put a *copy* of your :mod:`repoze.bfg` application into a temporary - location (perhaps by checking a fresh copy of the application out - of a version control repository). For example: - - .. code-block:: bash - - $ cd /tmp - $ svn co http://my.server/my/bfg/application/trunk bfgapp - -#. Use the ``bfg2pyramid`` script present in the ``bin`` directory of - the :app:`Pyramid` virtualenv to convert all :mod:`repoze.bfg` - Python import statements into compatible :app:`Pyramid` import - statements. ``bfg2pyramid`` will also fix ZCML directive usages of - common :mod:`repoze.bfg` directives. You invoke ``bfg2pyramid`` by - passing it the *path* of the copy of your application. The path - passed should contain a "setup.py" file, representing your - :mod:`repoze.bfg` application's setup script. ``bfg2pyramid`` will - change the copy of the application *in place*. - - .. code-block:: bash - - $ ~/pyramidenv/bfg2pyramid /tmp/bfgapp - - ``bfg2pyramid`` will convert the following :mod:`repoze.bfg` - application aspects to :app:`Pyramid` compatible analogues: - - - Python ``import`` statements naming :mod:`repoze.bfg` APIs will - be converted to :app:`Pyramid` compatible ``import`` statements. - Every Python file beneath the top-level path will be visited and - converted recursively, except Python files which live in - directories which start with a ``.`` (dot). - - - Each ZCML file found (recursively) within the path will have the - default ``xmlns`` attribute attached to the ``configure`` tag - changed from ``http://namespaces.repoze.org/bfg`` to - ``http://pylonshq.com/pyramid``. Every ZCML file beneath the - top-level path (files ending with ``.zcml``) will be visited and - converted recursively, except ZCML files which live in - directories which start with a ``.`` (dot). - - - ZCML files which contain directives that have attributes which - name a ``repoze.bfg`` API module or attribute of an API module - (e.g. ``context="repoze.bfg.exceptions.NotFound"``) will be - converted to :app:`Pyramid` compatible ZCML attributes - (e.g. ``context="pyramid.exceptions.NotFound``). Every ZCML file - beneath the top-level path (files ending with ``.zcml``) will be - visited and converted recursively, except ZCML files which live - in directories which start with a ``.`` (dot). - -#. Edit the ``setup.py`` file of the application you've just converted - (if you've been using the example paths, this will be - ``/tmp/bfgapp/setup.py``) to depend on the ``pyramid`` distribution - instead the of ``repoze.bfg`` distribution in its - ``install_requires`` list. If you used a scaffold to - create the :mod:`repoze.bfg` application, you can do so by changing - the ``requires`` line near the top of the ``setup.py`` file. The - original may look like this: - - .. code-block:: text - - requires = ['repoze.bfg', ... other dependencies ...] - - Edit the ``setup.py`` so it has: - - .. code-block:: text - - requires = ['pyramid', ... other dependencies ...] - - All other install-requires and tests-requires dependencies save for - the one on ``repoze.bfg`` can remain the same. - -#. Convert any ``install_requires`` dependencies your application has - on other add-on packages which have ``repoze.bfg`` in their names - to :app:`Pyramid` compatible analogues (e.g. ``repoze.bfg.jinja2`` - should be replaced with ``pyramid_jinja2``). You may need to - adjust configuration options and/or imports in your - :mod:`repoze.bfg` application after replacing these add-ons. Read - the documentation of the :app:`Pyramid` add-on package for - information. - -#. *Only if you use ZCML and add-ons which use ZCML*: The default - ``xmlns`` of the ``configure`` tag in ZCML has changed. The - ``bfg2pyramid`` script effects the default namespace change (it - changes the ``configure`` tag default ``xmlns`` from - ``http://namespaces.repoze.org/bfg`` to - ``http://pylonshq.com/pyramid``). - - This means that uses of add-ons which define ZCML directives in the - ``http://namespaces.repoze.org/bfg`` namespace will begin to "fail" - (they're actually not really failing, but your ZCML assumes that - they will always be used within a ``configure`` tag which names the - ``http://namespaces.repoze.org/bfg`` namespace as its default - ``xmlns``). Symptom: when you attempt to start the application, an - error such as ``ConfigurationError: ('Unknown directive', - u'http://namespaces.repoze.org/bfg', u'workflow')`` is printed to - the console and the application fails to start. In such a case, - either add an ``xmlns="http://namespaces.repoze.org/bfg"`` - attribute to each tag which causes a failure, or define a namespace - alias in the configure tag and prefix each failing tag. For - example, change this "failing" tag instance:: - - - - - - To this, which will begin to succeed:: - - - - - - You will also need to add the ``pyramid_zcml`` package to your - ``setup.py`` ``install_requires`` list. In Pyramid, ZCML configuration - became an optional add-on supported by the ``pyramid_zcml`` package. - -#. Retest your application using :app:`Pyramid`. This might be as - easy as: - - .. code-block:: bash - - $ cd /tmp/bfgapp - $ $VENV/bin/python setup.py test - -#. Fix any test failures. - -#. Fix any code which generates deprecation warnings. - -#. Start using the converted version of your application. Celebrate. - -Two terminological changes have been made to Pyramid which make its -documentation and newer APIs different than those of ``repoze.bfg``. The -concept that BFG called ``model`` is called ``resource`` in Pyramid and the -concept that BFG called ``resource`` is called ``asset`` in Pyramid. Various -APIs have changed as a result (although all have backwards compatible shims). -Additionally, the environment variables that influenced server behavior which -used to be prefixed with ``BFG_`` (such as ``BFG_DEBUG_NOTFOUND``) must now -be prefixed with ``PYRAMID_``. -- cgit v1.2.3 From e7575491cb6d63e887dcdc40c2d86bb30ff775ca Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 05:36:21 -0400 Subject: fix docs after removing bfg conversion chapter, add a prominent link to the quick tour --- docs/index.rst | 3 ++- docs/whatsnew-1.0.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index b0bda383f..2efe90cf7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,7 +20,8 @@ After you install :app:`Pyramid` and run this application, when you visit See :ref:`firstapp_chapter` for a full explanation of how this application works. Read the :ref:`html_narrative_documentation` to understand how :app:`Pyramid` is designed to scale from simple applications like this to -very large web applications. +very large web applications. To just dive in headfirst, read the +:doc:`quick_tour`. Front Matter ============ diff --git a/docs/whatsnew-1.0.rst b/docs/whatsnew-1.0.rst index de24838fb..8750863e7 100644 --- a/docs/whatsnew-1.0.rst +++ b/docs/whatsnew-1.0.rst @@ -92,7 +92,7 @@ BFG Conversion Script The ``bfg2pyramid`` conversion script performs a mostly automated conversion of an existing :mod:`repoze.bfg` application to Pyramid. The process is -described in :ref:`converting_a_bfg_app`. +described in "Converting a BFG Application to Pyramid". Scaffold Improvements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From b098c223a3574988d6e8855a6c4764587a46b067 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 8 Sep 2013 15:12:51 -0600 Subject: Small change to allow predicates to be Python Dotted Names This allows a {view,route,subscriber} predicate factory to be named as a python dotted name that is then automatically resolved. Includes tests. --- pyramid/config/__init__.py | 2 +- pyramid/tests/test_config/test_util.py | 46 ++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index d4557d6b1..f1f24fbc1 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -512,7 +512,7 @@ class Configurator( '%s predicate named %s' % (type, name), '%s predicate' % type) intr['name'] = name - intr['factory'] = factory + intr['factory'] = self.maybe_dotted(factory) intr['weighs_more_than'] = weighs_more_than intr['weighs_less_than'] = weighs_less_than def register(): diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py index f6cd414fb..939a51216 100644 --- a/pyramid/tests/test_config/test_util.py +++ b/pyramid/tests/test_config/test_util.py @@ -380,8 +380,8 @@ class TestPredicateList(unittest.TestCase): self.assertEqual(predicates[2].text(), '!header header') self.assertEqual(predicates[1](None, request), True) self.assertEqual(predicates[2](None, request), True) - - + + class Test_takes_one_arg(unittest.TestCase): def _callFUT(self, view, attr=None, argname=None): from pyramid.config.util import takes_one_arg @@ -560,7 +560,7 @@ class Test_takes_one_arg(unittest.TestCase): class Foo: pass foo = Foo() self.assertFalse(self._callFUT(foo)) - + def test_method_onearg_named_request(self): class Foo: def method(self, request): @@ -586,11 +586,43 @@ class TestNotted(unittest.TestCase): self.assertEqual(inst.text(), '') self.assertEqual(inst.phash(), '') self.assertEqual(inst(None, None), True) - + +class TestDotted(unittest.TestCase): + + + def _makeOne(self, *arg, **kw): + self.action_called = False + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_it_without_dots(self): + config = self._makeOne() + + def _fakeAction(discriminator, callable=None, args=(), kw=None, order=0, introspectables=(), **extra): + self.assertEqual(len(introspectables), 1) + self.assertEqual(introspectables[0]['name'], 'testing') + self.assertEqual(introspectables[0]['factory'], DummyPredicate) + + config.action = _fakeAction + config._add_predicate('route', 'testing', DummyPredicate) + + def test_it_with_dots(self): + config = self._makeOne() + + def _fakeAction(discriminator, callable=None, args=(), kw=None, order=0, introspectables=(), **extra): + self.assertEqual(len(introspectables), 1) + self.assertEqual(introspectables[0]['name'], 'testing') + self.assertEqual(introspectables[0]['factory'], DummyPredicate) + + config.action = _fakeAction + config._add_predicate('route', 'testing', 'pyramid.tests.test_config.test_util.DummyPredicate') + + class DummyPredicate(object): def __init__(self, result): self.result = result - + def text(self): return self.result @@ -598,7 +630,7 @@ class DummyPredicate(object): def __call__(self, context, request): return True - + class DummyCustomPredicate(object): def __init__(self): self.__text__ = 'custom predicate' @@ -626,4 +658,4 @@ class DummyRequest: class DummyConfigurator(object): def maybe_dotted(self, thing): return thing - + -- cgit v1.2.3 From d71acabebb804ebbd37703e78ac9886fcdded827 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 8 Sep 2013 15:15:58 -0600 Subject: Update documentation to reflect the dotted python name --- docs/narr/hooks.rst | 8 +++++--- pyramid/config/adapters.py | 3 ++- pyramid/config/routes.py | 3 ++- pyramid/config/views.py | 3 ++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 8ffda1a5f..a7dc3e78b 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1384,9 +1384,11 @@ The first argument to :meth:`pyramid.config.Configurator.add_view_predicate`, the name, is a string representing the name that is expected to be passed to ``view_config`` (or its imperative analogue ``add_view``). -The second argument is a view or route predicate factory. A view or route -predicate factory is most often a class with a constructor (``__init__``), a -``text`` method, a ``phash`` method and a ``__call__`` method. For example: +The second argument is a view or route predicate factory, or a :term:`dotted +Python name` which refers to a view or route predicate factory. A view or +route predicate factory is most often a class with a constructor +(``__init__``), a ``text`` method, a ``phash`` method and a ``__call__`` +method. For example: .. code-block:: python :linenos: diff --git a/pyramid/config/adapters.py b/pyramid/config/adapters.py index 5573b6748..0a74e76b4 100644 --- a/pyramid/config/adapters.py +++ b/pyramid/config/adapters.py @@ -147,7 +147,8 @@ class AdaptersConfiguratorMixin(object): Python identifier (it will be used as a ``**predicates`` keyword argument to :meth:`~pyramid.config.Configurator.add_subscriber`). - ``factory`` should be a :term:`predicate factory`. + ``factory`` should be a :term:`predicate factory` or :term:`dotted + Python name` which refers to a predicate factory. See :ref:`subscriber_predicates` for more information. diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 0ed370c94..c7659ce08 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -523,7 +523,8 @@ class RoutesConfiguratorMixin(object): Python identifier (it will be used as a keyword argument to ``add_view``). - ``factory`` should be a :term:`predicate factory`. + ``factory`` should be a :term:`predicate factory` or :term:`dotted + Python name` which refers to a predicate factory. See :ref:`view_and_route_predicates` for more information. diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 707c84043..209b9e4a2 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1369,7 +1369,8 @@ class ViewsConfiguratorMixin(object): Python identifier (it will be used as a keyword argument to ``add_view`` by others). - ``factory`` should be a :term:`predicate factory`. + ``factory`` should be a :term:`predicate factory` or :term:`dotted + Python name` which refers to a predicate factory. See :ref:`view_and_route_predicates` for more information. """ -- cgit v1.2.3 From e96f1b11e105c64577062b585f6465d00acbabdc Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 8 Sep 2013 15:16:34 -0600 Subject: Deprecate custom_predicates for add_view/add_route --- pyramid/config/routes.py | 2 ++ pyramid/config/views.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index c7659ce08..14dd87d0f 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -255,6 +255,8 @@ class RoutesConfiguratorMixin(object): custom_predicates + .. deprecated:: 1.5 + This value should be a sequence of references to custom predicate callables. Use custom predicates when no set of predefined predicates does what you need. Custom predicates diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 209b9e4a2..243c017fa 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1027,6 +1027,8 @@ class ViewsConfiguratorMixin(object): custom_predicates + .. deprecated:: 1.5 + This value should be a sequence of references to custom predicate callables. Use custom predicates when no set of predefined predicates do what you need. Custom predicates can be combined with -- cgit v1.2.3 From 004ac88872ee2e4637719fdb80c99b7f42da9820 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 8 Sep 2013 15:19:04 -0600 Subject: Remove useless spaces. --- pyramid/tests/test_config/test_util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py index 939a51216..93d5c8895 100644 --- a/pyramid/tests/test_config/test_util.py +++ b/pyramid/tests/test_config/test_util.py @@ -588,8 +588,6 @@ class TestNotted(unittest.TestCase): self.assertEqual(inst(None, None), True) class TestDotted(unittest.TestCase): - - def _makeOne(self, *arg, **kw): self.action_called = False from pyramid.config import Configurator -- cgit v1.2.3 From c390f4bcae4751b406a8467fecdbdecc242f3a25 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 8 Sep 2013 15:22:26 -0600 Subject: Add feature update to CHANGES.txt --- CHANGES.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 9d34786e2..3a78f6950 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,13 @@ Next Release ============ +Features +-------- + +- Users can now provide dotted Python names to + ``add_{view,route,subscriber}_predicates`` instead of the predicate factory + directly. + Bug Fixes --------- -- cgit v1.2.3 From cbcd4d2dc8f948d43fffd6f403cee3bec93f87f8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 17:28:39 -0400 Subject: wording --- CHANGES.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3a78f6950..a26336a00 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,9 +4,10 @@ Next Release Features -------- -- Users can now provide dotted Python names to - ``add_{view,route,subscriber}_predicates`` instead of the predicate factory - directly. +- Users can now provide dotted Python names to as the ``factory`` argument + the Configurator methods named ``add_{view,route,subscriber}_predicate`` + (instead of passing the predicate factory directly, you can pass a + dotted name which refers to the factory). Bug Fixes --------- -- cgit v1.2.3 From f9600f6c935736c0fe727d7c38e38c6dfa4e69dd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 17:37:38 -0400 Subject: move test to more correct location, 79 cols --- pyramid/tests/test_config/test_init.py | 36 +++++++++++++++++++++++++++++++++- pyramid/tests/test_config/test_util.py | 30 ---------------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index 4c6fd3ab9..a7ef65fe8 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -3,7 +3,6 @@ import warnings import os -from pyramid.compat import PYPY from pyramid.compat import im_func from pyramid.testing import skip_on @@ -1475,6 +1474,39 @@ class TestConfigurator_add_directive(unittest.TestCase): self.assertEqual(action['callable'], None) self.assertEqual(action['args'], config2.package) +class TestConfigurator__add_predicate(unittest.TestCase): + def _makeOne(self): + from pyramid.config import Configurator + return Configurator() + + def test_factory_as_object(self): + config = self._makeOne() + + def _fakeAction(discriminator, callable=None, args=(), kw=None, + order=0, introspectables=(), **extra): + self.assertEqual(len(introspectables), 1) + self.assertEqual(introspectables[0]['name'], 'testing') + self.assertEqual(introspectables[0]['factory'], DummyPredicate) + + config.action = _fakeAction + config._add_predicate('route', 'testing', DummyPredicate) + + def test_factory_as_dotted_name(self): + config = self._makeOne() + + def _fakeAction(discriminator, callable=None, args=(), + kw=None, order=0, introspectables=(), **extra): + self.assertEqual(len(introspectables), 1) + self.assertEqual(introspectables[0]['name'], 'testing') + self.assertEqual(introspectables[0]['factory'], DummyPredicate) + + config.action = _fakeAction + config._add_predicate( + 'route', + 'testing', + 'pyramid.tests.test_config.test_init.DummyPredicate' + ) + class TestActionState(unittest.TestCase): def _makeOne(self): from pyramid.config import ActionState @@ -1989,3 +2021,5 @@ class DummyIntrospectable(object): def register(self, introspector, action_info): self.registered.append((introspector, action_info)) +class DummyPredicate(object): + pass diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py index 93d5c8895..bb61714ae 100644 --- a/pyramid/tests/test_config/test_util.py +++ b/pyramid/tests/test_config/test_util.py @@ -587,36 +587,6 @@ class TestNotted(unittest.TestCase): self.assertEqual(inst.phash(), '') self.assertEqual(inst(None, None), True) -class TestDotted(unittest.TestCase): - def _makeOne(self, *arg, **kw): - self.action_called = False - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_it_without_dots(self): - config = self._makeOne() - - def _fakeAction(discriminator, callable=None, args=(), kw=None, order=0, introspectables=(), **extra): - self.assertEqual(len(introspectables), 1) - self.assertEqual(introspectables[0]['name'], 'testing') - self.assertEqual(introspectables[0]['factory'], DummyPredicate) - - config.action = _fakeAction - config._add_predicate('route', 'testing', DummyPredicate) - - def test_it_with_dots(self): - config = self._makeOne() - - def _fakeAction(discriminator, callable=None, args=(), kw=None, order=0, introspectables=(), **extra): - self.assertEqual(len(introspectables), 1) - self.assertEqual(introspectables[0]['name'], 'testing') - self.assertEqual(introspectables[0]['factory'], DummyPredicate) - - config.action = _fakeAction - config._add_predicate('route', 'testing', 'pyramid.tests.test_config.test_util.DummyPredicate') - - class DummyPredicate(object): def __init__(self, result): self.result = result -- cgit v1.2.3 From 2c4f4e3cbd1b5b56bb17d2348df3c397efd0a8e4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 20:39:39 -0400 Subject: - Removed the class named ``pyramid.view.static`` that had been deprecated since Pyramid 1.1. Instead use ``pyramid.static.static_view`` with ``use_subpath=True`` argument. --- CHANGES.txt | 4 ++++ docs/api/view.rst | 4 ---- pyramid/tests/test_view.py | 18 ------------------ pyramid/view.py | 23 ----------------------- 4 files changed, 4 insertions(+), 45 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index a26336a00..42ba8b3ce 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -73,6 +73,10 @@ Backwards Incompatibilities 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 ``pyramid.static.static_view`` with + ``use_subpath=True`` argument. + 1.5a1 (2013-08-30) ================== diff --git a/docs/api/view.rst b/docs/api/view.rst index 21d2bb90d..e79e1b505 100644 --- a/docs/api/view.rst +++ b/docs/api/view.rst @@ -25,8 +25,4 @@ .. autoclass:: forbidden_view_config :members: - .. autoclass:: static - :members: - :inherited-members: - diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py index a0d476662..bd7e635dd 100644 --- a/pyramid/tests/test_view.py +++ b/pyramid/tests/test_view.py @@ -673,24 +673,6 @@ class Test_default_exceptionresponse_view(unittest.TestCase): result = self._callFUT(context, request) self.assertEqual(result, 'abc') -class Test_static(unittest.TestCase): - def setUp(self): - from zope.deprecation import __show__ - __show__.off() - - def tearDown(self): - from zope.deprecation import __show__ - __show__.on() - - def _makeOne(self, path, package_name): - from pyramid.view import static - return static(path, package_name) - - def test_it(self): - path = 'fixtures' - view = self._makeOne(path, None) - self.assertEqual(view.docroot, 'fixtures') - class Test_view_defaults(unittest.TestCase): def test_it(self): from pyramid.view import view_defaults diff --git a/pyramid/view.py b/pyramid/view.py index b64db69d2..1ef8faab3 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -20,33 +20,10 @@ from pyramid.httpexceptions import ( default_exceptionresponse_view, ) -from pyramid.path import caller_package -from pyramid.static import static_view from pyramid.threadlocal import get_current_registry _marker = object() -class static(static_view): - """ Backwards compatibility alias for - :class:`pyramid.static.static_view`; it overrides that class' constructor - to pass ``use_subpath=True`` by default. - - .. deprecated:: 1.1 - use :class:`pyramid.static.static_view` instead - (probably with a ``use_subpath=True`` argument) - """ - def __init__(self, root_dir, cache_max_age=3600, package_name=None): - if package_name is None: - package_name = caller_package().__name__ - static_view.__init__(self, root_dir, cache_max_age=cache_max_age, - package_name=package_name, use_subpath=True) - -deprecated( - 'static', - 'The "pyramid.view.static" class is deprecated as of Pyramid 1.1; ' - 'use the "pyramid.static.static_view" class instead with the ' - '"use_subpath" argument set to True.') - def render_view_to_response(context, request, name='', secure=True): """ Call the :term:`view callable` configured with a :term:`view configuration` that matches the :term:`view name` ``name`` -- cgit v1.2.3 From 780bbf9998fd805df55499ef4a78f41cbf99c7de Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 20:45:33 -0400 Subject: - Removed the ``pyramid.view.is_response`` function that had been deprecated since Pyramid 1.1. Use the ``pyramid.request.Request.is_response`` method instead. --- CHANGES.txt | 4 ++++ docs/api/view.rst | 2 -- pyramid/tests/test_view.py | 45 --------------------------------------------- pyramid/view.py | 17 ----------------- 4 files changed, 4 insertions(+), 64 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 42ba8b3ce..989d1bca1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -77,6 +77,10 @@ Backwards Incompatibilities since Pyramid 1.1. Instead use ``pyramid.static.static_view`` with ``use_subpath=True`` argument. +- Removed the ``pyramid.view.is_response`` function that had been deprecated + since Pyramid 1.1. Use the ``pyramid.request.Request.is_response`` method + instead. + 1.5a1 (2013-08-30) ================== diff --git a/docs/api/view.rst b/docs/api/view.rst index e79e1b505..d8e429552 100644 --- a/docs/api/view.rst +++ b/docs/api/view.rst @@ -11,8 +11,6 @@ .. autofunction:: render_view - .. autofunction:: is_response - .. autoclass:: view_config :members: diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py index bd7e635dd..309fd47e2 100644 --- a/pyramid/tests/test_view.py +++ b/pyramid/tests/test_view.py @@ -301,51 +301,6 @@ class RenderViewTests(BaseTest, unittest.TestCase): s = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(s, b'anotherview') -class TestIsResponse(unittest.TestCase): - def setUp(self): - from zope.deprecation import __show__ - __show__.off() - - def tearDown(self): - from zope.deprecation import __show__ - __show__.on() - - def _callFUT(self, *arg, **kw): - from pyramid.view import is_response - return is_response(*arg, **kw) - - def test_is(self): - response = DummyResponse() - self.assertEqual(self._callFUT(response), True) - - def test_isnt(self): - response = None - self.assertEqual(self._callFUT(response), False) - - def test_isnt_no_headerlist(self): - class Response(object): - pass - resp = Response - resp.status = '200 OK' - resp.app_iter = [] - self.assertEqual(self._callFUT(resp), False) - - def test_isnt_no_status(self): - class Response(object): - pass - resp = Response - resp.app_iter = [] - resp.headerlist = () - self.assertEqual(self._callFUT(resp), False) - - def test_isnt_no_app_iter(self): - class Response(object): - pass - resp = Response - resp.status = '200 OK' - resp.headerlist = () - self.assertEqual(self._callFUT(resp), False) - class TestViewConfigDecorator(unittest.TestCase): def setUp(self): testing.setUp() diff --git a/pyramid/view.py b/pyramid/view.py index 1ef8faab3..edb4d688c 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -1,8 +1,6 @@ import venusian from zope.interface import providedBy -from zope.deprecation import deprecated - from pyramid.interfaces import ( IRoutesMapper, @@ -407,18 +405,3 @@ class forbidden_view_config(object): settings['_info'] = info.codeinfo # fbo "action_method" return wrapped -def is_response(ob): - """ Return ``True`` if ``ob`` implements the interface implied by - :ref:`the_response`. ``False`` if not. - - .. deprecated:: 1.1 - use :func:`pyramid.request.Request.is_response` instead""" - if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and - hasattr(ob, 'status') ): - return True - return False - -deprecated( - 'is_response', - 'pyramid.view.is_response is deprecated as of Pyramid 1.1. Use ' - 'pyramid.request.Request.is_response instead.') -- cgit v1.2.3 From fdf30b3bb6f47d93d2f255a09e75be0c33d54789 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 21:12:10 -0400 Subject: - Removed the ability to pass the following arguments to ``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 ``pyramid.config.Configurator.add_view`` to associate a view with a route using its ``route_name`` argument. Note that this impacts the ``pyramid.config.Configurator.add_static_view`` function too, because it delegates to ``add_route``. --- CHANGES.txt | 10 ++ docs/narr/urldispatch.rst | 7 -- pyramid/config/routes.py | 158 ------------------------- pyramid/config/views.py | 20 +--- pyramid/tests/test_config/test_init.py | 199 -------------------------------- pyramid/tests/test_config/test_views.py | 35 +----- 6 files changed, 17 insertions(+), 412 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 989d1bca1..69547ad46 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -81,6 +81,16 @@ Backwards Incompatibilities since Pyramid 1.1. Use the ``pyramid.request.Request.is_response`` method instead. +- Removed the ability to pass the following arguments to + ``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 + ``pyramid.config.Configurator.add_view`` to associate a view with a route + using its ``route_name`` argument. Note that this impacts the + ``pyramid.config.Configurator.add_static_view`` function too, because it + delegates to ``add_route``. + 1.5a1 (2013-08-30) ================== diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 62eb89348..61849c3c0 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -399,13 +399,6 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. -.. warning:: - - Some arguments are view-configuration related arguments, such as - ``view_renderer``. These only have an effect when the route configuration - names a ``view`` and these arguments have been deprecated as of - :app:`Pyramid` 1.1. - .. index:: single: route matching diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 14dd87d0f..c31bd7195 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -1,5 +1,3 @@ -import warnings - from pyramid.compat import urlparse from pyramid.interfaces import ( IRequest, @@ -25,8 +23,6 @@ class RoutesConfiguratorMixin(object): def add_route(self, name, pattern=None, - view=None, - view_for=None, permission=None, factory=None, for_=None, @@ -38,11 +34,7 @@ class RoutesConfiguratorMixin(object): request_param=None, traverse=None, custom_predicates=(), - view_permission=None, renderer=None, - view_renderer=None, - view_context=None, - view_attr=None, use_global_views=False, path=None, pregenerator=None, @@ -284,97 +276,6 @@ class RoutesConfiguratorMixin(object): .. versionadded:: 1.4 - View-Related Arguments - - .. warning:: - - The arguments described below have been deprecated as of - :app:`Pyramid` 1.1. *Do not use these for new development; they - should only be used to support older code bases which depend upon - them.* Use a separate call to - :meth:`pyramid.config.Configurator.add_view` to associate a view - with a route using the ``route_name`` argument. - - view - - .. deprecated:: 1.1 - - A Python object or :term:`dotted Python name` to the same - object that will be used as a view callable when this route - matches. e.g. ``mypackage.views.my_view``. - - view_context - - .. deprecated:: 1.1 - - A class or an :term:`interface` or :term:`dotted Python - name` to the same object which the :term:`context` of the - view should match for the view named by the route to be - used. This argument is only useful if the ``view`` - attribute is used. If this attribute is not specified, the - default (``None``) will be used. - - If the ``view`` argument is not provided, this argument has - no effect. - - This attribute can also be spelled as ``for_`` or ``view_for``. - - view_permission - - .. deprecated:: 1.1 - - The permission name required to invoke the view associated - with this route. e.g. ``edit``. (see - :ref:`using_security_with_urldispatch` for more information - about permissions). - - If the ``view`` attribute is not provided, this argument has - no effect. - - This argument can also be spelled as ``permission``. - - view_renderer - - .. deprecated:: 1.1 - - This is either a single string term (e.g. ``json``) or a - string implying a path or :term:`asset specification` - (e.g. ``templates/views.pt``). If the renderer value is a - single term (does not contain a dot ``.``), the specified - term will be used to look up a renderer implementation, and - that renderer implementation will be used to construct a - response from the view return value. If the renderer term - contains a dot (``.``), the specified term will be treated - as a path, and the filename extension of the last element in - the path will be used to look up the renderer - implementation, which will be passed the full path. The - renderer implementation will be used to construct a response - from the view return value. See - :ref:`views_which_use_a_renderer` for more information. - - If the ``view`` argument is not provided, this argument has - no effect. - - This argument can also be spelled as ``renderer``. - - view_attr - - .. deprecated:: 1.1 - - The view machinery defaults to using the ``__call__`` method - of the view callable (or the function itself, if the view - callable is a function) to obtain a response dictionary. - The ``attr`` value allows you to vary the method attribute - used to obtain the response. For example, if your view was - a class, and the class has a method named ``index`` and you - wanted to use this method instead of the class' ``__call__`` - method to return the response, you'd say ``attr="index"`` in - the view configuration for the view. This is - most useful when the view definition is a class. - - If the ``view`` argument is not provided, this argument has no - effect. - """ # these are route predicates; if they do not match, the next route # in the routelist will be tried @@ -501,19 +402,6 @@ class RoutesConfiguratorMixin(object): self.action(('route', name), register_route_request_iface, order=PHASE2_CONFIG, introspectables=introspectables) - # deprecated adding views from add_route; must come after - # route registration for purposes of autocommit ordering - if any([view, view_context, view_permission, view_renderer, - view_for, for_, permission, renderer, view_attr]): - self._add_view_from_route( - route_name=name, - view=view, - permission=view_permission or permission, - context=view_context or view_for or for_, - renderer=view_renderer or renderer, - attr=view_attr, - ) - @action_method def add_route_predicate(self, name, factory, weighs_more_than=None, weighs_less_than=None): @@ -564,49 +452,3 @@ class RoutesConfiguratorMixin(object): self.registry.registerUtility(mapper, IRoutesMapper) return mapper - def _add_view_from_route(self, - route_name, - view, - context, - permission, - renderer, - attr, - ): - if view: - self.add_view( - permission=permission, - context=context, - view=view, - name='', - route_name=route_name, - renderer=renderer, - attr=attr, - ) - else: - # prevent mistakes due to misunderstanding of how hybrid calls to - # add_route and add_view interact - if attr: - raise ConfigurationError( - 'view_attr argument not permitted without view ' - 'argument') - if context: - raise ConfigurationError( - 'view_context argument not permitted without view ' - 'argument') - if permission: - raise ConfigurationError( - 'view_permission argument not permitted without view ' - 'argument') - if renderer: - raise ConfigurationError( - 'view_renderer argument not permitted without ' - 'view argument') - - warnings.warn( - 'Passing view-related arguments to add_route() is deprecated as of ' - 'Pyramid 1.1. Use add_view() to associate a view with a route ' - 'instead. See "Deprecations" in "What\'s New in Pyramid 1.1" ' - 'within the general Pyramid documentation for further details.', - DeprecationWarning, - 4) - diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 243c017fa..a4b681347 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1910,27 +1910,16 @@ class StaticURLInfo(object): # Mutate extra to allow factory, etc to be passed through here. # Treat permission specially because we'd like to default to - # permissiveness (see docs of config.add_static_view). We need - # to deal with both ``view_permission`` and ``permission`` - # because ``permission`` is used in the docs for add_static_view, - # but ``add_route`` prefers ``view_permission`` - permission = extra.pop('view_permission', None) - if permission is None: - permission = extra.pop('permission', None) + # permissiveness (see docs of config.add_static_view). + permission = extra.pop('permission', None) if permission is None: permission = NO_PERMISSION_REQUIRED - context = extra.pop('view_context', None) - if context is None: - context = extra.pop('view_for', None) + context = extra.pop('context', None) if context is None: context = extra.pop('for_', None) - renderer = extra.pop('view_renderer', None) - if renderer is None: - renderer = extra.pop('renderer', None) - - attr = extra.pop('view_attr', None) + renderer = extra.pop('renderer', None) # register a route using the computed view, permission, and # pattern, plus any extras passed to us via add_static_view @@ -1946,7 +1935,6 @@ class StaticURLInfo(object): permission=permission, context=context, renderer=renderer, - attr=attr ) def register(): diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index a7ef65fe8..14054421e 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -1182,205 +1182,6 @@ pyramid.tests.test_config.dummy_include2""", foo_meth = config.foo self.assertTrue(getattr(foo_meth, im_func) is foo) -class TestConfiguratorDeprecatedFeatures(unittest.TestCase): - - def setUp(self): - self.warnings = warnings.catch_warnings() - self.warnings.__enter__() - warnings.filterwarnings('ignore') - - def tearDown(self): - self.warnings.__exit__(None, None, None) - - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - config.registry._dont_resolve_responses = True - return config - - def _getRouteRequestIface(self, config, name): - from pyramid.interfaces import IRouteRequest - iface = config.registry.getUtility(IRouteRequest, name) - return iface - - def _getViewCallable(self, config, ctx_iface=None, request_iface=None, - name='', exception_view=False): - from zope.interface import Interface - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - if exception_view: - classifier = IExceptionViewClassifier - else: - classifier = IViewClassifier - if ctx_iface is None: - ctx_iface = Interface - return config.registry.adapters.lookup( - (classifier, request_iface, ctx_iface), IView, name=name, - default=None) - - def _assertRoute(self, config, name, path, num_predicates=0): - from pyramid.interfaces import IRoutesMapper - mapper = config.registry.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, name) - self.assertEqual(route.path, path) - self.assertEqual(len(routes[0].predicates), num_predicates) - return route - - def _makeRequest(self, config): - request = DummyRequest() - request.registry = config.registry - return request - - def test_add_route_with_view(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_renderer=null_renderer) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - - def test_add_route_with_view_context(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_context=IDummy, - view_renderer=null_renderer) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, IDummy, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable(config, IOther, request_type) - self.assertEqual(wrapper, None) - - def test_add_route_with_view_exception(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_context=RuntimeError, - view_renderer=null_renderer) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), - request_iface=request_type, exception_view=True) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable( - config, ctx_iface=IOther, - request_iface=request_type, exception_view=True) - self.assertEqual(wrapper, None) - - def test_add_route_with_view_for(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_for=IDummy, - view_renderer=null_renderer) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, IDummy, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable(config, IOther, request_type) - self.assertEqual(wrapper, None) - - def test_add_route_with_for_(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, for_=IDummy, - view_renderer=null_renderer) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, IDummy, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable(config, IOther, request_type) - self.assertEqual(wrapper, None) - - def test_add_route_with_view_renderer(self): - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, - view_renderer='json') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, b'"OK"') - - def test_add_route_with_view_attr(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - class View(object): - def __init__(self, context, request): - pass - def alt(self): - return 'OK' - config.add_route('name', 'path', view=View, view_attr='alt', - view_renderer=null_renderer) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - request = self._makeRequest(config) - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_route_with_view_renderer_alias(self): - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, - renderer='json') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, b'"OK"') - - def test_add_route_with_view_permission(self): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - config = self._makeOne(autocommit=True) - policy = lambda *arg: None - config.registry.registerUtility(policy, IAuthenticationPolicy) - config.registry.registerUtility(policy, IAuthorizationPolicy) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_permission='edit') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertTrue(hasattr(wrapper, '__call_permissive__')) - - def test_add_route_with_view_permission_alias(self): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - config = self._makeOne(autocommit=True) - policy = lambda *arg: None - config.registry.registerUtility(policy, IAuthenticationPolicy) - config.registry.registerUtility(policy, IAuthorizationPolicy) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, permission='edit') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertTrue(hasattr(wrapper, '__call_permissive__')) - - def test_conflict_route_with_view(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - config.add_route('a', '/a', view=view1) - config.add_route('a', '/a', view=view2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'test_conflict_route_with_view') - self.assertEqual(c2, 'test_conflict_route_with_view') - else: # pragma: no cover - raise AssertionError - class TestConfigurator_add_directive(unittest.TestCase): def setUp(self): diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 618ac2bf4..848642aee 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -3777,27 +3777,13 @@ class TestStaticURLInfo(unittest.TestCase): permission='abc') self.assertEqual(config.view_kw['permission'], 'abc') - def test_add_viewname_with_view_permission(self): + def test_add_viewname_with_context(self): config = self._makeConfig() inst = self._makeOne() inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1, - view_permission='abc') - self.assertEqual(config.view_kw['permission'], 'abc') - - def test_add_viewname_with_view_context(self): - config = self._makeConfig() - inst = self._makeOne() - inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1, - view_context=DummyContext) + context=DummyContext) self.assertEqual(config.view_kw['context'], DummyContext) - - def test_add_viewname_with_view_for(self): - config = self._makeConfig() - inst = self._makeOne() - inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1, - view_for=DummyContext) - self.assertEqual(config.view_kw['context'], DummyContext) - + def test_add_viewname_with_for_(self): config = self._makeConfig() inst = self._makeOne() @@ -3805,14 +3791,6 @@ class TestStaticURLInfo(unittest.TestCase): for_=DummyContext) self.assertEqual(config.view_kw['context'], DummyContext) - def test_add_viewname_with_view_renderer(self): - config = self._makeConfig() - inst = self._makeOne() - inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1, - view_renderer='mypackage:templates/index.pt') - self.assertEqual(config.view_kw['renderer'], - 'mypackage:templates/index.pt') - def test_add_viewname_with_renderer(self): config = self._makeConfig() inst = self._makeOne() @@ -3821,13 +3799,6 @@ class TestStaticURLInfo(unittest.TestCase): self.assertEqual(config.view_kw['renderer'], 'mypackage:templates/index.pt') - def test_add_viewname_with_view_attr(self): - config = self._makeConfig() - inst = self._makeOne() - inst.add(config, 'view', 'anotherpackage:path', cache_max_age=1, - view_attr='attr') - self.assertEqual(config.view_kw['attr'], 'attr') - class Test_view_description(unittest.TestCase): def _callFUT(self, view): from pyramid.config.views import view_description -- cgit v1.2.3 From 8fe57d871af1321b0e2b853c559d8e5c127db5fa Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 21:24:04 -0400 Subject: - Removed the ability to influence and query a ``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. --- CHANGES.txt | 7 ++ pyramid/compat.py | 2 +- pyramid/request.py | 89 +----------------------- pyramid/testing.py | 9 +-- pyramid/tests/test_request.py | 157 ------------------------------------------ 5 files changed, 12 insertions(+), 252 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 69547ad46..641219a8b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -91,6 +91,13 @@ Backwards Incompatibilities ``pyramid.config.Configurator.add_static_view`` function too, because it delegates to ``add_route``. +- Removed the ability to influence and query a ``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. + 1.5a1 (2013-08-30) ================== diff --git a/pyramid/compat.py b/pyramid/compat.py index 222810b3b..bfa345b88 100644 --- a/pyramid/compat.py +++ b/pyramid/compat.py @@ -160,7 +160,7 @@ if PY3: # pragma: no cover return d.values() def iterkeys_(d): return d.keys() -else: +else: # pragma: no cover def iteritems_(d): return d.iteritems() def itervalues_(d): diff --git a/pyramid/request.py b/pyramid/request.py index 5c064d3ef..2cf0613f7 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -1,7 +1,5 @@ import json -from zope.deprecation import deprecate -from zope.deprecation.deprecation import deprecated from zope.interface import implementer from zope.interface.interface import InterfaceClass @@ -15,9 +13,6 @@ from pyramid.interfaces import ( ) from pyramid.compat import ( - iterkeys_, - itervalues_, - iteritems_, text_, bytes_, native_, @@ -32,85 +27,6 @@ from pyramid.util import InstancePropertyMixin class TemplateContext(object): pass -class DeprecatedRequestMethodsMixin(object): - - # b/c dict interface for "root factory" code that expects a bare - # environ. Explicitly omitted dict methods: clear (unnecessary), - # copy (implemented by WebOb), fromkeys (unnecessary); deprecated - # as of Pyramid 1.1. - - dictlike = ('Use of the request as a dict-like object is deprecated as ' - 'of Pyramid 1.1. Use dict-like methods of "request.environ" ' - 'instead.') - - @deprecate(dictlike) - def __contains__(self, k): - return self.environ.__contains__(k) - - @deprecate(dictlike) - def __delitem__(self, k): - return self.environ.__delitem__(k) - - @deprecate(dictlike) - def __getitem__(self, k): - return self.environ.__getitem__(k) - - @deprecate(dictlike) - def __iter__(self): - return iter(self.environ) - - @deprecate(dictlike) - def __setitem__(self, k, v): - self.environ[k] = v - - @deprecate(dictlike) - def get(self, k, default=None): - return self.environ.get(k, default) - - @deprecate(dictlike) - def has_key(self, k): - return k in self.environ - - @deprecate(dictlike) - def items(self): - return self.environ.items() - - @deprecate(dictlike) - def iteritems(self): - return iteritems_(self.environ) - - @deprecate(dictlike) - def iterkeys(self): - return iterkeys_(self.environ) - - @deprecate(dictlike) - def itervalues(self): - return itervalues_(self.environ) - - @deprecate(dictlike) - def keys(self): - return self.environ.keys() - - @deprecate(dictlike) - def pop(self, k): - return self.environ.pop(k) - - @deprecate(dictlike) - def popitem(self): - return self.environ.popitem() - - @deprecate(dictlike) - def setdefault(self, v, default): - return self.environ.setdefault(v, default) - - @deprecate(dictlike) - def update(self, v, **kw): - return self.environ.update(v, **kw) - - @deprecate(dictlike) - def values(self): - return self.environ.values() - class CallbackMethodsMixin(object): response_callbacks = () finished_callbacks = () @@ -220,9 +136,8 @@ class CallbackMethodsMixin(object): callback(self) @implementer(IRequest) -class Request(BaseRequest, DeprecatedRequestMethodsMixin, URLMethodsMixin, - CallbackMethodsMixin, InstancePropertyMixin, - LocalizerRequestMixin): +class Request(BaseRequest, URLMethodsMixin, CallbackMethodsMixin, + InstancePropertyMixin, LocalizerRequestMixin): """ A subclass of the :term:`WebOb` Request class. An instance of this class is created by the :term:`router` and is provided to a diff --git a/pyramid/testing.py b/pyramid/testing.py index 36c690117..789047ab3 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -34,12 +34,8 @@ from pyramid.threadlocal import ( manager, ) -from pyramid.request import ( - DeprecatedRequestMethodsMixin, - CallbackMethodsMixin, - ) - from pyramid.i18n import LocalizerRequestMixin +from pyramid.request import CallbackMethodsMixin from pyramid.url import URLMethodsMixin from pyramid.util import InstancePropertyMixin @@ -286,8 +282,7 @@ class DummySession(dict): @implementer(IRequest) -class DummyRequest(DeprecatedRequestMethodsMixin, URLMethodsMixin, - CallbackMethodsMixin, InstancePropertyMixin, +class DummyRequest(URLMethodsMixin, CallbackMethodsMixin, InstancePropertyMixin, LocalizerRequestMixin): """ A DummyRequest object (incompletely) imitates a :term:`request` object. diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index 565c6377e..6cd72fc59 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -308,163 +308,6 @@ class TestRequest(unittest.TestCase): self.assertEqual(1, request.db) self.assertEqual(1, request.db) -class TestRequestDeprecatedMethods(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - from zope.deprecation import __show__ - __show__.off() - - def tearDown(self): - testing.tearDown() - from zope.deprecation import __show__ - __show__.on() - - def _getTargetClass(self): - from pyramid.request import Request - return Request - - def _makeOne(self, environ=None): - if environ is None: - environ = {} - return self._getTargetClass()(environ) - - def test___contains__(self): - environ ={'zooma':1} - inst = self._makeOne(environ) - self.assertTrue('zooma' in inst) - - def test___delitem__(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - del inst['zooma'] - self.assertFalse('zooma' in environ) - - def test___getitem__(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst['zooma'], 1) - - def test___iter__(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - iterator = iter(inst) - self.assertEqual(list(iterator), list(iter(environ))) - - def test___setitem__(self): - environ = {} - inst = self._makeOne(environ) - inst['zooma'] = 1 - self.assertEqual(environ, {'zooma':1}) - - def test_get(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.get('zooma'), 1) - - def test_has_key(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.has_key('zooma'), True) - - def test_items(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.items(), environ.items()) - - def test_iteritems(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(list(inst.iteritems()), list(iteritems_(environ))) - - def test_iterkeys(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(list(inst.iterkeys()), list(iterkeys_(environ))) - - def test_itervalues(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(list(inst.itervalues()), list(itervalues_(environ))) - - def test_keys(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.keys(), environ.keys()) - - def test_pop(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - popped = inst.pop('zooma') - self.assertEqual(environ, {}) - self.assertEqual(popped, 1) - - def test_popitem(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - popped = inst.popitem() - self.assertEqual(environ, {}) - self.assertEqual(popped, ('zooma', 1)) - - def test_setdefault(self): - environ = {} - inst = self._makeOne(environ) - marker = [] - result = inst.setdefault('a', marker) - self.assertEqual(environ, {'a':marker}) - self.assertEqual(result, marker) - - def test_update(self): - environ = {} - inst = self._makeOne(environ) - inst.update({'a':1}, b=2) - self.assertEqual(environ, {'a':1, 'b':2}) - - def test_values(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - result = list(inst.values()) - self.assertEqual(result, list(environ.values())) - - def test_response_content_type(self): - inst = self._makeOne() - self.assertFalse(hasattr(inst, 'response_content_type')) - inst.response_content_type = 'abc' - self.assertEqual(inst.response_content_type, 'abc') - del inst.response_content_type - self.assertFalse(hasattr(inst, 'response_content_type')) - - def test_response_headerlist(self): - inst = self._makeOne() - self.assertFalse(hasattr(inst, 'response_headerlist')) - inst.response_headerlist = 'abc' - self.assertEqual(inst.response_headerlist, 'abc') - del inst.response_headerlist - self.assertFalse(hasattr(inst, 'response_headerlist')) - - def test_response_status(self): - inst = self._makeOne() - self.assertFalse(hasattr(inst, 'response_status')) - inst.response_status = 'abc' - self.assertEqual(inst.response_status, 'abc') - del inst.response_status - self.assertFalse(hasattr(inst, 'response_status')) - - def test_response_charset(self): - inst = self._makeOne() - self.assertFalse(hasattr(inst, 'response_charset')) - inst.response_charset = 'abc' - self.assertEqual(inst.response_charset, 'abc') - del inst.response_charset - self.assertFalse(hasattr(inst, 'response_charset')) - - def test_response_cache_for(self): - inst = self._makeOne() - self.assertFalse(hasattr(inst, 'response_cache_for')) - inst.response_cache_for = 'abc' - self.assertEqual(inst.response_cache_for, 'abc') - del inst.response_cache_for - self.assertFalse(hasattr(inst, 'response_cache_for')) - class Test_route_request_iface(unittest.TestCase): def _callFUT(self, name): from pyramid.request import route_request_iface -- cgit v1.2.3 From 6d14fa5f0aa469ecd096d92a787281d3d87776cf Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 21:34:52 -0400 Subject: update --- TODO.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/TODO.txt b/TODO.txt index 46eb33b82..9850bd761 100644 --- a/TODO.txt +++ b/TODO.txt @@ -121,22 +121,15 @@ Nice-to-Have Future ------ -- 1.5: remove ``pyramid.view.static`` and ``pyramid.view.is_response``. - - 1.5: turn ``pyramid.settings.Settings`` into a function that returns the original dict (after ``__getattr__`` deprecation period, it was deprecated in 1.2). -- 1.5: Remove ``pyramid.requests.DeprecatedRequestMethodsMixin`` and code in - renderers module that looks for _response_content_type, et. al. - - 1.5: Maybe? deprecate set_request_property in favor of pointing people at add_request_method, schedule removal for 1.8? - 1.5: Remove pyramid.config.rendering set_renderer_globals_factory maybe. -- 1.5: remove pyramid.config.route _add_view_from_route function. - - 1.6: Remove IContextURL and TraversalContextURL. - 1.7: Change ``pyramid.authentication.AuthTktAuthenticationPolicy`` default -- cgit v1.2.3 From 95e97113b3fe108a1dbf908ae6716b89e786c91d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 22:34:08 -0400 Subject: - 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. --- CHANGES.txt | 4 ++++ pyramid/tests/test_traversal.py | 15 +++------------ pyramid/traversal.py | 7 +------ 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 641219a8b..6abef1e6b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -98,6 +98,10 @@ Backwards Incompatibilities 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. + 1.5a1 (2013-08-30) ================== diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py index ff5937811..0dcc4a027 100644 --- a/pyramid/tests/test_traversal.py +++ b/pyramid/tests/test_traversal.py @@ -1278,22 +1278,13 @@ class TestDefaultRootFactory(unittest.TestCase): def _makeOne(self, environ): return self._getTargetClass()(environ) - def test_no_matchdict(self): - class DummyRequest: - matchdict = None + def test_it(self): + class DummyRequest(object): + pass root = self._makeOne(DummyRequest()) self.assertEqual(root.__parent__, None) self.assertEqual(root.__name__, None) - def test_matchdict(self): - class DummyRequest: - pass - request = DummyRequest() - request.matchdict = {'a':1, 'b':2} - root = self._makeOne(request) - self.assertEqual(root.a, 1) - self.assertEqual(root.b, 2) - class Test__join_path_tuple(unittest.TestCase): def _callFUT(self, tup): from pyramid.traversal import _join_path_tuple diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 341ed2d75..4c275c4c1 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -822,9 +822,4 @@ class DefaultRootFactory: __parent__ = None __name__ = None def __init__(self, request): - matchdict = request.matchdict - # provide backwards compatibility for applications which - # used routes (at least apps without any custom "context - # factory") in BFG 0.9.X and before - if matchdict is not None: - self.__dict__.update(matchdict) + pass -- cgit v1.2.3 From c6601f77f91dc933ca429d1448f4c6b27857b608 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 22:52:54 -0400 Subject: - The ``renderer_globals_factory`` argument to the ``pyramid.config.Configurator` constructor and its ``setup_registry`` method has been removed. The ``set_renderer_globals_factory`` method of ``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. --- CHANGES.txt | 10 +++++ docs/api/config.rst | 4 -- docs/glossary.rst | 7 ++- docs/narr/advconfig.rst | 1 - docs/narr/hooks.rst | 66 +---------------------------- docs/narr/introspector.rst | 12 ------ docs/whatsnew-1.1.rst | 9 ++-- pyramid/config/__init__.py | 23 ---------- pyramid/config/rendering.py | 44 ------------------- pyramid/events.py | 5 +-- pyramid/interfaces.py | 9 ---- pyramid/renderers.py | 8 ---- pyramid/tests/test_config/test_init.py | 29 ------------- pyramid/tests/test_config/test_rendering.py | 25 ----------- pyramid/tests/test_renderers.py | 10 ----- 15 files changed, 20 insertions(+), 242 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6abef1e6b..5cfd5e70d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -102,6 +102,16 @@ Backwards Incompatibilities ``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 + ``pyramid.config.Configurator` constructor and its ``setup_registry`` method + has been removed. The ``set_renderer_globals_factory`` method of + ``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. + 1.5a1 (2013-08-30) ================== diff --git a/docs/api/config.rst b/docs/api/config.rst index 1f65be9f1..48dd2f0b9 100644 --- a/docs/api/config.rst +++ b/docs/api/config.rst @@ -52,10 +52,6 @@ .. automethod:: override_asset(to_override, override_with) - :methodcategory:`Setting Renderer Globals` - - .. automethod:: set_renderer_globals_factory(factory) - :methodcategory:`Getting and Adding Settings` .. automethod:: add_settings diff --git a/docs/glossary.rst b/docs/glossary.rst index 8ade889a3..7dc69c7c4 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -798,9 +798,8 @@ Glossary :term:`Internationalization`. renderer globals - Values injected as names into a renderer based on application - policy. See :ref:`adding_renderer_globals` for more - information. + Values injected as names into a renderer by a + :class:`pyramid.event.BeforeRender` event. response callback A user-defined callback executed by the :term:`router` at a @@ -1021,4 +1020,4 @@ Glossary add-on A Python :term:`distribution` that uses Pyramid's extensibility to plug into a Pyramid application and provide extra, - configurable services. \ No newline at end of file + configurable services. diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 1b8e33de3..d3431e39e 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -302,7 +302,6 @@ These are the methods of the configurator which provide conflict detection: :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`, :meth:`~pyramid.config.Configurator.set_default_permission`, :meth:`~pyramid.config.Configurator.add_traverser`, diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a7dc3e78b..0c450fad7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -372,10 +372,8 @@ that can be used for this purpose. For example: def add_global(event): event['mykey'] = 'foo' -An object of this type is sent as an event just before a :term:`renderer` is -invoked (but *after* the application-level renderer globals factory added via -:class:`~pyramid.config.Configurator.set_renderer_globals_factory`, if any, -has injected its own keys into the renderer globals dictionary). +An object of this type is sent as an event just before a :term:`renderer` +is invoked. If a subscriber attempts to add a key that already exist in the renderer globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced @@ -417,66 +415,6 @@ your view callable, like so: See the API documentation for the :class:`~pyramid.events.BeforeRender` event interface at :class:`pyramid.interfaces.IBeforeRender`. -Another (deprecated) mechanism which allows event subscribers more control -when adding renderer global values exists in :ref:`adding_renderer_globals`. - -.. index:: - single: adding renderer globals - -.. _adding_renderer_globals: - -Adding Renderer Globals (Deprecated) ------------------------------------- - -.. deprecated:: 1.1 - An alternative mechanism which allows event subscribers to add renderer - global values 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` -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``, ``view``, and -``renderer_name``) are the only values present in the system dictionary -passed to every renderer. - -A callback that :app:`Pyramid` will call every time a renderer is invoked can -be added by passing a ``renderer_globals_factory`` argument to the -constructor of the :term:`configurator`. This callback can either be a -callable object or a :term:`dotted Python name` representing such a callable. - -.. code-block:: python - :linenos: - - def renderer_globals_factory(system): - return {'a': 1} - - config = Configurator( - renderer_globals_factory=renderer_globals_factory) - -Such a callback must accept a single positional argument (notionally named -``system``) which will contain the original system values. It must return a -dictionary of values that will be merged into the system dictionary. See -:ref:`renderer_system_values` for description of the values present in the -system dictionary. - -If you're doing imperative configuration, and you'd rather do it after you've -already constructed a :term:`configurator` it can also be registered via the -:meth:`pyramid.config.Configurator.set_renderer_globals_factory` method: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def renderer_globals_factory(system): - return {'a': 1} - - config = Configurator() - config.set_renderer_globals_factory(renderer_globals_factory) - - .. index:: single: response callback diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index dec22c5b1..3c0a6744f 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -232,18 +232,6 @@ introspectables in categories not described here. The factory object (the resolved ``factory`` argument to ``add_renderer``). -``renderer globals factory`` - - There will be one and only one introspectable in the ``renderer globals - factory`` category. It represents a call to - :meth:`pyramid.config.Configurator.set_renderer_globals_factory`; it will - have the following data. - - ``factory`` - - The factory object (the resolved ``factory`` argument to - ``set_renderer_globals_factory``). - ``routes`` Each introspectable in the ``routes`` category represents a call to diff --git a/docs/whatsnew-1.1.rst b/docs/whatsnew-1.1.rst index cc63017df..086c12ca2 100644 --- a/docs/whatsnew-1.1.rst +++ b/docs/whatsnew-1.1.rst @@ -540,11 +540,10 @@ Deprecations and Behavior Differences within a static view returns the index.html properly. See also https://github.com/Pylons/pyramid/issues/67. -- Deprecated the - :meth:`pyramid.config.Configurator.set_renderer_globals_factory` method and - the ``renderer_globals`` Configurator constructor parameter. Users should - convert code using this feature to use a BeforeRender event. See the section - :ref:`beforerender_event` in the Hooks chapter. +- Deprecated the ``pyramid.config.Configurator.set_renderer_globals_factory`` + method and the ``renderer_globals`` Configurator constructor parameter. + Users should convert code using this feature to use a BeforeRender event. See + the section :ref:`beforerender_event` in the Hooks chapter. - In Pyramid 1.0, the :class:`pyramid.events.subscriber` directive behaved contrary to the documentation when passed more than one interface object to diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index f1f24fbc1..0c3a836df 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -173,15 +173,6 @@ class Configurator( See :ref:`changing_the_request_factory`. By default it is ``None``, which means use the default request factory. - If ``renderer_globals_factory`` is passed, it should be a :term:`renderer - globals` factory implementation or a :term:`dotted Python name` to the - same. See :ref:`adding_renderer_globals`. By default, it is ``None``, - which means use no renderer globals factory. - - .. deprecated:: 1.1 - Use a BeforeRender event subscriber as per :ref:`beforerender_event` - in place of ``renderer_globals_factory``. - If ``default_permission`` is passed, it should be a :term:`permission` string to be used as the default permission for all view configuration registrations performed against this @@ -273,7 +264,6 @@ class Configurator( debug_logger=None, locale_negotiator=None, request_factory=None, - renderer_globals_factory=None, default_permission=None, session_factory=None, default_view_mapper=None, @@ -304,7 +294,6 @@ class Configurator( debug_logger=debug_logger, locale_negotiator=locale_negotiator, request_factory=request_factory, - renderer_globals_factory=renderer_globals_factory, default_permission=default_permission, session_factory=session_factory, default_view_mapper=default_view_mapper, @@ -320,7 +309,6 @@ class Configurator( debug_logger=None, locale_negotiator=None, request_factory=None, - renderer_globals_factory=None, default_permission=None, session_factory=None, default_view_mapper=None, @@ -410,17 +398,6 @@ class Configurator( if request_factory: self.set_request_factory(request_factory) - if renderer_globals_factory: - warnings.warn( - 'Passing ``renderer_globals_factory`` as a Configurator ' - 'constructor parameter is deprecated as of Pyramid 1.1. ' - 'Use a BeforeRender event subscriber as documented in the ' - '"Hooks" chapter of the Pyramid narrative documentation ' - 'instead', - DeprecationWarning, - 2) - self.set_renderer_globals_factory(renderer_globals_factory, - warn=False) if default_permission: self.set_default_permission(default_permission) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index a301b9c43..258c5a566 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -1,8 +1,5 @@ -import warnings - from pyramid.interfaces import ( IRendererFactory, - IRendererGlobalsFactory, PHASE1_CONFIG, ) @@ -48,44 +45,3 @@ class RenderingConfiguratorMixin(object): self.action((IRendererFactory, name), register, order=PHASE1_CONFIG, introspectables=(intr,)) - @action_method - def set_renderer_globals_factory(self, factory, warn=True): - """ The object passed as ``factory`` should be an callable (or - a :term:`dotted Python name` which refers to an callable) that - will be used by the :app:`Pyramid` rendering machinery as a - renderers global factory (see :ref:`adding_renderer_globals`). - - The ``factory`` callable must accept a single argument named - ``system`` (which will be a dictionary) and it must return a - dictionary. When an application uses a renderer, the - factory's return dictionary will be merged into the ``system`` - dictionary, and therefore will be made available to the code - which uses the renderer. - - .. deprecated:: 1.1 - Use a BeforeRender event subscriber as documented in the - :ref:`hooks_chapter` chapter instead. - - .. note:: - - Using the ``renderer_globals_factory`` argument - to the :class:`pyramid.config.Configurator` constructor - can be used to achieve the same purpose. - """ - if warn: - warnings.warn( - 'Calling the ``set_renderer_globals`` method of a Configurator ' - 'is deprecated as of Pyramid 1.1. Use a BeforeRender event ' - 'subscriber as documented in the "Hooks" chapter of the ' - 'Pyramid narrative documentation instead', - DeprecationWarning, - 3) - - factory = self.maybe_dotted(factory) - def register(): - self.registry.registerUtility(factory, IRendererGlobalsFactory) - intr = self.introspectable('renderer globals factory', None, - self.object_description(factory), - 'renderer globals factory') - intr['factory'] = factory - self.action(IRendererGlobalsFactory, register) diff --git a/pyramid/events.py b/pyramid/events.py index 31af8e1fc..ca10e2893 100644 --- a/pyramid/events.py +++ b/pyramid/events.py @@ -192,10 +192,7 @@ class BeforeRender(dict): event['mykey'] = 'foo' An object of this type is sent as an event just before a :term:`renderer` - is invoked (but *after* the -- deprecated -- application-level renderer - globals factory added via - :class:`pyramid.config.Configurator.set_renderer_globals_factory`, if - any, has injected its own keys into the renderer globals dictionary). + is invoked. If a subscriber adds a key via ``__setitem__`` that already exists in the renderer globals dictionary, it will overwrite the older value there. diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 1d5688195..85b2227b4 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -616,15 +616,6 @@ class IRendererFactory(Interface): """ Return an object that implements ``IRenderer``. ``info`` is an object that implement ``IRendererInfo``. """ -class IRendererGlobalsFactory(Interface): - def __call__(system_values): - """ Return a dictionary of global renderer values (aka - top-level template names). The ``system_values`` value passed - in will be a dictionary that includes at least a ``request`` - key, indicating the current request, and the value - ``renderer_name``, which will be the name of the renderer in - use.""" - class IViewPermission(Interface): def __call__(context, request): """ Return True if the permission allows, return False if it denies. """ diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 6f088a54f..d8542decc 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -9,7 +9,6 @@ from zope.interface.registry import Components from pyramid.interfaces import ( IJSONAdapter, - IRendererGlobalsFactory, IRendererFactory, IResponseFactory, IRendererInfo, @@ -425,13 +424,6 @@ class RendererHelper(object): system_values = BeforeRender(system_values, value) registry = self.registry - globals_factory = registry.queryUtility(IRendererGlobalsFactory) - - if globals_factory is not None: - renderer_globals = globals_factory(system_values) - if renderer_globals: - system_values.update(renderer_globals) - registry.notify(system_values) result = renderer(value, system_values) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index 14054421e..a0333b66d 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -550,35 +550,6 @@ class ConfiguratorTests(unittest.TestCase): utility = reg.getUtility(IRequestFactory) self.assertEqual(utility, pyramid.tests.test_config) - def test_setup_registry_renderer_globals_factory(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRendererGlobalsFactory - reg = Registry() - config = self._makeOne(reg) - factory = object() - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - config.setup_registry(renderer_globals_factory=factory) - self.assertEqual(reg.queryUtility(IRendererGlobalsFactory), None) - config.commit() - utility = reg.getUtility(IRendererGlobalsFactory) - self.assertEqual(utility, factory) - - def test_setup_registry_renderer_globals_factory_dottedname(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRendererGlobalsFactory - reg = Registry() - config = self._makeOne(reg) - import pyramid.tests.test_config - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - config.setup_registry( - renderer_globals_factory='pyramid.tests.test_config') - self.assertEqual(reg.queryUtility(IRendererGlobalsFactory), None) - config.commit() - utility = reg.getUtility(IRendererGlobalsFactory) - self.assertEqual(utility, pyramid.tests.test_config) - def test_setup_registry_alternate_renderers(self): from pyramid.registry import Registry from pyramid.interfaces import IRendererFactory diff --git a/pyramid/tests/test_config/test_rendering.py b/pyramid/tests/test_config/test_rendering.py index e6ee9ad70..2c3730775 100644 --- a/pyramid/tests/test_config/test_rendering.py +++ b/pyramid/tests/test_config/test_rendering.py @@ -1,7 +1,4 @@ import unittest -import warnings - -from pyramid.tests.test_config import dummyfactory class TestRenderingConfiguratorMixin(unittest.TestCase): def _makeOne(self, *arg, **kw): @@ -9,28 +6,6 @@ class TestRenderingConfiguratorMixin(unittest.TestCase): config = Configurator(*arg, **kw) return config - def test_set_renderer_globals_factory(self): - from pyramid.interfaces import IRendererGlobalsFactory - config = self._makeOne(autocommit=True) - factory = object() - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - config.set_renderer_globals_factory(factory) - self.assertEqual( - config.registry.getUtility(IRendererGlobalsFactory), - factory) - - def test_set_renderer_globals_factory_dottedname(self): - from pyramid.interfaces import IRendererGlobalsFactory - config = self._makeOne(autocommit=True) - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - config.set_renderer_globals_factory( - 'pyramid.tests.test_config.dummyfactory') - self.assertEqual( - config.registry.getUtility(IRendererGlobalsFactory), - dummyfactory) - def test_add_renderer(self): from pyramid.interfaces import IRendererFactory config = self._makeOne(autocommit=True) diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index 0b67462bb..f6b9d2b0d 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -255,16 +255,6 @@ class TestRendererHelper(unittest.TestCase): self.assertEqual(result[0], 'values') self.assertEqual(result[1], system) - def test_render_renderer_globals_factory_active(self): - self._registerRendererFactory() - from pyramid.interfaces import IRendererGlobalsFactory - def rg(system): - return {'a':1} - self.config.registry.registerUtility(rg, IRendererGlobalsFactory) - helper = self._makeOne('loo.foo') - result = helper.render('values', None) - self.assertEqual(result[1]['a'], 1) - def test__make_response_request_is_None(self): request = None helper = self._makeOne('loo.foo') -- cgit v1.2.3 From 72b93ff249c792381f3628b36541a318f8666e6e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 22:53:54 -0400 Subject: garden --- TODO.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/TODO.txt b/TODO.txt index 9850bd761..ee7391297 100644 --- a/TODO.txt +++ b/TODO.txt @@ -121,14 +121,12 @@ Nice-to-Have Future ------ -- 1.5: turn ``pyramid.settings.Settings`` into a function that returns the - original dict (after ``__getattr__`` deprecation period, it was deprecated - in 1.2). - - 1.5: Maybe? deprecate set_request_property in favor of pointing people at add_request_method, schedule removal for 1.8? -- 1.5: Remove pyramid.config.rendering set_renderer_globals_factory maybe. +- 1.6: turn ``pyramid.settings.Settings`` into a function that returns the + original dict (after ``__getattr__`` deprecation period, it was deprecated + in 1.2). - 1.6: Remove IContextURL and TraversalContextURL. -- cgit v1.2.3 From b01f1d02edaf863394ce487365e7d83446e1a95d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 23:10:41 -0400 Subject: issue warnings when custom_predicates argument is used to add_route or add_view --- pyramid/config/routes.py | 14 ++++++++++++++ pyramid/config/views.py | 14 ++++++++++++++ pyramid/tests/test_config/test_routes.py | 6 +++++- pyramid/tests/test_config/test_views.py | 24 ++++++++++++++++++------ 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index c31bd7195..9dca9e51e 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -1,3 +1,5 @@ +import warnings + from pyramid.compat import urlparse from pyramid.interfaces import ( IRequest, @@ -277,6 +279,18 @@ class RoutesConfiguratorMixin(object): .. versionadded:: 1.4 """ + if custom_predicates: + warnings.warn( + ('The "custom_predicates" argument to Configurator.add_route ' + 'is deprecated as of Pyramid 1.5. Use ' + '"config.add_route_predicate" and use the registered ' + 'route predicate as a predicate argument to add_route ' + 'instead. See "Adding A Third Party View, Route, or ' + 'Subscriber Predicate" in the "Hooks" chapter of the ' + 'documentation for more information.'), + DeprecationWarning, + stacklevel=3 + ) # these are route predicates; if they do not match, the next route # in the routelist will be tried if request_method is not None: diff --git a/pyramid/config/views.py b/pyramid/config/views.py index a4b681347..16deee987 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1,6 +1,7 @@ import inspect import operator import os +import warnings from zope.interface import ( Interface, @@ -1052,6 +1053,19 @@ class ViewsConfiguratorMixin(object): .. versionadded: 1.4a1 """ + if custom_predicates: + warnings.warn( + ('The "custom_predicates" argument to Configurator.add_view ' + 'is deprecated as of Pyramid 1.5. Use ' + '"config.add_view_predicate" and use the registered ' + 'view predicate as a predicate argument to add_view instead. ' + 'See "Adding A Third Party View, Route, or Subscriber ' + 'Predicate" in the "Hooks" chapter of the documentation ' + 'for more information.'), + DeprecationWarning, + stacklevel=4 + ) + view = self.maybe_dotted(view) context = self.maybe_dotted(context) for_ = self.maybe_dotted(for_) diff --git a/pyramid/tests/test_config/test_routes.py b/pyramid/tests/test_config/test_routes.py index 6fb5189f6..1d2530c02 100644 --- a/pyramid/tests/test_config/test_routes.py +++ b/pyramid/tests/test_config/test_routes.py @@ -153,10 +153,14 @@ class RoutesConfiguratorMixinTests(unittest.TestCase): self.assertEqual(predicate(None, request), False) def test_add_route_with_custom_predicates(self): + import warnings config = self._makeOne(autocommit=True) def pred1(context, request): pass def pred2(context, request): pass - config.add_route('name', 'path', custom_predicates=(pred1, pred2)) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_route('name', 'path', custom_predicates=(pred1, pred2)) + self.assertEqual(len(w), 1) route = self._assertRoute(config, 'name', 'path', 2) self.assertEqual(len(route.predicates), 2) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 848642aee..d9e0d17a6 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1391,6 +1391,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): self._assertNotFound(wrapper, None, request) def test_add_view_with_custom_predicates_match(self): + import warnings from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) @@ -1399,13 +1400,17 @@ class TestViewsConfigurationMixin(unittest.TestCase): def pred2(context, request): return True predicates = (pred1, pred2) - config.add_view(view=view, custom_predicates=predicates, - renderer=null_renderer) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, custom_predicates=predicates, + renderer=null_renderer) + self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_custom_predicates_nomatch(self): + import warnings view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) def pred1(context, request): @@ -1413,22 +1418,29 @@ class TestViewsConfigurationMixin(unittest.TestCase): def pred2(context, request): return False predicates = (pred1, pred2) - config.add_view(view=view, custom_predicates=predicates) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, custom_predicates=predicates) + self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) self._assertNotFound(wrapper, None, request) def test_add_view_custom_predicate_bests_standard_predicate(self): + import warnings from pyramid.renderers import null_renderer view = lambda *arg: 'OK' view2 = lambda *arg: 'NOT OK' config = self._makeOne(autocommit=True) def pred1(context, request): return True - config.add_view(view=view, custom_predicates=(pred1,), - renderer=null_renderer) - config.add_view(view=view2, request_method='GET', + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, custom_predicates=(pred1,), renderer=null_renderer) + config.add_view(view=view2, request_method='GET', + renderer=null_renderer) + self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'GET' -- cgit v1.2.3 From 26787cf215b9bb6ddc0cce84a777f7c2e3079842 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 23:28:30 -0400 Subject: done --- TODO.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index ee7391297..2aa1dc487 100644 --- a/TODO.txt +++ b/TODO.txt @@ -12,9 +12,6 @@ Nice-to-Have - Have action methods return their discriminators. -- Fix renderers chapter to better document system values passed to template - renderers. - - Modify view mapper narrative docs to not use pyramid_handlers. - Modify the urldispatch chapter examples to assume a scan rather than -- cgit v1.2.3