summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt36
-rw-r--r--docs/narr/viewconfig.rst11
-rw-r--r--docs/whatsnew-1.4.rst10
-rw-r--r--pyramid/chameleon_zpt.py10
-rw-r--r--pyramid/config/predicates.py49
-rw-r--r--pyramid/config/testing.py26
-rw-r--r--pyramid/config/views.py9
-rw-r--r--pyramid/renderers.py31
-rw-r--r--pyramid/session.py5
-rw-r--r--pyramid/testing.py15
-rw-r--r--pyramid/tests/fixtures/withmacro.pt1
-rw-r--r--pyramid/tests/test_chameleon_zpt.py9
-rw-r--r--pyramid/tests/test_config/test_predicates.py86
-rw-r--r--pyramid/tests/test_config/test_testing.py24
-rw-r--r--pyramid/tests/test_renderers.py7
15 files changed, 263 insertions, 66 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index e40401528..95375e5ba 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,9 +1,19 @@
Next release
============
+Features
+--------
+
+- Allow multiple values to be specified to the ``request_param`` view/route
+ predicate as a sequence. Previously only a single string value was allowed.
+ See https://github.com/Pylons/pyramid/pull/705
+
Bug Fixes
---------
+- The match_param predicate's text method was fixed to sort its values.
+ Part of https://github.com/Pylons/pyramid/pull/705
+
- 1.4a ``pyramid.scripting.prepare`` behaved differently than 1.3 series
function of same name. In particular, if passed a request, it would not
set the ``registry`` attribute of the request like 1.3 did. A symptom
@@ -14,6 +24,32 @@ Bug Fixes
1.4 too (a registry is attached to a request passed to bootstrap or
prepare).
+- When registering a view configuration that named a Chameleon ZPT renderer
+ with a macro name in it (e.g. ``renderer='some/template#somemacro.pt``) as
+ well as a view configuration without a macro name it it that pointed to the
+ same template (e.g. ``renderer='some/template.pt'), internal caching could
+ confuse the two, and your code might have rendered one instead of the
+ other.
+
+Features
+--------
+
+- The Configurator ``testing_securitypolicy`` method now returns the policy
+ object it creates.
+
+- The Configurator ``testing_securitypolicy`` method accepts two new
+ arguments: ``remember_result`` and ``forget_result``. If supplied, these
+ values influence the result of the policy's ``remember`` and ``forget``
+ methods, respectively.
+
+- The DummySecurityPolicy created by ``testing_securitypolicy`` now sets a
+ ``forgotten`` value on the policy (the value ``True``) when its ``forget``
+ method is called.
+
+- The DummySecurityPolicy created by ``testing_securitypolicy`` now sets a
+ ``remembered`` value on the policy, which is the value of the ``principal``
+ argument it's called with when its ``remember`` method is called.
+
1.4a2 (2012-09-27)
==================
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index f65435cc6..3c7897969 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -290,12 +290,13 @@ configured view.
of the ``REQUEST_METHOD`` of the :term:`WSGI` environment.
``request_param``
- This value can be any string. A view declaration with this argument
- ensures that the view will only be called when the :term:`request` has a
- key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST``
- variable) that has a name which matches the supplied value.
+ This value can be any string or a sequence of strings. A view declaration
+ with this argument ensures that the view will only be called when the
+ :term:`request` has a key in the ``request.params`` dictionary (an HTTP
+ ``GET`` or ``POST`` variable) that has a name which matches the a
+ supplied value.
- If the value supplied has a ``=`` sign in it,
+ If any value supplied has a ``=`` sign in it,
e.g. ``request_param="foo=123"``, then the key (``foo``) must both exist
in the ``request.params`` dictionary, *and* the value must match the right
hand side of the expression (``123``) for the view to "match" the current
diff --git a/docs/whatsnew-1.4.rst b/docs/whatsnew-1.4.rst
index 4e64d8162..6aa390e64 100644
--- a/docs/whatsnew-1.4.rst
+++ b/docs/whatsnew-1.4.rst
@@ -63,7 +63,7 @@ Partial Mako and Chameleon Template Renderings
of rendering the entire template. An example asset spec:
``package:path/to/template#macroname.pt``. This will render the macro
defined as ``macroname`` within the ``template.pt`` template instead of the
- entire templae.
+ entire template.
Subrequest Support
~~~~~~~~~~~~~~~~~~
@@ -78,7 +78,7 @@ Minor Feature Additions
-----------------------
- :meth:`pyramid.config.Configurator.add_directive` now accepts arbitrary
- callables like partials or objects implementing ``__call__`` which dont
+ callables like partials or objects implementing ``__call__`` which don't
have ``__name__`` and ``__doc__`` attributes. See
https://github.com/Pylons/pyramid/issues/621 and
https://github.com/Pylons/pyramid/pull/647.
@@ -112,7 +112,7 @@ Minor Feature Additions
- An :meth:`pyramid.config.Configurator.add_permission` directive method was
added to the Configurator. This directive registers a free-standing
permission introspectable into the Pyramid introspection system.
- Frameworks built atop Pyramid can thus use the the ``permissions``
+ Frameworks built atop Pyramid can thus use the ``permissions``
introspectable category data to build a comprehensive list of permissions
supported by a running system. Before this method was added, permissions
were already registered in this introspectable category as a side effect of
@@ -172,7 +172,7 @@ Backwards Incompatibilities
``bfg.routes.matchdict`` to the request's WSGI environment dictionary.
These values were docs-deprecated in ``repoze.bfg`` 1.0 (effectively seven
minor releases ago). If your code depended on these values, use
- request.matched_route and request.matchdict instead.
+ ``request.matched_route`` and ``request.matchdict`` instead.
- It is no longer possible to pass an environ dictionary directly to
``pyramid.traversal.ResourceTreeTraverser.__call__`` (aka
@@ -223,7 +223,7 @@ Backwards Incompatibilities
* ``registerEventListener``, use
:meth:`pyramid.config.Configurator.testing_add_subscriber` instead.
- * ``registerTemplateRenderer`` (aka `registerDummyRenderer``), use
+ * ``registerTemplateRenderer`` (aka ``registerDummyRenderer``), use
:meth:`pyramid.config.Configurator.testing_add_template` instead.
* ``registerView``, use :meth:`pyramid.config.Configurator.add_view` instead.
diff --git a/pyramid/chameleon_zpt.py b/pyramid/chameleon_zpt.py
index 73203a7cb..d8a8ee1be 100644
--- a/pyramid/chameleon_zpt.py
+++ b/pyramid/chameleon_zpt.py
@@ -18,10 +18,12 @@ class ZPTTemplateRenderer(object):
@reify # avoid looking up reload_templates before manager pushed
def template(self):
- tf = PageTemplateFile(self.path,
- auto_reload=self.lookup.auto_reload,
- debug=self.lookup.debug,
- translate=self.lookup.translate)
+ tf = PageTemplateFile(
+ self.path,
+ auto_reload=self.lookup.auto_reload,
+ debug=self.lookup.debug,
+ translate=self.lookup.translate
+ )
if self.macro:
# render only the portion of the template included in a
# define-macro named the value of self.macro
diff --git a/pyramid/config/predicates.py b/pyramid/config/predicates.py
index 77b55d9b3..100c9454e 100644
--- a/pyramid/config/predicates.py
+++ b/pyramid/config/predicates.py
@@ -1,7 +1,5 @@
import re
-from pyramid.compat import is_nonstr_iter
-
from pyramid.exceptions import ConfigurationError
from pyramid.traversal import (
@@ -64,43 +62,48 @@ class PathInfoPredicate(object):
class RequestParamPredicate(object):
def __init__(self, val, config):
- name = val
- v = None
- if '=' in name:
- name, v = name.split('=', 1)
- name, v = name.strip(), v.strip()
- if v is None:
- self._text = 'request_param %s' % (name,)
- else:
- self._text = 'request_param %s = %s' % (name, v)
- self.name = name
- self.val = v
+ val = as_sorted_tuple(val)
+ reqs = []
+ for p in val:
+ k = p
+ v = None
+ if '=' in p:
+ k, v = p.split('=', 1)
+ k, v = k.strip(), v.strip()
+ reqs.append((k, v))
+ self.val = val
+ self.reqs = reqs
def text(self):
- return self._text
+ return 'request_param %s' % ','.join(
+ ['%s=%s' % (x,y) if y else x for x, y in self.reqs]
+ )
phash = text
def __call__(self, context, request):
- if self.val is None:
- return self.name in request.params
- return request.params.get(self.name) == self.val
-
+ for k, v in self.reqs:
+ actual = request.params.get(k)
+ if actual is None:
+ return False
+ if v is not None and actual != v:
+ return False
+ return True
class HeaderPredicate(object):
def __init__(self, val, config):
name = val
v = None
if ':' in name:
- name, v = name.split(':', 1)
+ name, val_str = name.split(':', 1)
try:
- v = re.compile(v)
+ v = re.compile(val_str)
except re.error as why:
raise ConfigurationError(why.args[0])
if v is None:
self._text = 'header %s' % (name,)
else:
- self._text = 'header %s = %s' % (name, v)
+ self._text = 'header %s=%s' % (name, val_str)
self.name = name
self.val = v
@@ -156,9 +159,7 @@ class RequestTypePredicate(object):
class MatchParamPredicate(object):
def __init__(self, val, config):
- if not is_nonstr_iter(val):
- val = (val,)
- val = sorted(val)
+ val = as_sorted_tuple(val)
self.val = val
reqs = [ p.split('=', 1) for p in val ]
self.reqs = [ (x.strip(), y.strip()) for x, y in reqs ]
diff --git a/pyramid/config/testing.py b/pyramid/config/testing.py
index f40cf25a7..abbbffc10 100644
--- a/pyramid/config/testing.py
+++ b/pyramid/config/testing.py
@@ -19,7 +19,8 @@ from pyramid.config.util import action_method
class TestingConfiguratorMixin(object):
# testing API
def testing_securitypolicy(self, userid=None, groupids=(),
- permissive=True):
+ permissive=True, remember_result=None,
+ forget_result=None):
"""Unit/integration testing helper: Registers a pair of faux
:app:`Pyramid` security policies: a :term:`authentication
policy` and a :term:`authorization policy`.
@@ -31,6 +32,24 @@ class TestingConfiguratorMixin(object):
nonpermissive :term:`authorization policy` is registered; this
policy denies all access.
+ ``remember_result``, if provided, should be the result returned by
+ the ``remember`` method of the faux authentication policy. If it is
+ not provided (or it is provided, and is ``None``), the default value
+ ``[]`` (the empty list) will be returned by ``remember``.
+
+ .. note::
+
+ ``remember_result`` is new as of Pyramid 1.4.
+
+ ``forget_result``, if provided, should be the result returned by
+ the ``forget`` method of the faux authentication policy. If it is
+ not provided (or it is provided, and is ``None``), the default value
+ ``[]`` (the empty list) will be returned by ``forget``.
+
+ .. note::
+
+ ``forget_result`` is new as of Pyramid 1.4.
+
The behavior of the registered :term:`authentication policy`
depends on the values provided for the ``userid`` and
``groupids`` argument. The authentication policy will return
@@ -47,9 +66,12 @@ class TestingConfiguratorMixin(object):
:func:`pyramid.security.principals_allowed_by_permission`.
"""
from pyramid.testing import DummySecurityPolicy
- policy = DummySecurityPolicy(userid, groupids, permissive)
+ policy = DummySecurityPolicy(
+ userid, groupids, permissive, remember_result, forget_result
+ )
self.registry.registerUtility(policy, IAuthorizationPolicy)
self.registry.registerUtility(policy, IAuthenticationPolicy)
+ return policy
def testing_resources(self, resources):
"""Unit/integration testing helper: registers a dictionary of
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 9ace96c1d..15263ad04 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -904,11 +904,12 @@ class ViewsConfiguratorMixin(object):
request_param
- This value can be any string. A view declaration with this
- argument ensures that the view will only be called when the
- :term:`request` has a key in the ``request.params``
+ This value can be any string or any sequence of strings. A view
+ declaration with this argument ensures that the view will only be
+ called when the :term:`request` has a key in the ``request.params``
dictionary (an HTTP ``GET`` or ``POST`` variable) that has a
- name which matches the supplied value. If the value
+ name which matches the supplied value (if the value is a string)
+ or values (if the value is a tuple). If any value
supplied has a ``=`` sign in it,
e.g. ``request_param="foo=123"``, then the key (``foo``)
must both exist in the ``request.params`` dictionary, *and*
diff --git a/pyramid/renderers.py b/pyramid/renderers.py
index 1368e190e..57a61ebba 100644
--- a/pyramid/renderers.py
+++ b/pyramid/renderers.py
@@ -367,6 +367,12 @@ class JSONP(JSON):
@implementer(IChameleonLookup)
class ChameleonRendererLookup(object):
+ spec_re = re.compile(
+ r'(?P<asset>[\w_.:/-]+)'
+ r'(?:\#(?P<defname>[\w_]+))?'
+ r'(\.(?P<ext>.*))'
+ )
+
def __init__(self, impl, registry):
self.impl = impl
self.registry = registry
@@ -417,6 +423,12 @@ class ChameleonRendererLookup(object):
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
@@ -436,27 +448,22 @@ class ChameleonRendererLookup(object):
# spec is a package:relpath asset spec
renderer = registry.queryUtility(ITemplateRenderer, name=spec)
if renderer is None:
- p = re.compile(
- r'(?P<asset>[\w_.:/-]+)'
- r'(?:\#(?P<defname>[\w_]+))?'
- r'(\.(?P<ext>.*))'
- )
- asset, macro, ext = p.match(spec).group(
- 'asset', 'defname', 'ext'
- )
- spec = '%s.%s' % (asset, ext)
+ asset, macro, ext = self._crack_spec(spec)
+ spec_without_macro = '%s.%s' % (asset, ext)
try:
- package_name, filename = spec.split(':', 1)
+ 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
+ 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, abspath))
+ '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'):
diff --git a/pyramid/session.py b/pyramid/session.py
index 3b2834693..a5e6a8d3a 100644
--- a/pyramid/session.py
+++ b/pyramid/session.py
@@ -83,8 +83,9 @@ def signed_deserialize(serialized, secret, hmac=hmac):
def check_csrf_token(request, token='csrf_token', raises=True):
""" Check the CSRF token in the request's session against the value in
- ``request.params.get(token)``. If ``token`` is not supplied, the string
- value ``csrf_token`` will be used as the token value. If the value in
+ ``request.params.get(token)``. If a ``token`` keyword is not supplied
+ to this function, the string ``csrf_token`` will be used to look up
+ the token within ``request.params``. If the value in
``request.params.get(token)`` doesn't match the value supplied by
``request.session.get_csrf_token()``, and ``raises`` is ``True``, this
function will raise an :exc:`pyramid.httpexceptions.HTTPBadRequest`
diff --git a/pyramid/testing.py b/pyramid/testing.py
index 9e8f2bff3..cecf13469 100644
--- a/pyramid/testing.py
+++ b/pyramid/testing.py
@@ -53,10 +53,17 @@ class DummyRootFactory(object):
class DummySecurityPolicy(object):
""" A standin for both an IAuthentication and IAuthorization policy """
- def __init__(self, userid=None, groupids=(), permissive=True):
+ def __init__(self, userid=None, groupids=(), permissive=True,
+ remember_result=None, forget_result=None):
self.userid = userid
self.groupids = groupids
self.permissive = permissive
+ if remember_result is None:
+ remember_result = []
+ if forget_result is None:
+ forget_result = []
+ self.remember_result = remember_result
+ self.forget_result = forget_result
def authenticated_userid(self, request):
return self.userid
@@ -73,10 +80,12 @@ class DummySecurityPolicy(object):
return effective_principals
def remember(self, request, principal, **kw):
- return []
+ self.remembered = principal
+ return self.remember_result
def forget(self, request):
- return []
+ self.forgotten = True
+ return self.forget_result
def permits(self, context, principals, permission):
return self.permissive
diff --git a/pyramid/tests/fixtures/withmacro.pt b/pyramid/tests/fixtures/withmacro.pt
index 8bca01e4d..6fa654645 100644
--- a/pyramid/tests/fixtures/withmacro.pt
+++ b/pyramid/tests/fixtures/withmacro.pt
@@ -1,4 +1,5 @@
<html>
+Outside macro
<metal:m define-macro="foo">
Hello!
</metal:m>
diff --git a/pyramid/tests/test_chameleon_zpt.py b/pyramid/tests/test_chameleon_zpt.py
index 37538e83e..5ac57f869 100644
--- a/pyramid/tests/test_chameleon_zpt.py
+++ b/pyramid/tests/test_chameleon_zpt.py
@@ -132,8 +132,13 @@ class ZPTTemplateRendererTests(Base, unittest.TestCase):
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,
+ '<html>\nOutside macro\n\n Hello!\n\n</html>\n\n')
class DummyLookup(object):
auto_reload=True
diff --git a/pyramid/tests/test_config/test_predicates.py b/pyramid/tests/test_config/test_predicates.py
index 005b1b27a..2f0ef4132 100644
--- a/pyramid/tests/test_config/test_predicates.py
+++ b/pyramid/tests/test_config/test_predicates.py
@@ -117,6 +117,20 @@ class TestRequestParamPredicate(unittest.TestCase):
result = inst(None, request)
self.assertTrue(result)
+ def test___call___true_multi(self):
+ inst = self._makeOne(('abc', 'def =2 '))
+ request = Dummy()
+ request.params = {'abc':'1', 'def': '2'}
+ result = inst(None, request)
+ self.assertTrue(result)
+
+ def test___call___false_multi(self):
+ inst = self._makeOne(('abc=3', 'def =2 '))
+ request = Dummy()
+ request.params = {'abc':'3', 'def': '1'}
+ result = inst(None, request)
+ self.assertFalse(result)
+
def test___call___false(self):
inst = self._makeOne('abc')
request = Dummy()
@@ -130,7 +144,11 @@ class TestRequestParamPredicate(unittest.TestCase):
def test_text_withval(self):
inst = self._makeOne('abc= 1')
- self.assertEqual(inst.text(), 'request_param abc = 1')
+ self.assertEqual(inst.text(), 'request_param abc=1')
+
+ def test_text_multi(self):
+ inst = self._makeOne(('abc= 1', 'def'))
+ self.assertEqual(inst.text(), 'request_param abc=1,def')
def test_phash_exists(self):
inst = self._makeOne('abc')
@@ -138,7 +156,7 @@ class TestRequestParamPredicate(unittest.TestCase):
def test_phash_withval(self):
inst = self._makeOne('abc= 1')
- self.assertEqual(inst.phash(), "request_param abc = 1")
+ self.assertEqual(inst.phash(), "request_param abc=1")
class TestMatchParamPredicate(unittest.TestCase):
def _makeOne(self, val):
@@ -299,6 +317,70 @@ class Test_CheckCSRFTokenPredicate(unittest.TestCase):
result = inst(None, request)
self.assertEqual(result, True)
+class TestHeaderPredicate(unittest.TestCase):
+ def _makeOne(self, val):
+ from pyramid.config.predicates import HeaderPredicate
+ return HeaderPredicate(val, None)
+
+ def test___call___true_exists(self):
+ inst = self._makeOne('abc')
+ request = Dummy()
+ request.headers = {'abc':1}
+ result = inst(None, request)
+ self.assertTrue(result)
+
+ def test___call___true_withval(self):
+ inst = self._makeOne('abc:1')
+ request = Dummy()
+ request.headers = {'abc':'1'}
+ result = inst(None, request)
+ self.assertTrue(result)
+
+ def test___call___true_withregex(self):
+ inst = self._makeOne(r'abc:\d+')
+ request = Dummy()
+ request.headers = {'abc':'1'}
+ result = inst(None, request)
+ self.assertTrue(result)
+
+ def test___call___false_withregex(self):
+ inst = self._makeOne(r'abc:\d+')
+ request = Dummy()
+ request.headers = {'abc':'a'}
+ result = inst(None, request)
+ self.assertFalse(result)
+
+ def test___call___false(self):
+ inst = self._makeOne('abc')
+ request = Dummy()
+ request.headers = {}
+ result = inst(None, request)
+ self.assertFalse(result)
+
+ def test_text_exists(self):
+ inst = self._makeOne('abc')
+ self.assertEqual(inst.text(), 'header abc')
+
+ def test_text_withval(self):
+ inst = self._makeOne('abc:1')
+ self.assertEqual(inst.text(), 'header abc=1')
+
+ def test_text_withregex(self):
+ inst = self._makeOne(r'abc:\d+')
+ self.assertEqual(inst.text(), r'header abc=\d+')
+
+ def test_phash_exists(self):
+ inst = self._makeOne('abc')
+ self.assertEqual(inst.phash(), 'header abc')
+
+ def test_phash_withval(self):
+ inst = self._makeOne('abc:1')
+ self.assertEqual(inst.phash(), "header abc=1")
+
+ def test_phash_withregex(self):
+ inst = self._makeOne(r'abc:\d+')
+ self.assertEqual(inst.phash(), r'header abc=\d+')
+
class predicate(object):
def __repr__(self):
return 'predicate'
diff --git a/pyramid/tests/test_config/test_testing.py b/pyramid/tests/test_config/test_testing.py
index 6c048b46d..1089f09fc 100644
--- a/pyramid/tests/test_config/test_testing.py
+++ b/pyramid/tests/test_config/test_testing.py
@@ -23,6 +23,30 @@ class TestingConfiguratorMixinTests(unittest.TestCase):
self.assertEqual(ut.groupids, ('group1', 'group2'))
self.assertEqual(ut.permissive, False)
+ def test_testing_securitypolicy_remember_result(self):
+ from pyramid.security import remember
+ config = self._makeOne(autocommit=True)
+ pol = config.testing_securitypolicy(
+ 'user', ('group1', 'group2'),
+ permissive=False, remember_result=True)
+ request = DummyRequest()
+ request.registry = config.registry
+ val = remember(request, 'fred')
+ self.assertEqual(pol.remembered, 'fred')
+ self.assertEqual(val, True)
+
+ def test_testing_securitypolicy_forget_result(self):
+ from pyramid.security import forget
+ config = self._makeOne(autocommit=True)
+ pol = config.testing_securitypolicy(
+ 'user', ('group1', 'group2'),
+ permissive=False, forget_result=True)
+ request = DummyRequest()
+ request.registry = config.registry
+ val = forget(request)
+ self.assertEqual(pol.forgotten, True)
+ self.assertEqual(val, True)
+
def test_testing_resources(self):
from pyramid.traversal import find_resource
from pyramid.interfaces import ITraverser
diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py
index af9188abc..cb6c364a7 100644
--- a/pyramid/tests/test_renderers.py
+++ b/pyramid/tests/test_renderers.py
@@ -295,6 +295,7 @@ class TestChameleonRendererLookup(unittest.TestCase):
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__
@@ -302,10 +303,11 @@ class TestChameleonRendererLookup(unittest.TestCase):
renderer = {}
factory = DummyFactory(renderer)
spec = '%s:%s' % (module_name, relpath)
+ reg = self.config.registry
info = DummyRendererInfo({
'name':spec,
'package':None,
- 'registry':self.config.registry,
+ 'registry':reg,
'settings':{},
'type':'type',
})
@@ -318,6 +320,9 @@ class TestChameleonRendererLookup(unittest.TestCase):
'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