summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGES.txt14
-rw-r--r--docs/narr/environment.rst2
-rw-r--r--docs/narr/views.rst54
-rw-r--r--pyramid/chameleon_zpt.py8
-rw-r--r--pyramid/configuration.py84
-rw-r--r--pyramid/mako_templating.py40
-rw-r--r--pyramid/renderers.py112
-rw-r--r--pyramid/testing.py5
-rw-r--r--pyramid/tests/test_configuration.py59
-rw-r--r--pyramid/tests/test_mako_templating.py60
-rw-r--r--pyramid/tests/test_renderers.py152
-rw-r--r--pyramid/tests/test_testing.py12
-rw-r--r--pyramid/tests/test_view.py31
-rw-r--r--pyramid/view.py20
-rw-r--r--pyramid/zcml.py5
16 files changed, 354 insertions, 305 deletions
diff --git a/.gitignore b/.gitignore
index 31276c18f..92bc7bc23 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,5 @@
.coverage
env26
env24
+env27
build/
diff --git a/CHANGES.txt b/CHANGES.txt
index dcfdbcaaa..8dbbbfd66 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -90,3 +90,17 @@ Backwards Incompatibilities (with BFG 1.3.X)
- The Venusian "category" for all built-in Venusian decorators
(e.g. ``subscriber`` and ``view_config``/``bfg_view``) is now
``pyramid`` instead of ``bfg``.
+
+- ``pyramid.renderers.rendered_response`` function removed; use
+ ``render_pyramid.renderers.render_to_response`` instead.
+
+- Renderer factories now accept a *dictionary* rather than an absolute resource
+ specification or an absolute path. The dictonary contains the following
+ keys: ``name`` (the ``renderer=`` value), ``package`` (the 'current package'
+ when the renderer configuration statement was found), ``type``: the renderer
+ type, and ``registry``: the current registry.
+
+ Third-party ``repoze.bfg`` renderer implementations that must be ported to
+ Pyramid will need to account for this.
+
+ This change was made to support more flexible Mako template rendering.
diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst
index fa639cce1..83de12863 100644
--- a/docs/narr/environment.rst
+++ b/docs/narr/environment.rst
@@ -195,7 +195,7 @@ should be changed accordingly.
+-----------------------------+
| Config File Setting Name |
+=============================+
-| ``mako.input_encoding``__ |
+| ``mako.input_encoding`` |
| |
| |
| |
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index c74263bdc..0070e7a73 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -738,9 +738,12 @@ following interface:
:linenos:
class RendererFactory:
- def __init__(self, name):
- """ Constructor: ``name`` may be an absolute path or a
- resource specification """
+ def __init__(self, info):
+ """ Constructor: ``info`` will be a dictionary containing the
+ following keys: ``name`` (the renderer name), ``package``: the
+ package that was 'current' at the time the renderer was registered,
+ ``type``: the renderer type name, and ``registry``: the current
+ registry. """
def __call__(self, value, system):
""" Call a the renderer implementation with the value and
@@ -752,18 +755,17 @@ following interface:
There are essentially two different kinds of renderer factories:
-- A renderer factory which expects to accept a :term:`resource
- specification` or an absolute path as the ``name`` value in its
- constructor. These renderer factories are registered with a
- ``name`` value that begins with a dot (``.``). These types of
- renderer factories usually relate to a file on the filesystem, such
- as a template.
+- A renderer factory which expects to accept a :term:`resource specification`
+ or an absolute path as the ``name`` value in the ``info`` value fed to its
+ constructor. These renderer factories are registered with a ``name`` value
+ that begins with a dot (``.``). These types of renderer factories usually
+ relate to a file on the filesystem, such as a template.
-- A renderer factory which expects to accept a token that does not
- represent a filesystem path or a resource specification in its
- constructor. These renderer factories are registered with a
- ``name`` value that does not begin with a dot. These renderer
- factories are typically object serializers.
+- A renderer factory which expects to accept a token that does not represent a
+ filesystem path or a resource specification in the ``name`` value of the
+ ``info`` dict fed to its constructor. These renderer factories are
+ registered with a ``name`` value that does not begin with a dot. These
+ renderer factories are typically object serializers.
.. sidebar:: Resource Specifications
@@ -832,19 +834,17 @@ configuration`:
def myview(request):
return {'Hello':'world'}
-When a :term:`view configuration` which has a ``name`` attribute that
-does contain a dot, such as ``templates/mytemplate.jinja2`` above is
-encountered at startup time, the value of the name attribute is split
-on its final dot. The second element of the split is typically the
-filename extension. This extension is used to look up a renderer
-factory for the configured view. Then the value of ``renderer`` is
-passed to the factory to create a renderer for the view. In this
-case, the view configuration will create an instance of a
-``Jinja2Renderer`` for each view configuration which includes anything
-ending with ``.jinja2`` as its ``renderer`` value. The ``name``
-passed to the ``Jinja2Renderer`` constructor will usually be a
-:term:`resource specification`, but may also be an absolute path; the
-renderer factory implementation should be able to deal with either.
+When a :term:`view configuration` which has a ``name`` attribute that does
+contain a dot, such as ``templates/mytemplate.jinja2`` above is encountered at
+startup time, the value of the name attribute is split on its final dot. The
+second element of the split is typically the filename extension. This
+extension is used to look up a renderer factory for the configured view. Then
+the value of ``renderer`` is passed to the factory to create a renderer for the
+view. In this case, the view configuration will create an instance of a
+``Jinja2Renderer`` for each view configuration which includes anything ending
+with ``.jinja2`` as its ``renderer`` value. The ``name`` passed to the
+``Jinja2Renderer`` constructor will be whatever the user passed as
+``renderer=`` to the view configuration.
See also :ref:`renderer_directive` and
:meth:`pyramid.configuration.Configurator.add_renderer`.
diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py
index a9671c411..ec25bded7 100644
--- a/pyramid/chameleon_zpt.py
+++ b/pyramid/chameleon_zpt.py
@@ -70,7 +70,7 @@ def get_renderer(path):
:func:`pyramid.renderers.get_renderer` instead.
"""
package = caller_package()
- factory = renderers.RendererHelper(path, package=package)
+ factory = renderers.RendererHelper(name=path, package=package)
return factory.get_renderer()
def get_template(path):
@@ -84,7 +84,7 @@ def get_template(path):
:func:`pyramid.renderers.get_renderer` instead.
"""
package = caller_package()
- factory = renderers.RendererHelper(path, package=package)
+ factory = renderers.RendererHelper(name=path, package=package)
return factory.get_renderer().implementation()
def render_template(path, **kw):
@@ -100,7 +100,7 @@ def render_template(path, **kw):
"""
package = caller_package()
request = kw.pop('request', None)
- renderer = renderers.RendererHelper(path, package=package)
+ renderer = renderers.RendererHelper(name=path, package=package)
return renderer.render(kw, None, request=request)
def render_template_to_response(path, **kw):
@@ -117,5 +117,5 @@ def render_template_to_response(path, **kw):
"""
package = caller_package()
request = kw.pop('request', None)
- renderer = renderers.RendererHelper(path, package=package)
+ renderer = renderers.RendererHelper(name=path, package=package)
return renderer.render_to_response(kw, None, request=request)
diff --git a/pyramid/configuration.py b/pyramid/configuration.py
index 03966c3fd..3c2e3b6b5 100644
--- a/pyramid/configuration.py
+++ b/pyramid/configuration.py
@@ -283,7 +283,7 @@ class Configurator(object):
return resolve_resource_spec(path_or_spec, self.package_name)
def _derive_view(self, view, permission=None, predicates=(),
- attr=None, renderer_name=None, wrapper_viewname=None,
+ attr=None, renderer=None, wrapper_viewname=None,
viewname=None, accept=None, order=MAX_ORDER,
phash=DEFAULT_PHASH):
view = self.maybe_dotted(view)
@@ -291,8 +291,7 @@ class Configurator(object):
authz_policy = self.registry.queryUtility(IAuthorizationPolicy)
settings = self.registry.queryUtility(ISettings)
logger = self.registry.queryUtility(IDebugLogger)
- mapped_view = _map_view(view, attr, renderer_name, self.registry,
- self.package)
+ mapped_view = _map_view(view, attr, renderer, self.registry)
owrapped_view = _owrap_view(mapped_view, viewname, wrapper_viewname)
secured_view = _secure_view(owrapped_view, permission,
authn_policy, authz_policy)
@@ -543,7 +542,9 @@ class Configurator(object):
supplied, the user-supplied view must itself return a
:term:`response` object. """
- return self._derive_view(view, attr=attr, renderer_name=renderer)
+ if renderer is not None and not isinstance(renderer, dict):
+ renderer = {'name':renderer, 'package':self.package}
+ return self._derive_view(view, attr=attr, renderer=renderer)
def add_subscriber(self, subscriber, iface=None, info=u''):
"""Add an event :term:`subscriber` for the event stream
@@ -1072,6 +1073,9 @@ class Configurator(object):
# intent: will be None if no default permission is registered
permission = self.registry.queryUtility(IDefaultPermission)
+ if renderer is not None and not isinstance(renderer, dict):
+ renderer = {'name':renderer, 'package':self.package}
+
# NO_PERMISSION_REQUIRED handled by _secure_view
derived_view = self._derive_view(view, permission, predicates, attr,
renderer, wrapper, name, accept,
@@ -1687,7 +1691,9 @@ class Configurator(object):
The ``wrapper`` argument should be the name of another view
which will wrap this view when rendered (see the ``add_view``
method's ``wrapper`` argument for a description)."""
- view = self._derive_view(view, attr=attr, renderer_name=renderer)
+ if renderer is not None and not isinstance(renderer, dict):
+ renderer = {'name':renderer, 'package':self.package}
+ view = self._derive_view(view, attr=attr, renderer=renderer)
def bwcompat_view(context, request):
context = getattr(request, 'context', None)
return view(context, request)
@@ -1724,7 +1730,9 @@ class Configurator(object):
which will wrap this view when rendered (see the ``add_view``
method's ``wrapper`` argument for a description).
"""
- view = self._derive_view(view, attr=attr, renderer_name=renderer)
+ if renderer is not None and not isinstance(renderer, dict):
+ renderer = {'name':renderer, 'package':self.package}
+ view = self._derive_view(view, attr=attr, renderer=renderer)
def bwcompat_view(context, request):
context = getattr(request, 'context', None)
return view(context, request)
@@ -2090,18 +2098,18 @@ class Configurator(object):
"""
from pyramid.testing import DummyRendererFactory
- helper = RendererHelper(path, registry=self.registry)
+ helper = RendererHelper(name=path, registry=self.registry)
factory = helper.factory
if not isinstance(factory, DummyRendererFactory):
- factory = DummyRendererFactory(helper.renderer_type,
+ factory = DummyRendererFactory(helper.type,
helper.factory)
self.registry.registerUtility(factory, IRendererFactory,
- name=helper.renderer_type)
+ name=helper.type)
from pyramid.testing import DummyTemplateRenderer
if renderer is None:
renderer = DummyTemplateRenderer()
- factory.add(helper.renderer_name, renderer)
+ factory.add(helper.name, renderer)
return renderer
testing_add_template = testing_add_renderer
@@ -2426,15 +2434,15 @@ def is_response(ob):
return True
return False
-def _map_view(view, attr=None, renderer_name=None, registry=None,
- package=None):
+def _map_view(view, attr=None, renderer=None, registry=None):
wrapped_view = view
helper = None
- if renderer_name:
- helper = RendererHelper(renderer_name,
- registry=registry,
- package=package)
+
+ if renderer is not None:
+ helper = RendererHelper(renderer['name'],
+ package=renderer['package'],
+ registry=registry)
if inspect.isclass(view):
# If the object we've located is a class, turn it into a
@@ -2454,8 +2462,13 @@ def _map_view(view, attr=None, renderer_name=None, registry=None,
response = getattr(inst, attr)()
if helper is not None:
if not is_response(response):
- system = {'view':inst, 'renderer_name':renderer_name,
- 'context':context, 'request':request}
+ system = {
+ 'view':inst,
+ 'renderer_name':renderer['name'], # b/c
+ 'renderer_info':renderer,
+ 'context':context,
+ 'request':request
+ }
response = helper.render_to_response(response, system,
request=request)
return response
@@ -2470,8 +2483,12 @@ def _map_view(view, attr=None, renderer_name=None, registry=None,
response = getattr(inst, attr)()
if helper is not None:
if not is_response(response):
- system = {'view':inst, 'renderer_name':renderer_name,
- 'context':context, 'request':request}
+ system = {'view':inst,
+ 'renderer_name':renderer['name'], # b/c
+ 'renderer_info':renderer,
+ 'context':context,
+ 'request':request
+ }
response = helper.render_to_response(response, system,
request=request)
return response
@@ -2488,8 +2505,13 @@ def _map_view(view, attr=None, renderer_name=None, registry=None,
if helper is not None:
if not is_response(response):
- system = {'view':view, 'renderer_name':renderer_name,
- 'context':context, 'request':request}
+ system = {
+ 'view':view,
+ 'renderer_name':renderer['name'],
+ 'renderer_info':renderer,
+ 'context':context,
+ 'request':request
+ }
response = helper.render_to_response(response, system,
request=request)
return response
@@ -2500,8 +2522,13 @@ def _map_view(view, attr=None, renderer_name=None, registry=None,
response = getattr(view, attr)(context, request)
if helper is not None:
if not is_response(response):
- system = {'view':view, 'renderer_name':renderer_name,
- 'context':context, 'request':request}
+ system = {
+ 'view':view,
+ 'renderer_name':renderer['name'],
+ 'renderer_info':renderer,
+ 'context':context,
+ 'request':request
+ }
response = helper.render_to_response(response, system,
request=request)
return response
@@ -2511,8 +2538,13 @@ def _map_view(view, attr=None, renderer_name=None, registry=None,
def _rendered_view(context, request):
response = view(context, request)
if not is_response(response):
- system = {'view':view, 'renderer_name':renderer_name,
- 'context':context, 'request':request}
+ system = {
+ 'view':view,
+ 'renderer_name':renderer['name'], # b/c
+ 'renderer_info':renderer,
+ 'context':context,
+ 'request':request
+ }
response = helper.render_to_response(response, system,
request=request)
return response
diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py
index fb7a40c1c..ec6119764 100644
--- a/pyramid/mako_templating.py
+++ b/pyramid/mako_templating.py
@@ -1,13 +1,10 @@
import os
-import posixpath
-import re
from zope.interface import implements
from zope.interface import Interface
from pyramid.interfaces import ITemplateRenderer
from pyramid.exceptions import ConfigurationError
-from pyramid.threadlocal import get_current_registry
from pyramid.settings import get_settings
from pyramid.resource import resolve_resource_spec
from pyramid.resource import abspath_from_resource_spec
@@ -39,31 +36,26 @@ class PkgResourceTemplateLookup(TemplateLookup):
specification syntax.
"""
- if ':' not in uri:
- return TemplateLookup.get_template(self, uri)
- try:
- if self.filesystem_checks:
- return self._check(uri, self._collection[uri])
- else:
- return self._collection[uri]
- except KeyError:
- pname, path = resolve_resource_spec(uri)
- srcfile = abspath_from_resource_spec(path, pname)
- if os.path.isfile(srcfile):
- return self._load(srcfile, uri)
-
- u = re.sub(r'^\/+', '', path)
- for dir in self.directories:
- srcfile = posixpath.normpath(posixpath.join(dir, u))
+ isabs = os.path.isabs(uri)
+ if (not isabs) and (':' in uri):
+ try:
+ if self.filesystem_checks:
+ return self._check(uri, self._collection[uri])
+ else:
+ return self._collection[uri]
+ except KeyError:
+ pname, path = resolve_resource_spec(uri)
+ srcfile = abspath_from_resource_spec(path, pname)
if os.path.isfile(srcfile):
return self._load(srcfile, uri)
- else:
raise exceptions.TopLevelLookupException(
- "Cant locate template for uri %r" % uri)
+ "Cant locate template for uri %r" % uri)
+ return TemplateLookup.get_template(self, uri)
-def renderer_factory(path):
- registry = get_current_registry()
+def renderer_factory(info):
+ path = info['name']
+ registry = info['registry']
lookup = registry.queryUtility(IMakoLookup)
if lookup is None:
settings = get_settings() or {}
@@ -75,7 +67,7 @@ def renderer_factory(path):
raise ConfigurationError(
'Mako template used without a lookup path')
directories = directories.splitlines()
- directories = [ abspath_from_resource_spec(d) for d in directories ]
+ directories = [ abspath_from_resource_spec(d) for d in directories ]
lookup = PkgResourceTemplateLookup(directories=directories,
module_directory=module_directory,
input_encoding=input_encoding,
diff --git a/pyramid/renderers.py b/pyramid/renderers.py
index 251242916..78084ae97 100644
--- a/pyramid/renderers.py
+++ b/pyramid/renderers.py
@@ -4,19 +4,18 @@ import threading
from webob import Response
-from zope.deprecation import deprecated
-
from pyramid.interfaces import IRendererGlobalsFactory
from pyramid.interfaces import IRendererFactory
from pyramid.interfaces import IResponseFactory
from pyramid.interfaces import ITemplateRenderer
from pyramid.compat import json
+from pyramid.decorator import reify
from pyramid.path import caller_package
+from pyramid.path import package_path
+from pyramid.resource import resource_spec_from_abspath
from pyramid.settings import get_settings
from pyramid.threadlocal import get_current_registry
-from pyramid.resource import resolve_resource_spec
-from pyramid.decorator import reify
# API
@@ -60,7 +59,8 @@ def render(renderer_name, value, request=None, package=None):
registry = None
if package is None:
package = caller_package()
- renderer = RendererHelper(renderer_name, package=package, registry=registry)
+ renderer = RendererHelper(name=renderer_name, package=package,
+ registry=registry)
return renderer.render(value, None, request=request)
def render_to_response(renderer_name, value, request=None, package=None):
@@ -102,7 +102,8 @@ def render_to_response(renderer_name, value, request=None, package=None):
registry = None
if package is None:
package = caller_package()
- renderer = RendererHelper(renderer_name, package=package, registry=registry)
+ renderer = RendererHelper(name=renderer_name, package=package,
+ registry=registry)
return renderer.render_to_response(value, None, request=request)
def get_renderer(renderer_name, package=None):
@@ -119,13 +120,13 @@ def get_renderer(renderer_name, package=None):
"""
if package is None:
package = caller_package()
- renderer = RendererHelper(renderer_name, package=package)
+ renderer = RendererHelper(name=renderer_name, package=package)
return renderer.get_renderer()
# concrete renderer factory implementations (also API)
-def json_renderer_factory(name):
+def json_renderer_factory(info):
def _render(value, system):
request = system.get('request')
if request is not None:
@@ -134,7 +135,7 @@ def json_renderer_factory(name):
return json.dumps(value)
return _render
-def string_renderer_factory(name):
+def string_renderer_factory(info):
def _render(value, system):
if not isinstance(value, basestring):
value = str(value)
@@ -152,8 +153,19 @@ def string_renderer_factory(name):
# at runtime, from more than a single thread.
registry_lock = threading.Lock()
-def template_renderer_factory(spec, impl, lock=registry_lock):
- reg = get_current_registry()
+def template_renderer_factory(info, impl, lock=registry_lock):
+ reg = info['registry']
+ spec = info['name']
+ package = info['package']
+ isabs = os.path.isabs(spec)
+
+ if (not isabs) and (not ':' in spec) and package:
+ # relative resource spec
+ if not isabs:
+ pp = package_path(package)
+ spec = os.path.join(pp, spec)
+ spec = resource_spec_from_abspath(spec, package)
+
if os.path.isabs(spec):
# 'spec' is an absolute filename
if not os.path.exists(spec):
@@ -197,67 +209,39 @@ def _reload_resources():
settings = get_settings()
return settings and settings.get('reload_resources')
-def renderer_from_name(path, package=None):
- return RendererHelper(path, package=package).get_renderer()
-
-def rendered_response(renderer, result, view, context, request, renderer_name):
- # XXX: deprecated, left here only to not break old code; use
- # render_to_response instead
- if ( hasattr(result, 'app_iter') and hasattr(result, 'headerlist')
- and hasattr(result, 'status') ):
- return result
-
- system = {'view':view, 'renderer_name':renderer_name,
- 'context':context, 'request':request}
-
- helper = RendererHelper(renderer_name)
- helper.renderer = renderer
- return helper.render_to_response(result, system, request=request)
-
-deprecated('rendered_response',
- "('pyramid.renderers.rendered_response' is not a public API; it is "
- "officially deprecated as of pyramid 1.0; "
- "use pyramid.renderers.render_to_response instead')",
- )
+def renderer_from_name(path, package=None): # XXX deprecate?
+ return RendererHelper(name=path, package=package).get_renderer()
class RendererHelper(object):
- def __init__(self, renderer_name, registry=None, package=None):
+ def __init__(self, name=None, package=None, registry=None):
if registry is None:
registry = get_current_registry()
- self.registry = registry
- self.package = package
- if renderer_name is None:
- factory = registry.queryUtility(IRendererFactory)
- renderer_type = None
+
+ if name and '.' in name:
+ rtype = os.path.splitext(name)[1]
else:
- if '.' in renderer_name:
- renderer_type = os.path.splitext(renderer_name)[1]
- renderer_name = self.resolve_spec(renderer_name)
- else:
- renderer_type = renderer_name
- renderer_name = renderer_name
- factory = registry.queryUtility(IRendererFactory,
- name=renderer_type)
- self.renderer_name = renderer_name
- self.renderer_type = renderer_type
+ rtype = name
+
+ factory = registry.queryUtility(IRendererFactory, name=rtype)
+
+ self.name = name
+ self.package = package
+ self.type = rtype
self.factory = factory
+ self.registry = registry
@reify
def renderer(self):
if self.factory is None:
- raise ValueError('No such renderer factory %s' % str(self.renderer_type))
- return self.factory(self.renderer_name)
-
- def resolve_spec(self, path_or_spec):
- if path_or_spec is None:
- return path_or_spec
-
- package, filename = resolve_resource_spec(path_or_spec,
- self.package)
- if package is None:
- return filename # absolute filename
- return '%s:%s' % (package, filename)
-
+ raise ValueError(
+ 'No such renderer factory %s' % str(self.type))
+ return self.factory({
+ 'name':self.name,
+ 'type':self.type,
+ 'package':self.package,
+ 'registry':self.registry
+ })
+
def get_renderer(self):
return self.renderer
@@ -266,7 +250,9 @@ class RendererHelper(object):
if system_values is None:
system_values = {
'view':None,
- 'renderer_name':self.renderer_name,
+ 'renderer_name':self.name,
+ 'renderer_type':self.type,
+ 'renderer_package':self.package,
'context':getattr(request, 'context', None),
'request':request,
}
diff --git a/pyramid/testing.py b/pyramid/testing.py
index 188485635..26873680e 100644
--- a/pyramid/testing.py
+++ b/pyramid/testing.py
@@ -710,7 +710,8 @@ class DummyRendererFactory(object):
package, relative = spec.split(':', 1)
self.renderers[relative] = renderer
- def __call__(self, spec):
+ def __call__(self, info):
+ spec = info['name']
renderer = self.renderers.get(spec)
if renderer is None:
if ':' in spec:
@@ -718,7 +719,7 @@ class DummyRendererFactory(object):
renderer = self.renderers.get(relative)
if renderer is None:
if self.factory:
- renderer = self.factory(spec)
+ renderer = self.factory(info)
else:
raise KeyError('No testing renderer registered for %r' %
spec)
diff --git a/pyramid/tests/test_configuration.py b/pyramid/tests/test_configuration.py
index e24876744..415d760ed 100644
--- a/pyramid/tests/test_configuration.py
+++ b/pyramid/tests/test_configuration.py
@@ -13,8 +13,8 @@ class ConfiguratorTests(unittest.TestCase):
from zope.interface import implements
class Renderer:
implements(ITemplateRenderer)
- def __init__(self, path):
- self.__class__.path = path
+ def __init__(self, info):
+ self.__class__.info = info
def __call__(self, *arg):
return 'Hello!'
config.registry.registerUtility(Renderer, IRendererFactory, name=name)
@@ -1353,6 +1353,7 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(wrapper(ctx, request), 'view8')
def test_add_view_with_template_renderer(self):
+ import pyramid.tests
class view(object):
def __init__(self, context, request):
self.request = request
@@ -1368,9 +1369,13 @@ class ConfiguratorTests(unittest.TestCase):
request = self._makeRequest(config)
result = wrapper(None, request)
self.assertEqual(result.body, 'Hello!')
- self.assertEqual(renderer.path, 'pyramid.tests:fixtures/minimal.txt')
+ self.assertEqual(renderer.info,
+ {'registry':config.registry, 'type': '.txt',
+ 'name': 'pyramid.tests:fixtures/minimal.txt',
+ 'package': pyramid.tests})
def test_add_view_with_template_renderer_no_callable(self):
+ import pyramid.tests
config = self._makeOne()
renderer = self._registerRenderer(config)
fixture = 'pyramid.tests:fixtures/minimal.txt'
@@ -1379,7 +1384,12 @@ class ConfiguratorTests(unittest.TestCase):
request = self._makeRequest(config)
result = wrapper(None, request)
self.assertEqual(result.body, 'Hello!')
- self.assertEqual(renderer.path, 'pyramid.tests:fixtures/minimal.txt')
+ self.assertEqual(renderer.info,
+ {'registry':config.registry,
+ 'type': '.txt',
+ 'name': 'pyramid.tests:fixtures/minimal.txt',
+ 'package':pyramid.tests}
+ )
def test_add_view_with_request_type_as_iface(self):
from zope.interface import directlyProvides
@@ -3257,8 +3267,8 @@ class Test__map_view(unittest.TestCase):
def test__map_view_as_function_with_attr_and_renderer(self):
renderer = self._registerRenderer()
view = lambda *arg: 'OK'
- result = self._callFUT(view, attr='__name__',
- renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='__name__', renderer=info)
self.failIf(result is view)
self.assertRaises(TypeError, result, None, None)
@@ -3316,7 +3326,8 @@ class Test__map_view(unittest.TestCase):
pass
def index(self):
return {'a':'1'}
- result = self._callFUT(view, attr='index', renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='index', renderer=info)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
self.assertEqual(view.__doc__, result.__doc__)
@@ -3357,7 +3368,8 @@ class Test__map_view(unittest.TestCase):
pass
def index(self):
return {'a':'1'}
- result = self._callFUT(view, attr='index', renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='index', renderer=info)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
self.assertEqual(view.__doc__, result.__doc__)
@@ -3398,7 +3410,8 @@ class Test__map_view(unittest.TestCase):
pass
def index(self):
return {'a':'1'}
- result = self._callFUT(view, attr='index', renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='index', renderer=info)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
self.assertEqual(view.__doc__, result.__doc__)
@@ -3439,7 +3452,8 @@ class Test__map_view(unittest.TestCase):
pass
def index(self):
return {'a':'1'}
- result = self._callFUT(view, attr='index', renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='index', renderer=info)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
self.assertEqual(view.__doc__, result.__doc__)
@@ -3471,7 +3485,8 @@ class Test__map_view(unittest.TestCase):
def index(self, context, request):
return {'a':'1'}
view = View()
- result = self._callFUT(view, attr='index', renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='index', renderer=info)
self.failIf(result is view)
request = self._makeRequest()
self.assertEqual(result(None, request).body, 'Hello!')
@@ -3506,7 +3521,8 @@ class Test__map_view(unittest.TestCase):
def index(self, request):
return {'a':'1'}
view = View()
- result = self._callFUT(view, attr='index', renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, attr='index', renderer=info)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
self.assertEqual(view.__doc__, result.__doc__)
@@ -3518,7 +3534,8 @@ class Test__map_view(unittest.TestCase):
renderer = self._registerRenderer()
def view(context, request):
return {'a':'1'}
- result = self._callFUT(view, renderer_name=renderer.spec)
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, renderer=info)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
self.assertEqual(view.__doc__, result.__doc__)
@@ -3529,7 +3546,8 @@ class Test__map_view(unittest.TestCase):
renderer = self._registerRenderer()
def view(context, request):
return {'a':'1'}
- result = self._callFUT(view, renderer_name=renderer.spec,
+ info = {'name':renderer.spec, 'package':None}
+ result = self._callFUT(view, renderer=info,
registry=self.registry)
self.failIf(result is view)
self.assertEqual(view.__module__, result.__module__)
@@ -3537,19 +3555,6 @@ class Test__map_view(unittest.TestCase):
request = self._makeRequest()
self.assertEqual(result(None, request).body, 'Hello!')
- def test__map_view_with_package(self):
- renderer = self._registerRenderer()
- def view(context, request):
- return {'a':'1'}
- result = self._callFUT(view, renderer_name=renderer.spec,
- package='pyramid')
- self.failIf(result is view)
- self.assertEqual(view.__module__, result.__module__)
- self.assertEqual(view.__doc__, result.__doc__)
- request = self._makeRequest()
- self.assertEqual(result(None, request).body, 'Hello!')
- self.assertEqual(renderer.path, 'pyramid:abc.txt')
-
class Test_decorate_view(unittest.TestCase):
def _callFUT(self, wrapped, original):
from pyramid.configuration import decorate_view
diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py
index 54df83a79..37780d1ba 100644
--- a/pyramid/tests/test_mako_templating.py
+++ b/pyramid/tests/test_mako_templating.py
@@ -15,18 +15,22 @@ class Base(object):
self.config.end()
class Test_renderer_factory(Base, unittest.TestCase):
- def _callFUT(self, path):
+ def _callFUT(self, info):
from pyramid.mako_templating import renderer_factory
- return renderer_factory(path)
+ return renderer_factory(info)
def test_no_directories(self):
from pyramid.exceptions import ConfigurationError
- self.assertRaises(ConfigurationError, self._callFUT, 'path')
+ info = {'name':'helloworld.mak', 'package':None,
+ 'registry':self.config.registry}
+ self.assertRaises(ConfigurationError, self._callFUT, info)
def test_no_lookup(self):
from pyramid.mako_templating import IMakoLookup
self.config.add_settings({'mako.directories':self.templates_dir})
- renderer = self._callFUT('helloworld.mak')
+ info = {'name':'helloworld.mak', 'package':None,
+ 'registry':self.config.registry}
+ renderer = self._callFUT(info)
lookup = self.config.registry.getUtility(IMakoLookup)
self.assertEqual(lookup.directories, [self.templates_dir])
self.assertEqual(lookup.filesystem_checks, False)
@@ -37,7 +41,9 @@ class Test_renderer_factory(Base, unittest.TestCase):
from pyramid.mako_templating import IMakoLookup
twice = self.templates_dir + '\n' + self.templates_dir
self.config.add_settings({'mako.directories':twice})
- self._callFUT('helloworld.mak')
+ info = {'name':'helloworld.mak', 'package':None,
+ 'registry':self.config.registry}
+ self._callFUT(info)
lookup = self.config.registry.getUtility(IMakoLookup)
self.assertEqual(lookup.directories, [self.templates_dir]*2)
@@ -45,7 +51,9 @@ class Test_renderer_factory(Base, unittest.TestCase):
from pyramid.mako_templating import IMakoLookup
lookup = dict()
self.config.registry.registerUtility(lookup, IMakoLookup)
- renderer = self._callFUT('helloworld.mak')
+ info = {'name':'helloworld.mak', 'package':None,
+ 'registry':self.config.registry}
+ renderer = self._callFUT(info)
self.assertEqual(renderer.lookup, lookup)
self.assertEqual(renderer.path, 'helloworld.mak')
@@ -163,8 +171,46 @@ class TestIntegration(unittest.TestCase):
def test_template_not_found(self):
from pyramid.renderers import render
from mako.exceptions import TemplateLookupException
- self.assertRaises(TemplateLookupException, render, 'helloworld_not_here.mak', {})
+ self.assertRaises(TemplateLookupException, render,
+ 'helloworld_not_here.mak', {})
+class TestPkgResourceTemplateLookup(unittest.TestCase):
+ 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_resource_spec(self):
+ inst = self._makeOne()
+ result = inst.adjust_uri('a', None)
+ self.assertEqual(result, '/a')
+
+ def test_adjust_uri_resource_spec(self):
+ inst = self._makeOne()
+ result = inst.adjust_uri('a:b', None)
+ self.assertEqual(result, 'a:b')
+
+ def test_get_template_not_resource_spec(self):
+ fixturedir = self.get_fixturedir()
+ inst = self._makeOne(directories=[fixturedir])
+ result = inst.get_template('helloworld.mak')
+ self.failIf(result is None)
+
+ def test_get_template_resource_spec_with_filesystem_checks(self):
+ inst = self._makeOne(filesystem_checks=True)
+ result = inst.get_template('pyramid.tests:fixtures/helloworld.mak')
+ self.failIf(result is None)
+
+ def test_get_template_resource_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 DummyLookup(object):
def get_template(self, path):
diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py
index 7f4d893e8..917bb7c40 100644
--- a/pyramid/tests/test_renderers.py
+++ b/pyramid/tests/test_renderers.py
@@ -5,7 +5,7 @@ from pyramid import testing
class TestTemplateRendererFactory(unittest.TestCase):
def setUp(self):
- cleanUp()
+ self.config = cleanUp()
def tearDown(self):
cleanUp()
@@ -18,7 +18,9 @@ class TestTemplateRendererFactory(unittest.TestCase):
from pyramid.interfaces import ITemplateRenderer
abspath = '/wont/exist'
testing.registerUtility({}, ITemplateRenderer, name=abspath)
- self.assertRaises(ValueError, self._callFUT, abspath, None)
+ info = {'name':abspath, 'package':None,
+ 'registry':self.config.registry}
+ self.assertRaises(ValueError, self._callFUT, info, None)
def test_abspath_alreadyregistered(self):
from pyramid.interfaces import ITemplateRenderer
@@ -26,7 +28,9 @@ class TestTemplateRendererFactory(unittest.TestCase):
abspath = os.path.abspath(__file__)
renderer = {}
testing.registerUtility(renderer, ITemplateRenderer, name=abspath)
- result = self._callFUT(abspath, None)
+ info = {'name':abspath, 'package':None,
+ 'registry':self.config.registry}
+ result = self._callFUT(info, None)
self.failUnless(result is renderer)
def test_abspath_notyetregistered(self):
@@ -35,26 +39,37 @@ class TestTemplateRendererFactory(unittest.TestCase):
abspath = os.path.abspath(__file__)
renderer = {}
testing.registerUtility(renderer, ITemplateRenderer, name=abspath)
- result = self._callFUT(abspath, None)
+ info = {'name':abspath, 'package':None,
+ 'registry':self.config.registry}
+ result = self._callFUT(info, None)
self.failUnless(result is renderer)
def test_relpath_path_registered(self):
renderer = {}
from pyramid.interfaces import ITemplateRenderer
testing.registerUtility(renderer, ITemplateRenderer, name='foo/bar')
- result = self._callFUT('foo/bar', None)
+ spec = 'foo/bar'
+ info = {'name':spec, 'package':None,
+ 'registry':self.config.registry}
+ result = self._callFUT(info, None)
self.failUnless(renderer is result)
- def test_relpath_is_package_registered(self):
+ def test_relpath_has_package_registered(self):
renderer = {}
from pyramid.interfaces import ITemplateRenderer
- testing.registerUtility(renderer, ITemplateRenderer, name='foo:bar/baz')
- result = self._callFUT('foo:bar/baz', None)
+ import pyramid.tests
+ spec = 'bar/baz'
+ testing.registerUtility(renderer, ITemplateRenderer,
+ name='pyramid.tests:bar/baz')
+ info = {'name':spec, 'package':pyramid.tests,
+ 'registry':self.config.registry}
+ result = self._callFUT(info, None)
self.failUnless(renderer is result)
def test_spec_notfound(self):
- self.assertRaises(ValueError, self._callFUT,
- 'pyramid.tests:wont/exist', None)
+ spec = 'pyramid.tests:wont/exist'
+ info = {'name':spec, 'package':None, 'registry':self.config.registry}
+ self.assertRaises(ValueError, self._callFUT, info, None)
def test_spec_alreadyregistered(self):
from pyramid.interfaces import ITemplateRenderer
@@ -62,9 +77,10 @@ class TestTemplateRendererFactory(unittest.TestCase):
module_name = tests.__name__
relpath = 'test_renderers.py'
spec = '%s:%s' % (module_name, relpath)
+ info = {'name':spec, 'package':None, 'registry':self.config.registry}
renderer = {}
testing.registerUtility(renderer, ITemplateRenderer, name=spec)
- result = self._callFUT(spec, None)
+ result = self._callFUT(info, None)
self.failUnless(result is renderer)
def test_spec_notyetregistered(self):
@@ -75,7 +91,8 @@ class TestTemplateRendererFactory(unittest.TestCase):
renderer = {}
factory = DummyFactory(renderer)
spec = '%s:%s' % (module_name, relpath)
- result = self._callFUT(spec, factory)
+ info = {'name':spec, 'package':None, 'registry':self.config.registry}
+ result = self._callFUT(info, factory)
self.failUnless(result is renderer)
path = os.path.abspath(__file__)
if path.endswith('pyc'): # pragma: no cover
@@ -84,6 +101,7 @@ class TestTemplateRendererFactory(unittest.TestCase):
self.assertEqual(factory.kw, {})
def test_reload_resources_true(self):
+ import pyramid.tests
from pyramid.threadlocal import get_current_registry
from pyramid.interfaces import ISettings
from pyramid.interfaces import ITemplateRenderer
@@ -91,7 +109,10 @@ class TestTemplateRendererFactory(unittest.TestCase):
testing.registerUtility(settings, ISettings)
renderer = {}
factory = DummyFactory(renderer)
- result = self._callFUT('pyramid.tests:test_renderers.py', factory)
+ spec = 'test_renderers.py'
+ info = {'name':spec, 'package':pyramid.tests,
+ 'registry':self.config.registry}
+ result = self._callFUT(info, factory)
self.failUnless(result is renderer)
spec = '%s:%s' % ('pyramid.tests', 'test_renderers.py')
reg = get_current_registry()
@@ -99,6 +120,7 @@ class TestTemplateRendererFactory(unittest.TestCase):
None)
def test_reload_resources_false(self):
+ import pyramid.tests
from pyramid.threadlocal import get_current_registry
from pyramid.interfaces import ISettings
from pyramid.interfaces import ITemplateRenderer
@@ -106,7 +128,10 @@ class TestTemplateRendererFactory(unittest.TestCase):
testing.registerUtility(settings, ISettings)
renderer = {}
factory = DummyFactory(renderer)
- result = self._callFUT('pyramid.tests:test_renderers.py', factory)
+ spec = 'test_renderers.py'
+ info = {'name':spec, 'package':pyramid.tests,
+ 'registry':self.config.registry}
+ result = self._callFUT(info, factory)
self.failUnless(result is renderer)
spec = '%s:%s' % ('pyramid.tests', 'test_renderers.py')
reg = get_current_registry()
@@ -125,24 +150,39 @@ class TestRendererFromName(unittest.TestCase):
return renderer_from_name(path, package)
def test_it(self):
+ from pyramid.threadlocal import get_current_registry
+ registry = get_current_registry()
from pyramid.interfaces import IRendererFactory
import os
here = os.path.dirname(os.path.abspath(__file__))
fixture = os.path.join(here, 'fixtures/minimal.pt')
- def factory(path, **kw):
- return path
+ def factory(info, **kw):
+ return info
testing.registerUtility(factory, IRendererFactory, name='.pt')
result = self._callFUT(fixture)
- self.assertEqual(result, fixture)
-
- def test_with_package(self):
+ self.assertEqual(result, {'registry':registry,
+ 'type':'.pt',
+ 'package':None,
+ 'name':fixture,
+ })
+
+ def test_it_with_package(self):
+ import pyramid
+ from pyramid.threadlocal import get_current_registry
+ registry = get_current_registry()
from pyramid.interfaces import IRendererFactory
- def factory(path, **kw):
- return path
+ import os
+ here = os.path.dirname(os.path.abspath(__file__))
+ fixture = os.path.join(here, 'fixtures/minimal.pt')
+ def factory(info, **kw):
+ return info
testing.registerUtility(factory, IRendererFactory, name='.pt')
- import pyramid.tests
- result = self._callFUT('fixtures/minimal.pt', pyramid.tests)
- self.assertEqual(result, 'pyramid.tests:fixtures/minimal.pt')
+ result = self._callFUT(fixture, pyramid)
+ self.assertEqual(result, {'registry':registry,
+ 'type':'.pt',
+ 'package':pyramid,
+ 'name':fixture,
+ })
def test_it_no_renderer(self):
self.assertRaises(ValueError, self._callFUT, 'foo')
@@ -207,42 +247,6 @@ class Test_string_renderer_factory(unittest.TestCase):
renderer(None, {'request':request})
self.assertEqual(request.response_content_type, 'text/mishmash')
-class Test_rendered_response(unittest.TestCase):
- def setUp(self):
- testing.setUp()
- from zope.deprecation import __show__
- __show__.off()
-
- def tearDown(self):
- testing.tearDown()
- from zope.deprecation import __show__
- __show__.on()
-
- def _callFUT(self, renderer, response, view=None,
- context=None, request=None, renderer_name=None):
- from pyramid.renderers import rendered_response
- if request is None:
- request = testing.DummyRequest()
- return rendered_response(renderer, response, view,
- context, request, renderer_name)
-
- def _makeRenderer(self):
- def renderer(*arg):
- return 'Hello!'
- return renderer
-
- def test_is_response(self):
- renderer = self._makeRenderer()
- response = DummyResponse()
- result = self._callFUT(renderer, response)
- self.assertEqual(result, response)
-
- def test_calls_renderer(self):
- renderer = self._makeRenderer()
- response = {'a':'1'}
- result = self._callFUT(renderer, response)
- self.assertEqual(result.body, 'Hello!')
-
class TestRendererHelper(unittest.TestCase):
def setUp(self):
@@ -265,26 +269,6 @@ class TestRendererHelper(unittest.TestCase):
name='.foo')
return renderer
- def test_resolve_spec_path_is_None(self):
- helper = self._makeOne('loo.foo')
- result = helper.resolve_spec(None)
- self.assertEqual(result, None)
-
- def test_resolve_spec_package_is_None(self):
- helper = self._makeOne('loo.foo')
- result = helper.resolve_spec('/foo/bar')
- self.assertEqual(result, '/foo/bar')
-
- def test_resolve_spec_absolute(self):
- helper = self._makeOne('loo.foo')
- result = helper.resolve_spec('pyramid:flub')
- self.assertEqual(result, 'pyramid:flub')
-
- def test_resolve_spec_relative(self):
- helper = self._makeOne('loo.foo', package='pyramid')
- result = helper.resolve_spec('flub')
- self.assertEqual(result, 'pyramid:flub')
-
def test_render_to_response(self):
self._registerRendererFactory()
request = Dummy()
@@ -314,8 +298,12 @@ class TestRendererHelper(unittest.TestCase):
request.context = context
helper = self._makeOne('loo.foo')
result = helper.render('values', None, request=request)
- system = {'request':request, 'context':context,
- 'renderer_name':'loo.foo', 'view':None}
+ system = {'request':request,
+ 'context':context,
+ 'renderer_name':'loo.foo',
+ 'view':None,
+ 'renderer_type':'.foo',
+ 'renderer_package':None}
self.assertEqual(result, ('values', system))
def test_render_renderer_globals_factory_active(self):
diff --git a/pyramid/tests/test_testing.py b/pyramid/tests/test_testing.py
index 05f9ad518..5929ce650 100644
--- a/pyramid/tests/test_testing.py
+++ b/pyramid/tests/test_testing.py
@@ -655,22 +655,26 @@ class TestDummyRendererFactory(unittest.TestCase):
def test_call(self):
f = self._makeOne('name', None)
f.renderers['spec'] = 'renderer'
- self.assertEqual(f('spec'), 'renderer')
+ info = {'name':'spec'}
+ self.assertEqual(f(info), 'renderer')
def test_call2(self):
f = self._makeOne('name', None)
f.renderers['spec'] = 'renderer'
- self.assertEqual(f('spec:spec'), 'renderer')
+ info = {'name':'spec:spec'}
+ self.assertEqual(f(info), 'renderer')
def test_call3(self):
def factory(spec):
return 'renderer'
f = self._makeOne('name', factory)
- self.assertEqual(f('spec'), 'renderer')
+ info = {'name':'spec'}
+ self.assertEqual(f(info), 'renderer')
def test_call_miss(self):
f = self._makeOne('name', None)
- self.assertRaises(KeyError, f, 'spec')
+ info = {'name':'spec'}
+ self.assertRaises(KeyError, f, info)
class TestMockTemplate(unittest.TestCase):
def _makeOne(self, response):
diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py
index fc725379e..64c2d9518 100644
--- a/pyramid/tests/test_view.py
+++ b/pyramid/tests/test_view.py
@@ -306,18 +306,8 @@ class TestViewConfigDecorator(unittest.TestCase):
settings = call_venusian(venusian)
self.assertEqual(settings[0]['custom_predicates'], (1,))
- def test_call_with_renderer_nodot(self):
- decorator = self._makeOne(renderer='json')
- venusian = DummyVenusian()
- decorator.venusian = venusian
- def foo(): pass
- wrapped = decorator(foo)
- self.failUnless(wrapped is foo)
- settings = call_venusian(venusian)
- self.assertEqual(len(settings), 1)
- self.assertEqual(settings[0]['renderer'], 'json')
-
- def test_call_with_renderer_relpath(self):
+ def test_call_with_renderer_string(self):
+ import pyramid.tests
decorator = self._makeOne(renderer='fixtures/minimal.pt')
venusian = DummyVenusian()
decorator.venusian = venusian
@@ -326,12 +316,14 @@ class TestViewConfigDecorator(unittest.TestCase):
self.failUnless(wrapped is foo)
settings = call_venusian(venusian)
self.assertEqual(len(settings), 1)
- self.assertEqual(settings[0]['renderer'],
- 'pyramid.tests:fixtures/minimal.pt')
-
- def test_call_with_renderer_pkgpath(self):
- decorator = self._makeOne(
- renderer='pyramid.tests:fixtures/minimal.pt')
+ renderer = settings[0]['renderer']
+ self.assertEqual(renderer,
+ {'name':'fixtures/minimal.pt',
+ 'package':pyramid.tests,
+ })
+
+ def test_call_with_renderer_dict(self):
+ decorator = self._makeOne(renderer={'a':1})
venusian = DummyVenusian()
decorator.venusian = venusian
def foo(): pass
@@ -339,8 +331,7 @@ class TestViewConfigDecorator(unittest.TestCase):
self.failUnless(wrapped is foo)
settings = call_venusian(venusian)
self.assertEqual(len(settings), 1)
- self.assertEqual(settings[0]['renderer'],
- 'pyramid.tests:fixtures/minimal.pt')
+ self.assertEqual(settings[0]['renderer'], {'a':1})
class Test_append_slash_notfound_view(BaseTest, unittest.TestCase):
def _callFUT(self, context, request):
diff --git a/pyramid/view.py b/pyramid/view.py
index 68a8b92e7..4b1eb94ed 100644
--- a/pyramid/view.py
+++ b/pyramid/view.py
@@ -1,5 +1,4 @@
import mimetypes
-import os
# See http://bugs.python.org/issue5853 which is a recursion bug
# that seems to effect Python 2.6, Python 2.6.1, and 2.6.2 (a fix
@@ -21,8 +20,6 @@ from pyramid.interfaces import IRoutesMapper
from pyramid.interfaces import IView
from pyramid.interfaces import IViewClassifier
-from pyramid.path import package_path
-from pyramid.resource import resource_spec_from_abspath
from pyramid.static import static_view as static # B/C
from pyramid.threadlocal import get_current_registry
@@ -417,19 +414,10 @@ class view_config(object):
if settings['attr'] is None:
settings['attr'] = wrapped.__name__
- # try to convert the renderer provided into a fully qualified
- # resource specification
- abspath = settings.get('renderer')
- if abspath is not None and '.' in abspath:
- isabs = os.path.isabs(abspath)
- if not (':' in abspath and not isabs):
- # not already a resource spec
- if not isabs:
- pp = package_path(info.module)
- abspath = os.path.join(pp, abspath)
- resource = resource_spec_from_abspath(abspath, info.module)
- settings['renderer'] = resource
-
+ renderer_name = settings.get('renderer')
+ if renderer_name is not None and not isinstance(renderer_name, dict):
+ settings['renderer'] = {'name':renderer_name,
+ 'package':info.module}
return wrapped
bfg_view = view_config # permanent b/c
diff --git a/pyramid/zcml.py b/pyramid/zcml.py
index 80f73a3a2..5382deb99 100644
--- a/pyramid/zcml.py
+++ b/pyramid/zcml.py
@@ -188,8 +188,9 @@ def view(
raise ConfigurationError(
'request_type must be an interface, not %s' % request_type)
- if renderer and '.' in renderer:
- renderer = path_spec(_context, renderer)
+ if renderer is not None:
+ package = getattr(_context, 'package', None)
+ renderer = {'name':renderer, 'package':package}
context = context or for_