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 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 From dd5358b514b80d890149995ba0d65d7a18da29f1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 16:30:10 -0400 Subject: remove self-flagellation about number of dependencies --- docs/designdefense.rst | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index cebcf6218..5159e6ec7 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -627,22 +627,15 @@ over 2K lines of Python code, excluding tests. Pyramid Has Too Many Dependencies --------------------------------- -This is true. At the time of this writing (Pyramid 1.3), the total number of -Python package distributions that :app:`Pyramid` depends upon transitively is -if you use Python 3.2 or Python 2.7 is 10. If you use Python 2.6, Pyramid -will pull in 12 package distributions. This is a lot more than zero package -distribution dependencies: a metric which various Python microframeworks and -Django boast. - -However, Pyramid 1.2 relied on 15 packages under Python 2.7 and 17 packages -under Python 2.6, so we've made progress here. A port to Python 3 completed -in Pyramid 1.3 helped us shed a good number of dependencies by forcing us to -make better packaging decisions. - -In the future, we may also move templating system dependencies out of the -core and place them in add-on packages, to be included by developers instead -of by the framework. This would reduce the number of core dependencies by -about five, leaving us with only five remaining core dependencies. +Over time, we've made lots of progress on reducing the number of packaging +dependencies Pyramid has had. Pyramid 1.2 had 15 of them. Pyramid 1.3 and 1.4 +had 12 of them. The current release as of this writing, Pyramid 1.5, has +only 7. This number is unlikely to become any smaller. + +A port to Python 3 completed in Pyramid 1.3 helped us shed a good number of +dependencies by forcing us to make better packaging decisions. Removing +Chameleon and Mako templating system dependencies in the Pyramid core in 1.5 +let us shed most of the remainder of them. Pyramid "Cheats" To Obtain Speed -------------------------------- -- cgit v1.2.3 From 5614e9c86562f6e62cefe7de9f4b468e7a4489a6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 16:58:52 -0400 Subject: update numbers in pyramid-is-too-big section --- docs/designdefense.rst | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 5159e6ec7..50ef1b148 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -594,35 +594,32 @@ requires extensibility because it must be deployed in multiple locations. Pyramid Is Too Big ------------------ -"The :app:`Pyramid` compressed tarball is almost 2MB. It must be +"The :app:`Pyramid` compressed tarball is larger than 2MB. It must be enormous!" -No. We just ship it with test code and helper templates. Here's a +No. We just ship it with docs, test code, and scaffolding. Here's a breakdown of what's included in subdirectories of the package tree: docs/ - 3.0MB + 4.9MB pyramid/tests/ - 1.1MB + 2.0MB -pyramid/paster_templates/ +pyramid/scaffolds/ - 804KB + 460KB -pyramid/ (except for ``pyramd/tests and pyramid/paster_templates``) +pyramid/ (except for ``pyramd/tests`` and ``pyramid/scaffolds``) - 539K + 844KB -The actual :app:`Pyramid` runtime code is about 10% of the total size of the -tarball omitting docs, helper templates used for package generation, and test -code. Of the approximately 19K lines of Python code in the package, the code +Of the approximately 34K lines of Python code in the package, the code that actually has a chance of executing during normal operation, excluding -tests and paster template Python files, accounts for approximately 5K lines -of Python code. This is comparable to Pylons 1.X, which ships with a little -over 2K lines of Python code, excluding tests. +tests and scaffolding Python files, accounts for approximately 10K lines +of Python code. Pyramid Has Too Many Dependencies --------------------------------- -- cgit v1.2.3 From 643b2a8e7ef0b1836d910b4c5e74d302ed0a0052 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 17:03:10 -0400 Subject: wording --- docs/designdefense.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 50ef1b148..165ee3dbc 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -618,8 +618,8 @@ pyramid/ (except for ``pyramd/tests`` and ``pyramid/scaffolds``) Of the approximately 34K lines of Python code in the package, the code that actually has a chance of executing during normal operation, excluding -tests and scaffolding Python files, accounts for approximately 10K lines -of Python code. +tests and scaffolding Python files, accounts for approximately 10K lines. + Pyramid Has Too Many Dependencies --------------------------------- -- cgit v1.2.3 From cb05b6f9b141c85dfd7eee12ed488b4de5e8c43c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 17:28:17 -0400 Subject: update docs page numbers (whimper) --- docs/designdefense.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 165ee3dbc..dbb02a4a5 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -1649,7 +1649,7 @@ If you can understand this hello world program, you can use Pyramid: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -Pyramid has ~ 650 pages of documentation (printed), covering topics from the +Pyramid has ~ 700 pages of documentation (printed), covering topics from the very basic to the most advanced. *Nothing* is left undocumented, quite literally. It also has an *awesome*, very helpful community. Visit the #pyramid IRC channel on freenode.net (irc://freenode.net#pyramid) and see. -- cgit v1.2.3 From ce9110a92043c62b902926826b9f96dbd80b576c Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 9 Sep 2013 18:35:35 -0400 Subject: Update theme. --- docs/_themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_themes b/docs/_themes index a181b85d4..91cda806e 160000 --- a/docs/_themes +++ b/docs/_themes @@ -1 +1 @@ -Subproject commit a181b85d4ca08fa109ee2786d4f1b5b17e9b4589 +Subproject commit 91cda806e6227e457963409fe380963d146b0e6d -- cgit v1.2.3 From b117f9c16e8c59915bb3d87d8e548e1111ed6899 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 18:58:37 -0400 Subject: rely on pylons_sphinx_latesturl --- rtd.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/rtd.txt b/rtd.txt index 9de7ff3bb..b449ac73c 100644 --- a/rtd.txt +++ b/rtd.txt @@ -1,3 +1,4 @@ repoze.sphinx.autointerface repoze.lru +pylons_sphinx_latesturl -- cgit v1.2.3 From ec0c5cae96a57b8f3b57f18a870c8d91adc56cd8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 19:44:40 -0400 Subject: add note about requiring a later pyramid_debugtoolbar package if you use 1.5a2+ --- CHANGES.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 5cfd5e70d..cdbeeffa3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -51,6 +51,11 @@ Backwards Incompatibilities result = pyramid.renderers.render('mypkg:templates/home.mako', {}) + Note that if you're using the Pyramid debug toolbar, when you upgrade + Pyramid, you'll also need to upgrade the ``pyramid_debugtoolbar`` package to + at least version 1.0.8, as older versions are not compatible with Pyramid + 1.5a2+. + - 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. -- cgit v1.2.3 From f8be30b706e7b735b1ea419fbd9899dd2b5c7d27 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 20:04:29 -0400 Subject: wording --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index cdbeeffa3..41549fbe5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -54,7 +54,7 @@ Backwards Incompatibilities Note that if you're using the Pyramid debug toolbar, when you upgrade Pyramid, you'll also need to upgrade the ``pyramid_debugtoolbar`` package to at least version 1.0.8, as older versions are not compatible with Pyramid - 1.5a2+. + 1.5a2+ due to this change. - Removed the ``request.response_*`` varying attributes. These attributes have been deprecated since Pyramid 1.1, and as per the deprecation policy, -- cgit v1.2.3 From 03403e14826e4cb56f91ec8556ea658e16ab28da Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 20:18:35 -0400 Subject: 79 cols --- pyramid/events.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/events.py b/pyramid/events.py index ca10e2893..5179ab08a 100644 --- a/pyramid/events.py +++ b/pyramid/events.py @@ -228,9 +228,9 @@ class BeforeRender(dict): # {'mykey': 'somevalue'} is returned from the view print(event.rendering_val['mykey']) - In other words, :attr:`rendering_val` is the (non-system) value returned by a - view or passed to ``render*`` as ``value``. This feature is new in Pyramid - 1.2. + In other words, :attr:`rendering_val` is the (non-system) value returned + by a view or passed to ``render*`` as ``value``. This feature is new in + Pyramid 1.2. For a description of the values present in the renderer globals dictionary, see :ref:`renderer_system_values`. -- cgit v1.2.3 From 7b980354623908992c0aea4ae311a0e51ca83f30 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 21:03:56 -0400 Subject: unused import --- pyramid/config/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index 0c3a836df..0fb7fa5d2 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -4,7 +4,6 @@ import logging import operator import os import sys -import warnings import venusian from webob.exc import WSGIHTTPException as WebobWSGIHTTPException -- cgit v1.2.3 From b7e92d256826b53fa17b57040d527246f551b0da Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 21:12:53 -0400 Subject: create an add_default_renderers method on the configurator and use it from testing.setUp() and within the Configurator constructor --- pyramid/config/__init__.py | 5 +---- pyramid/config/rendering.py | 4 ++++ pyramid/testing.py | 13 +------------ pyramid/tests/test_config/test_rendering.py | 10 ++++++++++ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index 0fb7fa5d2..870f8b84d 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -62,7 +62,6 @@ from pyramid.config.adapters import AdaptersConfiguratorMixin from pyramid.config.assets import AssetsConfiguratorMixin from pyramid.config.factories import FactoriesConfiguratorMixin from pyramid.config.i18n import I18NConfiguratorMixin -from pyramid.config.rendering import DEFAULT_RENDERERS from pyramid.config.rendering import RenderingConfiguratorMixin from pyramid.config.routes import RoutesConfiguratorMixin from pyramid.config.security import SecurityConfiguratorMixin @@ -344,9 +343,7 @@ class Configurator( registry.registerUtility(debug_logger, IDebugLogger) - for name, renderer in DEFAULT_RENDERERS: - self.add_renderer(name, renderer) - + self.add_default_renderers() self.add_default_view_predicates() self.add_default_route_predicates() diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index 258c5a566..68671d08e 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -12,6 +12,10 @@ DEFAULT_RENDERERS = ( ) class RenderingConfiguratorMixin(object): + def add_default_renderers(self): + for name, renderer in DEFAULT_RENDERERS: + self.add_renderer(name, renderer) + @action_method def add_renderer(self, name, factory): """ diff --git a/pyramid/testing.py b/pyramid/testing.py index 789047ab3..4590c55f8 100644 --- a/pyramid/testing.py +++ b/pyramid/testing.py @@ -450,18 +450,7 @@ def setUp(registry=None, request=None, hook_zca=True, autocommit=True, # someone may be passing us an esoteric "dummy" registry, and # the below won't succeed if it doesn't have a registerUtility # method. - from pyramid.config import DEFAULT_RENDERERS - for name, renderer in DEFAULT_RENDERERS: - # Cause the default renderers to be registered because - # in-the-wild test code relies on being able to call - # e.g. ``pyramid.chameleon_zpt.render_template`` - # without registering a .pt renderer, expecting the "real" - # template to be rendered. This is a holdover from when - # individual template system renderers weren't indirected - # by the ``pyramid.renderers`` machinery, and - # ``render_template`` and friends went behind the back of - # any existing renderer factory lookup system. - config.add_renderer(name, renderer) + config.add_default_renderers() config.add_default_view_predicates() config.add_default_route_predicates() config.commit() diff --git a/pyramid/tests/test_config/test_rendering.py b/pyramid/tests/test_config/test_rendering.py index 2c3730775..cede64d3a 100644 --- a/pyramid/tests/test_config/test_rendering.py +++ b/pyramid/tests/test_config/test_rendering.py @@ -6,6 +6,16 @@ class TestRenderingConfiguratorMixin(unittest.TestCase): config = Configurator(*arg, **kw) return config + def test_add_default_renderers(self): + from pyramid.config.rendering import DEFAULT_RENDERERS + from pyramid.interfaces import IRendererFactory + config = self._makeOne(autocommit=True) + config.add_default_renderers() + for name, impl in DEFAULT_RENDERERS: + self.assertTrue( + config.registry.queryUtility(IRendererFactory, name) is not None + ) + def test_add_renderer(self): from pyramid.interfaces import IRendererFactory config = self._makeOne(autocommit=True) -- cgit v1.2.3 From 65fe0c9152027981c3b6011282ceb3d1062daa21 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 21:15:24 -0400 Subject: unused import --- pyramid/config/i18n.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index f08cfb9a8..69af0f9bc 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -7,7 +7,6 @@ from pyramid.interfaces import ( ) from pyramid.exceptions import ConfigurationError -from pyramid.i18n import get_localizer from pyramid.path import package_path from pyramid.util import action_method -- cgit v1.2.3 From 27190e533abf642f6fd6698016c91fee35e663a0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 21:32:10 -0400 Subject: rename _register_response_adapters method to add_default_response_adapters and change its implementation so it uses add_response_adapter instead of mutating registry directly --- pyramid/config/__init__.py | 14 +++++++------- pyramid/config/adapters.py | 7 ++++--- pyramid/tests/test_config/test_init.py | 8 ++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index 870f8b84d..19c47cbd9 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -333,7 +333,6 @@ class Configurator( self._fix_registry() self._set_settings(settings) - self._register_response_adapters() if isinstance(debug_logger, string_types): debug_logger = logging.getLogger(debug_logger) @@ -343,6 +342,7 @@ class Configurator( registry.registerUtility(debug_logger, IDebugLogger) + self.add_default_response_adapters() self.add_default_renderers() self.add_default_view_predicates() self.add_default_route_predicates() @@ -362,12 +362,12 @@ class Configurator( self.commit() - # self.commit() should not be called after this point because the - # following registrations should be treated as analogues of methods - # called by the user after configurator construction. Rationale: - # user-supplied implementations should be preferred rather than - # add-on author implementations with the help of automatic conflict - # resolution. + # self.commit() should not be called within this method after this + # point because the following registrations should be treated as + # analogues of methods called by the user after configurator + # construction. Rationale: user-supplied implementations should be + # preferred rather than add-on author implementations with the help of + # automatic conflict resolution. if authentication_policy and not authorization_policy: authorization_policy = ACLAuthorizationPolicy() # default diff --git a/pyramid/config/adapters.py b/pyramid/config/adapters.py index 0a74e76b4..f6a652e3d 100644 --- a/pyramid/config/adapters.py +++ b/pyramid/config/adapters.py @@ -1,3 +1,5 @@ +from webob import Response as WebobResponse + from functools import update_wrapper from zope.interface import Interface @@ -193,10 +195,9 @@ class AdaptersConfiguratorMixin(object): intr['type'] = type_or_iface self.action(discriminator, register, introspectables=(intr,)) - def _register_response_adapters(self): + def add_default_response_adapters(self): # cope with WebOb response objects that aren't decorated with IResponse - from webob import Response as WebobResponse - self.registry.registerSelfAdapter((WebobResponse,), IResponse) + self.add_response_adapter(None, WebobResponse) @action_method def add_traverser(self, adapter, iface=None): diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index a0333b66d..d6dba17f6 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -227,6 +227,14 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne(introspection=False) self.assertEqual(config.introspection, False) + def test_ctor_default_webob_response_adapter_registered(self): + from webob import Response as WebobResponse + response = WebobResponse() + from pyramid.interfaces import IResponse + config = self._makeOne(autocommit=True) + result = config.registry.queryAdapter(response, IResponse) + self.assertEqual(result, response) + def test_with_package_module(self): from pyramid.tests.test_config import test_init import pyramid.tests -- cgit v1.2.3 From 75f3857c811c61b9461c6ba31e8147e403bf80e6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 21:54:41 -0400 Subject: - The ``pyramid.config.Configurator.set_request_property`` method now issues a deprecation warning when used. It had been docs-deprecated in 1.4 but did not issue a deprecation warning when used. --- CHANGES.txt | 7 ++ pyramid/config/factories.py | 8 ++- pyramid/tests/test_config/test_factories.py | 105 ++++++++++++++++------------ 3 files changed, 73 insertions(+), 47 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 41549fbe5..5976a326f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -117,6 +117,13 @@ Backwards Incompatibilities Pyramid narrative documentation instead of providing renderer globals values to the configurator. +Deprecations +------------ + +- The ``pyramid.config.Configurator.set_request_property`` method now issues + a deprecation warning when used. It had been docs-deprecated in 1.4 + but did not issue a deprecation warning when used. + 1.5a1 (2013-08-30) ================== diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py index d30df3b74..774125821 100644 --- a/pyramid/config/factories.py +++ b/pyramid/config/factories.py @@ -1,3 +1,4 @@ +from zope.deprecation import deprecate from zope.interface import implementer from pyramid.interfaces import ( @@ -179,12 +180,15 @@ class FactoriesConfiguratorMixin(object): introspectables=(intr,)) @action_method + @deprecate('set_request_propery() is deprecated as of Pyramid 1.5; use ' + 'add_request_method() with the property=True argument instead') def set_request_property(self, callable, name=None, reify=False): """ Add a property to the request object. - .. deprecated:: 1.4 + .. deprecated:: 1.5 :meth:`pyramid.config.Configurator.add_request_method` should be - used instead. + used instead. (This method was docs-deprecated in 1.4 and + issues a real deprecation warning in 1.5). .. versionadded:: 1.3 """ diff --git a/pyramid/tests/test_config/test_factories.py b/pyramid/tests/test_config/test_factories.py index e89fc077e..6e679397f 100644 --- a/pyramid/tests/test_config/test_factories.py +++ b/pyramid/tests/test_config/test_factories.py @@ -67,51 +67,6 @@ class TestFactoriesMixin(unittest.TestCase): self.assertEqual(config.registry.getUtility(ISessionFactory), dummyfactory) - def test_set_request_property_with_callable(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne(autocommit=True) - callable = lambda x: None - config.set_request_property(callable, name='foo') - exts = config.registry.getUtility(IRequestExtensions) - self.assertTrue('foo' in exts.descriptors) - - def test_set_request_property_with_unnamed_callable(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne(autocommit=True) - def foo(self): pass - config.set_request_property(foo, reify=True) - exts = config.registry.getUtility(IRequestExtensions) - self.assertTrue('foo' in exts.descriptors) - - def test_set_request_property_with_property(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne(autocommit=True) - callable = property(lambda x: None) - config.set_request_property(callable, name='foo') - exts = config.registry.getUtility(IRequestExtensions) - self.assertTrue('foo' in exts.descriptors) - - def test_set_multiple_request_properties(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne() - def foo(self): pass - bar = property(lambda x: None) - config.set_request_property(foo, reify=True) - config.set_request_property(bar, name='bar') - config.commit() - exts = config.registry.getUtility(IRequestExtensions) - self.assertTrue('foo' in exts.descriptors) - self.assertTrue('bar' in exts.descriptors) - - def test_set_multiple_request_properties_conflict(self): - from pyramid.exceptions import ConfigurationConflictError - config = self._makeOne() - def foo(self): pass - bar = property(lambda x: None) - config.set_request_property(foo, name='bar', reify=True) - config.set_request_property(bar, name='bar') - self.assertRaises(ConfigurationConflictError, config.commit) - def test_add_request_method_with_callable(self): from pyramid.interfaces import IRequestExtensions config = self._makeOne(autocommit=True) @@ -157,3 +112,63 @@ class TestFactoriesMixin(unittest.TestCase): self.assertRaises(AttributeError, config.add_request_method) +class TestDeprecatedFactoriesMixinMethods(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, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_set_request_property_with_callable(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne(autocommit=True) + callable = lambda x: None + config.set_request_property(callable, name='foo') + exts = config.registry.getUtility(IRequestExtensions) + self.assertTrue('foo' in exts.descriptors) + + def test_set_request_property_with_unnamed_callable(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne(autocommit=True) + def foo(self): pass + config.set_request_property(foo, reify=True) + exts = config.registry.getUtility(IRequestExtensions) + self.assertTrue('foo' in exts.descriptors) + + def test_set_request_property_with_property(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne(autocommit=True) + callable = property(lambda x: None) + config.set_request_property(callable, name='foo') + exts = config.registry.getUtility(IRequestExtensions) + self.assertTrue('foo' in exts.descriptors) + + def test_set_multiple_request_properties(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne() + def foo(self): pass + bar = property(lambda x: None) + config.set_request_property(foo, reify=True) + config.set_request_property(bar, name='bar') + config.commit() + exts = config.registry.getUtility(IRequestExtensions) + self.assertTrue('foo' in exts.descriptors) + self.assertTrue('bar' in exts.descriptors) + + def test_set_multiple_request_properties_conflict(self): + from pyramid.exceptions import ConfigurationConflictError + config = self._makeOne() + def foo(self): pass + bar = property(lambda x: None) + config.set_request_property(foo, name='bar', reify=True) + config.set_request_property(bar, name='bar') + self.assertRaises(ConfigurationConflictError, config.commit) + + -- cgit v1.2.3 From ebf4577b5fcd0d579c265b8246095ee9d757592b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 22:03:30 -0400 Subject: garden --- TODO.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 2aa1dc487..5b6648abc 100644 --- a/TODO.txt +++ b/TODO.txt @@ -118,9 +118,6 @@ Nice-to-Have Future ------ -- 1.5: Maybe? deprecate set_request_property in favor of pointing people at - add_request_method, schedule removal for 1.8? - - 1.6: turn ``pyramid.settings.Settings`` into a function that returns the original dict (after ``__getattr__`` deprecation period, it was deprecated in 1.2). @@ -130,6 +127,8 @@ Future - 1.7: Change ``pyramid.authentication.AuthTktAuthenticationPolicy`` default ``hashalg`` to ``sha512``. +- 1.8 Remove set_request_property. + Probably Bad Ideas ------------------ -- cgit v1.2.3 From 2204c6a7ca835dc61b35f64c4c18d7d445db0806 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 9 Sep 2013 22:07:16 -0400 Subject: garden --- TODO.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO.txt b/TODO.txt index 5b6648abc..62b8c39f4 100644 --- a/TODO.txt +++ b/TODO.txt @@ -38,8 +38,6 @@ Nice-to-Have - Add narrative docs for wsgiapp and wsgiapp2. -- Flesh out "Paste" narrative docs chapter. - - Basic WSGI documentation (pipeline / app / server). - Change docs about creating a venusian decorator to not use ZCA (use -- cgit v1.2.3 From bb6e929288eb7e36173adbf9b28a2062caf9af71 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 11 Sep 2013 00:55:39 -0400 Subject: wording --- CHANGES.txt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5976a326f..0f04587ee 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -18,11 +18,12 @@ Bug Fixes Backwards 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: +- Pyramid has dropped native support for the Mako and Chameleon templating + system renderers. To re-add support for these renderers into your existing + projects, there are 3 steps: - - Add `pyramid_mako` and/or `pyramid_chameleon` as dependencies by - adding them to the `install_requires` section of the package's `setup.py`:: + - Add ``pyramid_mako`` and/or ``pyramid_chameleon`` as dependencies by + adding them to the `install_requires` section of your package's `setup.py`:: setup( #... @@ -34,8 +35,8 @@ Backwards Incompatibilities ], ) - - Update instances of the ``pyramid.config.Configurator`` to include the - required addons:: + - Update instances of the ``pyramid.config.Configurator`` to ``include`` the + one or the other (or both) required addons:: config.include('pyramid_chameleon') config.include('pyramid_mako') @@ -67,10 +68,6 @@ 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. - The ``pyramid.events.NewResponse`` event is now sent **after** response -- cgit v1.2.3 From 44327c30ac807896ec999ca000373a29c94da95c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 11 Sep 2013 18:01:32 -0400 Subject: appease --- pyramid/renderers.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pyramid/renderers.py b/pyramid/renderers.py index d8542decc..e90d07b38 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -201,11 +201,17 @@ class JSON(object): adapters with the renderer. See :ref:`json_serializing_custom_objects` for more information. - The default serializer uses ``json.JSONEncoder``. A different - serializer can be specified via the ``serializer`` argument. - Custom serializers should accept the object, a callback - ``default``, and any extra ``kw`` keyword arguments passed during - renderer construction. + .. note:: + + The default serializer uses ``json.JSONEncoder``. A different + serializer can be specified via the ``serializer`` argument. Custom + serializers should accept the object, a callback ``default``, and any + extra ``kw`` keyword arguments passed during renderer construction. + This feature isn't widely used but it can be used to replace the + stock JSON serializer with, say, simplejson. If all you want to + do, however, is serialize custom objects, you should use the method + explained in :ref:`json_serializing_custom_objects` instead + of replacing the serializer. .. versionadded:: 1.4 Prior to this version, there was no public API for supplying options -- cgit v1.2.3 From db1efe21c3d9b025883b3ed9b0b897cc3d718c28 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 11 Sep 2013 18:10:18 -0400 Subject: appease --- docs/narr/renderers.rst | 51 ++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index e13e09af3..3059aef35 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -207,13 +207,7 @@ representing the JSON serialization of the return value: The return value needn't be a dictionary, but the return value must contain values serializable by the configured serializer (by default ``json.dumps``). -.. note:: - - Extra arguments can be passed to the serializer by overriding the default - ``json`` renderer. See :class:`pyramid.renderers.JSON` and - :ref:`adding_and_overriding_renderers` for more information. - -You can configure a view to use the JSON renderer by naming ``json`` as the +You can configure a view to use the JSON renderer by naming``json`` as the ``renderer`` argument of a view configuration, e.g. by using :meth:`~pyramid.config.Configurator.add_view`: @@ -234,6 +228,18 @@ using the api of the ``request.response`` attribute. See Serializing Custom Objects ++++++++++++++++++++++++++ +Some objects are not, by default, JSON-serializable (such as datetimes and +other arbitrary Python objects). You can, however, register code that makes +non-serializable objects serializable in two ways: + +- By defining a ``__json__`` method on objects in your application. + +- For objects you don't "own", you can register JSON renderer that knows about + an *adapter* for that kind of object. + +Using a Custom ``__json__`` Method +********************************** + Custom objects can be made easily JSON-serializable in Pyramid by defining a ``__json__`` method on the object's class. This method should return values natively JSON-serializable (such as ints, lists, dictionaries, strings, and @@ -259,6 +265,9 @@ will be the active request object at render time. # the JSON value returned by ``objects`` will be: # [{"x": 1}, {"x": 2}] +Using the ``add_adapter`` Method of a Custom JSON Renderer +********************************************************** + If you aren't the author of the objects being serialized, it won't be possible (or at least not reasonable) to add a custom ``__json__`` method to their classes in order to influence serialization. If the object passed @@ -273,19 +282,21 @@ objects using the registered adapters. A short example follows: from pyramid.renderers import JSON - json_renderer = JSON() - def datetime_adapter(obj, request): - return obj.isoformat() - json_renderer.add_adapter(datetime.datetime, datetime_adapter) - - # then during configuration .... - config = Configurator() - config.add_renderer('json', json_renderer) - -The adapter should accept two arguments: the object needing to be serialized -and ``request``, which will be the current request object at render time. -The adapter should raise a :exc:`TypeError` if it can't determine what to do -with the object. + if __name__ == '__main__': + config = Configurator() + json_renderer = JSON() + def datetime_adapter(obj, request): + return obj.isoformat() + json_renderer.add_adapter(datetime.datetime, datetime_adapter) + config.add_renderer('json', json_renderer) + +The ``add_adapter`` method should accept two arguments: the *class* of the object that you want this adapter to run for (in the example above, +``datetime.datetime``), and the adapter itself. + +The adapter should be a callable. It should accept two arguments: the object +needing to be serialized and ``request``, which will be the current request +object at render time. The adapter should raise a :exc:`TypeError` +if it can't determine what to do with the object. See :class:`pyramid.renderers.JSON` and :ref:`adding_and_overriding_renderers` for more information. -- cgit v1.2.3 From a8f6693def4f60f673806c79c1092c8d58a8e10d Mon Sep 17 00:00:00 2001 From: Adam Groszer Date: Thu, 12 Sep 2013 17:27:52 +0200 Subject: Add doc about the top level member limitation of ``view_config`` --- pyramid/view.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pyramid/view.py b/pyramid/view.py index edb4d688c..55ab38871 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -166,6 +166,9 @@ class view_config(object): See :ref:`mapping_views_using_a_decorator_section` for details about using :class:`pyramid.view.view_config`. + ATTENTION: ``view_config`` will work ONLY on module top level members + because of the limitation of ``venusian.Scanner.scan``. + """ venusian = venusian # for testing injection def __init__(self, **settings): @@ -205,7 +208,7 @@ class view_defaults(view_config): See :ref:`view_defaults` for more information. """ - + def __call__(self, wrapped): wrapped.__view_defaults__ = self.__dict__.copy() return wrapped @@ -305,7 +308,7 @@ class notfound_view_config(object): from pyramid.view import notfound_view_config from pyramid.response import Response - + @notfound_view_config() def notfound(request): return Response('Not found, dude!', status='404 Not Found') @@ -368,7 +371,7 @@ class forbidden_view_config(object): from pyramid.view import forbidden_view_config from pyramid.response import Response - + @forbidden_view_config() def forbidden(request): return Response('You are not allowed', status='401 Unauthorized') @@ -404,4 +407,4 @@ class forbidden_view_config(object): settings['_info'] = info.codeinfo # fbo "action_method" return wrapped - + -- cgit v1.2.3 From 93137f090f24b1ffa4812b282adf95708576c1a1 Mon Sep 17 00:00:00 2001 From: Adam Gomaa Date: Thu, 12 Sep 2013 14:16:39 -0700 Subject: fix broken link to tox --- HACKING.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HACKING.txt b/HACKING.txt index 684a42ee6..4ebb59160 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -21,10 +21,10 @@ checkout. (alternately, create a writeable fork on GitHub and check that out). Since pyramid is a framework and not an application, it can be -convenient to work against a sample application, preferably in its -own virtualenv. A quick way to achieve this is to (ab-)use ``tox`` -(http://codespeak.net/~hpk/tox/) with a custom configuration file that's part of -the checkout:: +convenient to work against a sample application, preferably in its own +virtualenv. A quick way to achieve this is to (ab-)use ``tox`` +(http://tox.readthedocs.org/en/latest/) with a custom configuration +file that's part of the checkout:: tox -c hacking-tox.ini -- cgit v1.2.3 From 1936a3c0ef27c78baebe565706c3f9bcc0defaea Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 14 Sep 2013 02:22:28 -0400 Subject: use most recent version of theme --- docs/_themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_themes b/docs/_themes index 91cda806e..267326456 160000 --- a/docs/_themes +++ b/docs/_themes @@ -1 +1 @@ -Subproject commit 91cda806e6227e457963409fe380963d146b0e6d +Subproject commit 26732645619b372764097e5e8086f89871d90c04 -- cgit v1.2.3 From 14e164132e64f4808ff2a41399e2f47bd22bea68 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 14 Sep 2013 23:49:17 -0500 Subject: The sentence needed a conjunction. --- docs/designdefense.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index dbb02a4a5..bbc9e2660 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -792,8 +792,8 @@ such a feature. main template and the CSS in a separate Python package which defines overrides. -- If a deployment needs an application page to do something differently needs - it to expose more or different information, the deployer may override the +- If a deployment needs an application page to do something differently, or + to expose more or different information, the deployer may override the view that renders the page within a separate Python package. - If a deployment needs an additional feature, the deployer may add a view to -- cgit v1.2.3 From 9d0f887fa913482a2e07df442ed0b02ae7778a89 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 14 Sep 2013 23:55:12 -0500 Subject: "useful...than" made no sense. --- docs/designdefense.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index bbc9e2660..e30b847de 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -764,7 +764,7 @@ content management system (CMS) may have basic functionality that needs to be extended for a particular deployment. That CMS system may be deployed for many organizations at many places. Some number of deployments of this CMS may be deployed centrally by a third party and managed as a group. It's -useful to be able to extend such a system for each deployment via preordained +easier to be able to extend such a system for each deployment via preordained plugpoints than it is to continually keep each software branch of the system in sync with some upstream source: the upstream developers may change code in such a way that your changes to the same codebase conflict with theirs in -- cgit v1.2.3 From 4fa49f72be3b61182c76eca353e6f37fdb625227 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 15 Sep 2013 00:03:23 -0500 Subject: typo --- docs/designdefense.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index e30b847de..02f868e5d 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -810,7 +810,7 @@ won't regularly need to deal wth meaningless textual merge conflicts that trivial changes to upstream packages often entail when it comes time to update the upstream package, because if you extend an application externally, there just is no textual merge done. Your modifications will also, for -whatever its worth, be contained in one, canonical, well-defined place. +whatever it's worth, be contained in one, canonical, well-defined place. Branching an application and continually merging in order to get new features and bugfixes is clearly useful. You can do that with a :app:`Pyramid` -- cgit v1.2.3 From 2d2b438f2d3c44dc5a7c49a64d71e8653c0eac60 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 15 Sep 2013 00:07:01 -0500 Subject: typo --- docs/designdefense.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 02f868e5d..a8f1c409a 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -822,7 +822,7 @@ dismiss this feature in favor of branching and merging because applications written in their framework of choice aren't extensible out of the box in a comparably fundamental way. -While :app:`Pyramid` application are fundamentally extensible even if you +While :app:`Pyramid` applications are fundamentally extensible even if you don't write them with specific extensibility in mind, if you're moderately adventurous, you can also take it a step further. If you learn more about the :term:`Zope Component Architecture`, you can optionally use it to expose -- cgit v1.2.3 From 63e18d797b4f10f6d06ec7ad25d3dadc85147ae2 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 15 Sep 2013 00:08:43 -0500 Subject: Double 'instead' removed. --- docs/designdefense.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index a8f1c409a..bbce3e29c 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -842,7 +842,7 @@ applications by :app:`Pyramid` are good or bad is mostly pointless. You needn't take advantage of the extensibility features provided by a particular :app:`Pyramid` application in order to affect a modification for a particular set of its deployments. You can ignore the application's extensibility -plugpoints entirely, and instead use version control branching and merging to +plugpoints entirely, and use version control branching and merging to manage application deployment modifications instead, as if you were deploying an application written using any other web framework. -- cgit v1.2.3 From 4d2fc0bbc58bc1948c73b2fcb3e0e1bdeee7a5d6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 20 Sep 2013 00:41:01 -0400 Subject: subrepo dance --- docs/_themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_themes b/docs/_themes index 267326456..f3acb7cfd 160000 --- a/docs/_themes +++ b/docs/_themes @@ -1 +1 @@ -Subproject commit 26732645619b372764097e5e8086f89871d90c04 +Subproject commit f3acb7cfd1ab69510bc202676dc1d8f321282953 -- cgit v1.2.3