summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyramid/authentication.py11
-rw-r--r--pyramid/config/__init__.py14
-rw-r--r--pyramid/config/adapters.py7
-rw-r--r--pyramid/config/assets.py2
-rw-r--r--pyramid/config/factories.py2
-rw-r--r--pyramid/config/i18n.py3
-rw-r--r--pyramid/config/predicates.py2
-rw-r--r--pyramid/config/rendering.py2
-rw-r--r--pyramid/config/routes.py7
-rw-r--r--pyramid/config/security.py2
-rw-r--r--pyramid/config/testing.py2
-rw-r--r--pyramid/config/tweens.py7
-rw-r--r--pyramid/config/util.py146
-rw-r--r--pyramid/config/views.py79
-rw-r--r--pyramid/csrf.py5
-rw-r--r--pyramid/predicates.py30
-rw-r--r--pyramid/registry.py2
-rw-r--r--pyramid/tests/test_authentication.py15
-rw-r--r--pyramid/tests/test_config/test_init.py2
-rw-r--r--pyramid/tests/test_config/test_util.py264
-rw-r--r--pyramid/tests/test_config/test_views.py16
-rw-r--r--pyramid/tests/test_decorator.py7
-rw-r--r--pyramid/tests/test_predicates.py38
-rw-r--r--pyramid/tests/test_util.py244
-rw-r--r--pyramid/util.py135
-rw-r--r--pyramid/viewderivers.py55
26 files changed, 553 insertions, 546 deletions
diff --git a/pyramid/authentication.py b/pyramid/authentication.py
index 445d6fcd2..9d61e4d90 100644
--- a/pyramid/authentication.py
+++ b/pyramid/authentication.py
@@ -34,6 +34,7 @@ from pyramid.security import (
)
from pyramid.util import strings_differ
+from pyramid.util import SimpleSerializer
VALID_TOKEN = re.compile(r"^[A-Za-z][A-Za-z0-9+_-]*$")
@@ -797,7 +798,7 @@ class AuthTktCookieHelper(object):
max_age=None, http_only=False, path="/", wild_domain=True,
hashalg='md5', parent_domain=False, domain=None):
- serializer = _SimpleSerializer()
+ serializer = SimpleSerializer()
self.cookie_profile = CookieProfile(
cookie_name=cookie_name,
@@ -1125,14 +1126,6 @@ class BasicAuthAuthenticationPolicy(CallbackAuthenticationPolicy):
return self.check(username, password, request)
-class _SimpleSerializer(object):
- def loads(self, bstruct):
- return native_(bstruct)
-
- def dumps(self, appstruct):
- return bytes_(appstruct)
-
-
HTTPBasicCredentials = namedtuple(
'HTTPBasicCredentials', ['username', 'password'])
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index 886eec0df..f4fcf413e 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -58,12 +58,17 @@ from pyramid.settings import aslist
from pyramid.threadlocal import manager
from pyramid.util import (
- ActionInfo,
WeakOrderedSet,
- action_method,
object_description,
)
+from pyramid.config.util import (
+ ActionInfo,
+ PredicateList,
+ action_method,
+ not_,
+)
+
from pyramid.config.adapters import AdaptersConfiguratorMixin
from pyramid.config.assets import AssetsConfiguratorMixin
from pyramid.config.factories import FactoriesConfiguratorMixin
@@ -74,7 +79,6 @@ from pyramid.config.security import SecurityConfiguratorMixin
from pyramid.config.settings import SettingsConfiguratorMixin
from pyramid.config.testing import TestingConfiguratorMixin
from pyramid.config.tweens import TweensConfiguratorMixin
-from pyramid.config.util import PredicateList, not_
from pyramid.config.views import ViewsConfiguratorMixin
from pyramid.config.zca import ZCAConfiguratorMixin
@@ -83,9 +87,7 @@ from pyramid.path import DottedNameResolver
empty = text_('')
_marker = object()
-ConfigurationError = ConfigurationError # pyflakes
-
-not_ = not_ # pyflakes, this is an API
+not_ = not_ # api
PHASE0_CONFIG = PHASE0_CONFIG # api
PHASE1_CONFIG = PHASE1_CONFIG # api
diff --git a/pyramid/config/adapters.py b/pyramid/config/adapters.py
index a68070134..945faa3c6 100644
--- a/pyramid/config/adapters.py
+++ b/pyramid/config/adapters.py
@@ -10,10 +10,9 @@ from pyramid.interfaces import (
IResourceURL,
)
-from pyramid.config.util import (
- action_method,
- takes_one_arg,
- )
+from pyramid.util import takes_one_arg
+
+from pyramid.config.util import action_method
class AdaptersConfiguratorMixin(object):
diff --git a/pyramid/config/assets.py b/pyramid/config/assets.py
index 6eafc1eb1..b9536df42 100644
--- a/pyramid/config/assets.py
+++ b/pyramid/config/assets.py
@@ -12,7 +12,7 @@ from pyramid.interfaces import (
from pyramid.exceptions import ConfigurationError
from pyramid.threadlocal import get_current_registry
-from pyramid.util import action_method
+from pyramid.config.util import action_method
class OverrideProvider(pkg_resources.DefaultProvider):
def __init__(self, module):
diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py
index 202c3ef61..7a5b589cf 100644
--- a/pyramid/config/factories.py
+++ b/pyramid/config/factories.py
@@ -15,11 +15,11 @@ from pyramid.router import default_execution_policy
from pyramid.traversal import DefaultRootFactory
from pyramid.util import (
- action_method,
get_callable_name,
InstancePropertyHelper,
)
+from pyramid.config.util import action_method
class FactoriesConfiguratorMixin(object):
@action_method
diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py
index 9c5b7e682..5dabe2845 100644
--- a/pyramid/config/i18n.py
+++ b/pyramid/config/i18n.py
@@ -5,7 +5,8 @@ from pyramid.interfaces import (
from pyramid.exceptions import ConfigurationError
from pyramid.path import AssetResolver
-from pyramid.util import action_method
+
+from pyramid.config.util import action_method
class I18NConfiguratorMixin(object):
@action_method
diff --git a/pyramid/config/predicates.py b/pyramid/config/predicates.py
index 5d99d6564..bda763161 100644
--- a/pyramid/config/predicates.py
+++ b/pyramid/config/predicates.py
@@ -1,2 +1,2 @@
import zope.deprecation
-zope.deprecation.moved('pyramid.predicates', 'Pyramid 2.0')
+zope.deprecation.moved('pyramid.predicates', 'Pyramid 1.10')
diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py
index 68671d08e..0d55c41e8 100644
--- a/pyramid/config/rendering.py
+++ b/pyramid/config/rendering.py
@@ -3,8 +3,8 @@ from pyramid.interfaces import (
PHASE1_CONFIG,
)
-from pyramid.util import action_method
from pyramid import renderers
+from pyramid.config.util import action_method
DEFAULT_RENDERERS = (
('json', renderers.json_renderer_factory),
diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py
index 20fdb2b5d..904c7bd4e 100644
--- a/pyramid/config/routes.py
+++ b/pyramid/config/routes.py
@@ -10,15 +10,18 @@ from pyramid.interfaces import (
)
from pyramid.exceptions import ConfigurationError
-from pyramid.registry import predvalseq
from pyramid.request import route_request_iface
from pyramid.urldispatch import RoutesMapper
-from pyramid.config.util import action_method
from pyramid.util import as_sorted_tuple
import pyramid.predicates
+from pyramid.config.util import (
+ action_method,
+ predvalseq,
+)
+
class RoutesConfiguratorMixin(object):
@action_method
def add_route(self,
diff --git a/pyramid/config/security.py b/pyramid/config/security.py
index 20b816161..c7afbcf4e 100644
--- a/pyramid/config/security.py
+++ b/pyramid/config/security.py
@@ -12,9 +12,9 @@ from pyramid.interfaces import (
from pyramid.csrf import LegacySessionCSRFStoragePolicy
from pyramid.exceptions import ConfigurationError
-from pyramid.util import action_method
from pyramid.util import as_sorted_tuple
+from pyramid.config.util import action_method
class SecurityConfiguratorMixin(object):
diff --git a/pyramid/config/testing.py b/pyramid/config/testing.py
index 5df726a31..1daf5cdeb 100644
--- a/pyramid/config/testing.py
+++ b/pyramid/config/testing.py
@@ -14,7 +14,7 @@ from pyramid.traversal import (
split_path_info,
)
-from pyramid.util import action_method
+from pyramid.config.util import action_method
class TestingConfiguratorMixin(object):
# testing API
diff --git a/pyramid/config/tweens.py b/pyramid/config/tweens.py
index 16712ab16..8bf21cf71 100644
--- a/pyramid/config/tweens.py
+++ b/pyramid/config/tweens.py
@@ -15,11 +15,12 @@ from pyramid.tweens import (
EXCVIEW,
)
-from pyramid.config.util import (
- action_method,
+from pyramid.util import (
+ is_string_or_iterable,
TopologicalSorter,
)
-from pyramid.util import is_string_or_iterable
+
+from pyramid.config.util import action_method
class TweensConfiguratorMixin(object):
def add_tween(self, tween_factory, under=None, over=None):
diff --git a/pyramid/config/util.py b/pyramid/config/util.py
index 63f06ff9b..aedebd9e2 100644
--- a/pyramid/config/util.py
+++ b/pyramid/config/util.py
@@ -1,28 +1,81 @@
+import functools
from hashlib import md5
-import inspect
+import traceback
+from zope.interface import implementer
from pyramid.compat import (
bytes_,
- getargspec,
is_nonstr_iter
- )
+)
+from pyramid.interfaces import IActionInfo
-from pyramid.compat import im_func
from pyramid.exceptions import ConfigurationError
+from pyramid.predicates import Notted
from pyramid.registry import predvalseq
-
from pyramid.util import (
TopologicalSorter,
- action_method,
- ActionInfo,
- )
+ takes_one_arg,
+)
+
+TopologicalSorter = TopologicalSorter # support bw-compat imports
+takes_one_arg = takes_one_arg # support bw-compat imports
+
+@implementer(IActionInfo)
+class ActionInfo(object):
+ def __init__(self, file, line, function, src):
+ self.file = file
+ self.line = line
+ self.function = function
+ self.src = src
+
+ def __str__(self):
+ srclines = self.src.split('\n')
+ src = '\n'.join(' %s' % x for x in srclines)
+ return 'Line %s of file %s:\n%s' % (self.line, self.file, src)
+
+def action_method(wrapped):
+ """ Wrapper to provide the right conflict info report data when a method
+ that calls Configurator.action calls another that does the same. Not a
+ documented API but used by some external systems."""
+ def wrapper(self, *arg, **kw):
+ if self._ainfo is None:
+ self._ainfo = []
+ info = kw.pop('_info', None)
+ # backframes for outer decorators to actionmethods
+ backframes = kw.pop('_backframes', 0) + 2
+ if is_nonstr_iter(info) and len(info) == 4:
+ # _info permitted as extract_stack tuple
+ info = ActionInfo(*info)
+ if info is None:
+ try:
+ f = traceback.extract_stack(limit=4)
+
+ # Work around a Python 3.5 issue whereby it would insert an
+ # extra stack frame. This should no longer be necessary in
+ # Python 3.5.1
+ last_frame = ActionInfo(*f[-1])
+ if last_frame.function == 'extract_stack': # pragma: no cover
+ f.pop()
+ info = ActionInfo(*f[-backframes])
+ except Exception: # pragma: no cover
+ info = ActionInfo(None, 0, '', '')
+ self._ainfo.append(info)
+ try:
+ result = wrapped(self, *arg, **kw)
+ finally:
+ self._ainfo.pop()
+ return result
+
+ if hasattr(wrapped, '__name__'):
+ functools.update_wrapper(wrapper, wrapped)
+ wrapper.__docobj__ = wrapped
+ return wrapper
-action_method = action_method # support bw compat imports
-ActionInfo = ActionInfo # support bw compat imports
MAX_ORDER = 1 << 30
DEFAULT_PHASH = md5().hexdigest()
+
class not_(object):
"""
@@ -61,30 +114,6 @@ class not_(object):
def __init__(self, value):
self.value = value
-class Notted(object):
- def __init__(self, predicate):
- self.predicate = predicate
-
- def _notted_text(self, val):
- # if the underlying predicate doesnt return a value, it's not really
- # a predicate, it's just something pretending to be a predicate,
- # so dont update the hash
- if val:
- val = '!' + val
- return val
-
- def text(self):
- return self._notted_text(self.predicate.text())
-
- def phash(self):
- return self._notted_text(self.predicate.phash())
-
- def __call__(self, context, request):
- result = self.predicate(context, request)
- phash = self.phash()
- if phash:
- result = not result
- return result
# under = after
# over = before
@@ -189,52 +218,3 @@ class PredicateList(object):
score = score | bit
order = (MAX_ORDER - score) / (len(preds) + 1)
return order, preds, phash.hexdigest()
-
-def takes_one_arg(callee, attr=None, argname=None):
- ismethod = False
- if attr is None:
- attr = '__call__'
- if inspect.isroutine(callee):
- fn = callee
- elif inspect.isclass(callee):
- try:
- fn = callee.__init__
- except AttributeError:
- return False
- ismethod = hasattr(fn, '__call__')
- else:
- try:
- fn = getattr(callee, attr)
- except AttributeError:
- return False
-
- try:
- argspec = getargspec(fn)
- except TypeError:
- return False
-
- args = argspec[0]
-
- if hasattr(fn, im_func) or ismethod:
- # it's an instance method (or unbound method on py2)
- if not args:
- return False
- args = args[1:]
-
- if not args:
- return False
-
- if len(args) == 1:
- return True
-
- if argname:
-
- defaults = argspec[3]
- if defaults is None:
- defaults = ()
-
- if args[0] == argname:
- if len(args) - len(defaults) == 1:
- return True
-
- return False
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index e5ebc8e07..eb002ec2d 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -1,3 +1,4 @@
+import functools
import inspect
import posixpath
import operator
@@ -54,10 +55,7 @@ from pyramid.httpexceptions import (
default_exceptionresponse_view,
)
-from pyramid.registry import (
- predvalseq,
- Deferred,
- )
+from pyramid.registry import Deferred
from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.static import static_view
@@ -66,10 +64,7 @@ from pyramid.url import parse_url_overrides
from pyramid.view import AppendSlashNotFoundViewFactory
-import pyramid.util
from pyramid.util import (
- viewdefaults,
- action_method,
as_sorted_tuple,
TopologicalSorter,
)
@@ -88,8 +83,10 @@ from pyramid.viewderivers import (
)
from pyramid.config.util import (
+ action_method,
DEFAULT_PHASH,
MAX_ORDER,
+ predvalseq,
)
urljoin = urlparse.urljoin
@@ -183,6 +180,68 @@ class MultiView(object):
continue
raise PredicateMismatch(self.name)
+def attr_wrapped_view(view, info):
+ accept, order, phash = (info.options.get('accept', None),
+ getattr(info, 'order', MAX_ORDER),
+ getattr(info, 'phash', DEFAULT_PHASH))
+ # this is a little silly but we don't want to decorate the original
+ # function with attributes that indicate accept, order, and phash,
+ # so we use a wrapper
+ if (
+ (accept is None) and
+ (order == MAX_ORDER) and
+ (phash == DEFAULT_PHASH)
+ ):
+ return view # defaults
+ def attr_view(context, request):
+ return view(context, request)
+ attr_view.__accept__ = accept
+ attr_view.__order__ = order
+ attr_view.__phash__ = phash
+ attr_view.__view_attr__ = info.options.get('attr')
+ attr_view.__permission__ = info.options.get('permission')
+ return attr_view
+
+attr_wrapped_view.options = ('accept', 'attr', 'permission')
+
+def predicated_view(view, info):
+ preds = info.predicates
+ if not preds:
+ return view
+ def predicate_wrapper(context, request):
+ for predicate in preds:
+ if not predicate(context, request):
+ view_name = getattr(view, '__name__', view)
+ raise PredicateMismatch(
+ 'predicate mismatch for view %s (%s)' % (
+ view_name, predicate.text()))
+ return view(context, request)
+ def checker(context, request):
+ return all((predicate(context, request) for predicate in
+ preds))
+ predicate_wrapper.__predicated__ = checker
+ predicate_wrapper.__predicates__ = preds
+ return predicate_wrapper
+
+def viewdefaults(wrapped):
+ """ Decorator for add_view-like methods which takes into account
+ __view_defaults__ attached to view it is passed. Not a documented API but
+ used by some external systems."""
+ def wrapper(self, *arg, **kw):
+ defaults = {}
+ if arg:
+ view = arg[0]
+ else:
+ view = kw.get('view')
+ view = self.maybe_dotted(view)
+ if inspect.isclass(view):
+ defaults = getattr(view, '__view_defaults__', {}).copy()
+ if '_backframes' not in kw:
+ kw['_backframes'] = 1 # for action_method
+ defaults.update(kw)
+ return wrapped(self, *arg, **defaults)
+ return functools.wraps(wrapped)(wrapper)
+
class ViewsConfiguratorMixin(object):
@viewdefaults
@action_method
@@ -1106,11 +1165,9 @@ class ViewsConfiguratorMixin(object):
raise ConfigurationError('Unknown view options: %s' % (kw,))
def _apply_view_derivers(self, info):
- d = pyramid.viewderivers
-
# These derivers are not really derivers and so have fixed order
- outer_derivers = [('attr_wrapped_view', d.attr_wrapped_view),
- ('predicated_view', d.predicated_view)]
+ outer_derivers = [('attr_wrapped_view', attr_wrapped_view),
+ ('predicated_view', predicated_view)]
view = info.original_view
derivers = self.registry.getUtility(IViewDerivers)
diff --git a/pyramid/csrf.py b/pyramid/csrf.py
index 7c836e5ad..b023bda5f 100644
--- a/pyramid/csrf.py
+++ b/pyramid/csrf.py
@@ -4,8 +4,6 @@ from webob.cookies import CookieProfile
from zope.interface import implementer
-from pyramid.authentication import _SimpleSerializer
-
from pyramid.compat import (
bytes_,
urlparse,
@@ -18,6 +16,7 @@ from pyramid.exceptions import (
from pyramid.interfaces import ICSRFStoragePolicy
from pyramid.settings import aslist
from pyramid.util import (
+ SimpleSerializer,
is_same_domain,
strings_differ
)
@@ -112,7 +111,7 @@ class CookieCSRFStoragePolicy(object):
def __init__(self, cookie_name='csrf_token', secure=False, httponly=False,
domain=None, max_age=None, path='/'):
- serializer = _SimpleSerializer()
+ serializer = SimpleSerializer()
self.cookie_profile = CookieProfile(
cookie_name=cookie_name,
secure=secure,
diff --git a/pyramid/predicates.py b/pyramid/predicates.py
index 3d7bb1b4b..5e54badff 100644
--- a/pyramid/predicates.py
+++ b/pyramid/predicates.py
@@ -12,8 +12,10 @@ from pyramid.traversal import (
)
from pyramid.urldispatch import _compile_route
-from pyramid.util import object_description
-from pyramid.util import as_sorted_tuple
+from pyramid.util import (
+ as_sorted_tuple,
+ object_description,
+)
_marker = object()
@@ -298,3 +300,27 @@ class EffectivePrincipalsPredicate(object):
return True
return False
+class Notted(object):
+ def __init__(self, predicate):
+ self.predicate = predicate
+
+ def _notted_text(self, val):
+ # if the underlying predicate doesnt return a value, it's not really
+ # a predicate, it's just something pretending to be a predicate,
+ # so dont update the hash
+ if val:
+ val = '!' + val
+ return val
+
+ def text(self):
+ return self._notted_text(self.predicate.text())
+
+ def phash(self):
+ return self._notted_text(self.predicate.phash())
+
+ def __call__(self, context, request):
+ result = self.predicate(context, request)
+ phash = self.phash()
+ if phash:
+ result = not result
+ return result
diff --git a/pyramid/registry.py b/pyramid/registry.py
index 7b75aeefc..a741c495e 100644
--- a/pyramid/registry.py
+++ b/pyramid/registry.py
@@ -2,7 +2,6 @@ import operator
import threading
from zope.interface import implementer
-
from zope.interface.registry import Components
from pyramid.compat import text_
@@ -294,6 +293,5 @@ def undefer(v):
class predvalseq(tuple):
""" A subtype of tuple used to represent a sequence of predicate values """
- pass
global_registry = Registry('global')
diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py
index b9a4c6be4..aeb4a467b 100644
--- a/pyramid/tests/test_authentication.py
+++ b/pyramid/tests/test_authentication.py
@@ -1549,21 +1549,6 @@ class TestExtractHTTPBasicCredentials(unittest.TestCase):
self.assertEqual(result.username, 'chrisr')
self.assertEqual(result.password, 'pass')
-
-
-
-class TestSimpleSerializer(unittest.TestCase):
- def _makeOne(self):
- from pyramid.authentication import _SimpleSerializer
- return _SimpleSerializer()
-
- def test_loads(self):
- inst = self._makeOne()
- self.assertEqual(inst.loads(b'abc'), text_('abc'))
-
- def test_dumps(self):
- inst = self._makeOne()
- self.assertEqual(inst.dumps('abc'), bytes_('abc'))
class DummyContext:
pass
diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py
index ab584cc3d..76a3d703d 100644
--- a/pyramid/tests/test_config/test_init.py
+++ b/pyramid/tests/test_config/test_init.py
@@ -852,7 +852,7 @@ pyramid.tests.test_config.dummy_include2""",
self.assertEqual(config.action('discrim', kw={'a':1}), None)
def test_action_autocommit_with_introspectables(self):
- from pyramid.util import ActionInfo
+ from pyramid.config.util import ActionInfo
config = self._makeOne(autocommit=True)
intr = DummyIntrospectable()
config.action('discrim', introspectables=(intr,))
diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py
index bb86a1f56..99c67e8c6 100644
--- a/pyramid/tests/test_config/test_util.py
+++ b/pyramid/tests/test_config/test_util.py
@@ -1,6 +1,38 @@
import unittest
+
from pyramid.compat import text_
+class TestActionInfo(unittest.TestCase):
+ def _getTargetClass(self):
+ from pyramid.config.util import ActionInfo
+ return ActionInfo
+
+ def _makeOne(self, filename, lineno, function, linerepr):
+ return self._getTargetClass()(filename, lineno, function, linerepr)
+
+ def test_class_conforms(self):
+ from zope.interface.verify import verifyClass
+ from pyramid.interfaces import IActionInfo
+ verifyClass(IActionInfo, self._getTargetClass())
+
+ def test_instance_conforms(self):
+ from zope.interface.verify import verifyObject
+ from pyramid.interfaces import IActionInfo
+ verifyObject(IActionInfo, self._makeOne('f', 0, 'f', 'f'))
+
+ def test_ctor(self):
+ inst = self._makeOne('filename', 10, 'function', 'src')
+ self.assertEqual(inst.file, 'filename')
+ self.assertEqual(inst.line, 10)
+ self.assertEqual(inst.function, 'function')
+ self.assertEqual(inst.src, 'src')
+
+ def test___str__(self):
+ inst = self._makeOne('filename', 0, 'function', ' linerepr ')
+ self.assertEqual(str(inst),
+ "Line 0 of file filename:\n linerepr ")
+
+
class TestPredicateList(unittest.TestCase):
def _makeOne(self):
@@ -391,220 +423,6 @@ class TestPredicateList(unittest.TestCase):
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
- return takes_one_arg(view, attr=attr, argname=argname)
-
- def test_requestonly_newstyle_class_no_init(self):
- class foo(object):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_requestonly_newstyle_class_init_toomanyargs(self):
- class foo(object):
- def __init__(self, context, request):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_requestonly_newstyle_class_init_onearg_named_request(self):
- class foo(object):
- def __init__(self, request):
- """ """
- self.assertTrue(self._callFUT(foo))
-
- def test_newstyle_class_init_onearg_named_somethingelse(self):
- class foo(object):
- def __init__(self, req):
- """ """
- self.assertTrue(self._callFUT(foo))
-
- def test_newstyle_class_init_defaultargs_firstname_not_request(self):
- class foo(object):
- def __init__(self, context, request=None):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_newstyle_class_init_defaultargs_firstname_request(self):
- class foo(object):
- def __init__(self, request, foo=1, bar=2):
- """ """
- self.assertTrue(self._callFUT(foo, argname='request'))
-
- def test_newstyle_class_init_firstname_request_with_secondname(self):
- class foo(object):
- def __init__(self, request, two):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_newstyle_class_init_noargs(self):
- class foo(object):
- def __init__():
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_oldstyle_class_no_init(self):
- class foo:
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_oldstyle_class_init_toomanyargs(self):
- class foo:
- def __init__(self, context, request):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_oldstyle_class_init_onearg_named_request(self):
- class foo:
- def __init__(self, request):
- """ """
- self.assertTrue(self._callFUT(foo))
-
- def test_oldstyle_class_init_onearg_named_somethingelse(self):
- class foo:
- def __init__(self, req):
- """ """
- self.assertTrue(self._callFUT(foo))
-
- def test_oldstyle_class_init_defaultargs_firstname_not_request(self):
- class foo:
- def __init__(self, context, request=None):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_oldstyle_class_init_defaultargs_firstname_request(self):
- class foo:
- def __init__(self, request, foo=1, bar=2):
- """ """
- self.assertTrue(self._callFUT(foo, argname='request'), True)
-
- def test_oldstyle_class_init_noargs(self):
- class foo:
- def __init__():
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_function_toomanyargs(self):
- def foo(context, request):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_function_with_attr_false(self):
- def bar(context, request):
- """ """
- def foo(context, request):
- """ """
- foo.bar = bar
- self.assertFalse(self._callFUT(foo, 'bar'))
-
- def test_function_with_attr_true(self):
- def bar(context, request):
- """ """
- def foo(request):
- """ """
- foo.bar = bar
- self.assertTrue(self._callFUT(foo, 'bar'))
-
- def test_function_onearg_named_request(self):
- def foo(request):
- """ """
- self.assertTrue(self._callFUT(foo))
-
- def test_function_onearg_named_somethingelse(self):
- def foo(req):
- """ """
- self.assertTrue(self._callFUT(foo))
-
- def test_function_defaultargs_firstname_not_request(self):
- def foo(context, request=None):
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_function_defaultargs_firstname_request(self):
- def foo(request, foo=1, bar=2):
- """ """
- self.assertTrue(self._callFUT(foo, argname='request'))
-
- def test_function_noargs(self):
- def foo():
- """ """
- self.assertFalse(self._callFUT(foo))
-
- def test_instance_toomanyargs(self):
- class Foo:
- def __call__(self, context, request):
- """ """
- foo = Foo()
- self.assertFalse(self._callFUT(foo))
-
- def test_instance_defaultargs_onearg_named_request(self):
- class Foo:
- def __call__(self, request):
- """ """
- foo = Foo()
- self.assertTrue(self._callFUT(foo))
-
- def test_instance_defaultargs_onearg_named_somethingelse(self):
- class Foo:
- def __call__(self, req):
- """ """
- foo = Foo()
- self.assertTrue(self._callFUT(foo))
-
- def test_instance_defaultargs_firstname_not_request(self):
- class Foo:
- def __call__(self, context, request=None):
- """ """
- foo = Foo()
- self.assertFalse(self._callFUT(foo))
-
- def test_instance_defaultargs_firstname_request(self):
- class Foo:
- def __call__(self, request, foo=1, bar=2):
- """ """
- foo = Foo()
- self.assertTrue(self._callFUT(foo, argname='request'), True)
-
- def test_instance_nocall(self):
- class Foo: pass
- foo = Foo()
- self.assertFalse(self._callFUT(foo))
-
- def test_method_onearg_named_request(self):
- class Foo:
- def method(self, request):
- """ """
- foo = Foo()
- self.assertTrue(self._callFUT(foo.method))
-
- def test_function_annotations(self):
- def foo(bar):
- """ """
- # avoid SyntaxErrors in python2, this if effectively nop
- getattr(foo, '__annotations__', {}).update({'bar': 'baz'})
- self.assertTrue(self._callFUT(foo))
-
-class TestNotted(unittest.TestCase):
- def _makeOne(self, predicate):
- from pyramid.config.util import Notted
- return Notted(predicate)
-
- def test_it_with_phash_val(self):
- pred = DummyPredicate('val')
- inst = self._makeOne(pred)
- self.assertEqual(inst.text(), '!val')
- self.assertEqual(inst.phash(), '!val')
- self.assertEqual(inst(None, None), False)
-
- def test_it_without_phash_val(self):
- pred = DummyPredicate('')
- inst = self._makeOne(pred)
- self.assertEqual(inst.text(), '')
- self.assertEqual(inst.phash(), '')
- self.assertEqual(inst(None, None), True)
-
-
class TestDeprecatedPredicates(unittest.TestCase):
def test_it(self):
import warnings
@@ -613,18 +431,6 @@ class TestDeprecatedPredicates(unittest.TestCase):
from pyramid.config.predicates import XHRPredicate
self.assertEqual(len(w), 1)
-class DummyPredicate(object):
- def __init__(self, result):
- self.result = result
-
- def text(self):
- return self.result
-
- phash = text
-
- def __call__(self, context, request):
- return True
-
class DummyCustomPredicate(object):
def __init__(self):
self.__text__ = 'custom predicate'
@@ -636,8 +442,9 @@ class DummyCustomPredicate(object):
@classmethod
def classmethod_predicate_no_text(*args): pass # pragma: no cover
-class Dummy:
- pass
+class Dummy(object):
+ def __init__(self, **kw):
+ self.__dict__.update(**kw)
class DummyRequest:
subpath = ()
@@ -652,4 +459,3 @@ class DummyRequest:
class DummyConfigurator(object):
def maybe_dotted(self, thing):
return thing
-
diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py
index 860254385..cb554a816 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -542,8 +542,8 @@ class TestViewsConfigurationMixin(unittest.TestCase):
self.assertEqual(wrapper(None, request), 'OK')
def test_add_view_default_phash_overrides_default_phash(self):
- from pyramid.renderers import null_renderer
from pyramid.config.util import DEFAULT_PHASH
+ from pyramid.renderers import null_renderer
from zope.interface import Interface
from pyramid.interfaces import IRequest
from pyramid.interfaces import IView
@@ -564,8 +564,8 @@ class TestViewsConfigurationMixin(unittest.TestCase):
self.assertEqual(wrapper(None, request), 'OK')
def test_add_view_exc_default_phash_overrides_default_phash(self):
- from pyramid.renderers import null_renderer
from pyramid.config.util import DEFAULT_PHASH
+ from pyramid.renderers import null_renderer
from zope.interface import implementedBy
from pyramid.interfaces import IRequest
from pyramid.interfaces import IView
@@ -3385,6 +3385,18 @@ class Test_view_description(unittest.TestCase):
self.assertEqual(result,
'function pyramid.tests.test_config.test_views.view')
+class Test_viewdefaults(unittest.TestCase):
+ def _makeOne(self, wrapped):
+ from pyramid.decorator import reify
+ return reify(wrapped)
+
+ def test_dunder_attrs_copied(self):
+ from pyramid.config.views import viewdefaults
+ decorator = self._makeOne(viewdefaults)
+ self.assertEqual(decorator.__doc__, viewdefaults.__doc__)
+ self.assertEqual(decorator.__name__, viewdefaults.__name__)
+ self.assertEqual(decorator.__module__, viewdefaults.__module__)
+
class DummyRegistry:
utility = None
diff --git a/pyramid/tests/test_decorator.py b/pyramid/tests/test_decorator.py
index 0a98a512d..4b9313e06 100644
--- a/pyramid/tests/test_decorator.py
+++ b/pyramid/tests/test_decorator.py
@@ -21,13 +21,6 @@ class TestReify(unittest.TestCase):
result = decorator.__get__(None)
self.assertEqual(result, decorator)
- def test_dunder_attrs_copied(self):
- from pyramid.util import viewdefaults
- decorator = self._makeOne(viewdefaults)
- self.assertEqual(decorator.__doc__, viewdefaults.__doc__)
- self.assertEqual(decorator.__name__, viewdefaults.__name__)
- self.assertEqual(decorator.__module__, viewdefaults.__module__)
-
class Dummy(object):
pass
diff --git a/pyramid/tests/test_predicates.py b/pyramid/tests/test_predicates.py
index 8a002c24e..da0b44708 100644
--- a/pyramid/tests/test_predicates.py
+++ b/pyramid/tests/test_predicates.py
@@ -514,13 +514,43 @@ class Test_EffectivePrincipalsPredicate(unittest.TestCase):
context = Dummy()
self.assertFalse(inst(context, request))
+
+class TestNotted(unittest.TestCase):
+ def _makeOne(self, predicate):
+ from pyramid.predicates import Notted
+ return Notted(predicate)
+
+ def test_it_with_phash_val(self):
+ pred = DummyPredicate('val')
+ inst = self._makeOne(pred)
+ self.assertEqual(inst.text(), '!val')
+ self.assertEqual(inst.phash(), '!val')
+ self.assertEqual(inst(None, None), False)
+
+ def test_it_without_phash_val(self):
+ pred = DummyPredicate('')
+ inst = self._makeOne(pred)
+ self.assertEqual(inst.text(), '')
+ self.assertEqual(inst.phash(), '')
+ self.assertEqual(inst(None, None), True)
+
class predicate(object):
def __repr__(self):
return 'predicate'
def __hash__(self):
return 1
-
+
class Dummy(object):
- def __init__(self, **kw):
- self.__dict__.update(**kw)
-
+ pass
+
+class DummyPredicate(object):
+ def __init__(self, result):
+ self.result = result
+
+ def text(self):
+ return self.result
+
+ phash = text
+
+ def __call__(self, context, request):
+ return True
diff --git a/pyramid/tests/test_util.py b/pyramid/tests/test_util.py
index 0f7671d59..a76cd2017 100644
--- a/pyramid/tests/test_util.py
+++ b/pyramid/tests/test_util.py
@@ -1,5 +1,9 @@
import unittest
-from pyramid.compat import PY2
+from pyramid.compat import (
+ PY2,
+ text_,
+ bytes_,
+ )
class Test_InstancePropertyHelper(unittest.TestCase):
@@ -747,36 +751,6 @@ class TestSentinel(unittest.TestCase):
r = repr(Sentinel('ABC'))
self.assertEqual(r, 'ABC')
-class TestActionInfo(unittest.TestCase):
- def _getTargetClass(self):
- from pyramid.util import ActionInfo
- return ActionInfo
-
- def _makeOne(self, filename, lineno, function, linerepr):
- return self._getTargetClass()(filename, lineno, function, linerepr)
-
- def test_class_conforms(self):
- from zope.interface.verify import verifyClass
- from pyramid.interfaces import IActionInfo
- verifyClass(IActionInfo, self._getTargetClass())
-
- def test_instance_conforms(self):
- from zope.interface.verify import verifyObject
- from pyramid.interfaces import IActionInfo
- verifyObject(IActionInfo, self._makeOne('f', 0, 'f', 'f'))
-
- def test_ctor(self):
- inst = self._makeOne('filename', 10, 'function', 'src')
- self.assertEqual(inst.file, 'filename')
- self.assertEqual(inst.line, 10)
- self.assertEqual(inst.function, 'function')
- self.assertEqual(inst.src, 'src')
-
- def test___str__(self):
- inst = self._makeOne('filename', 0, 'function', ' linerepr ')
- self.assertEqual(str(inst),
- "Line 0 of file filename:\n linerepr ")
-
class TestCallableName(unittest.TestCase):
def test_valid_ascii(self):
@@ -927,3 +901,211 @@ class Test_make_contextmanager(unittest.TestCase):
mgr = self._callFUT(mygen)
with mgr() as ctx:
self.assertEqual(ctx, 'a')
+
+
+class Test_takes_one_arg(unittest.TestCase):
+ def _callFUT(self, view, attr=None, argname=None):
+ from pyramid.util import takes_one_arg
+ return takes_one_arg(view, attr=attr, argname=argname)
+
+ def test_requestonly_newstyle_class_no_init(self):
+ class foo(object):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_requestonly_newstyle_class_init_toomanyargs(self):
+ class foo(object):
+ def __init__(self, context, request):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_requestonly_newstyle_class_init_onearg_named_request(self):
+ class foo(object):
+ def __init__(self, request):
+ """ """
+ self.assertTrue(self._callFUT(foo))
+
+ def test_newstyle_class_init_onearg_named_somethingelse(self):
+ class foo(object):
+ def __init__(self, req):
+ """ """
+ self.assertTrue(self._callFUT(foo))
+
+ def test_newstyle_class_init_defaultargs_firstname_not_request(self):
+ class foo(object):
+ def __init__(self, context, request=None):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_newstyle_class_init_defaultargs_firstname_request(self):
+ class foo(object):
+ def __init__(self, request, foo=1, bar=2):
+ """ """
+ self.assertTrue(self._callFUT(foo, argname='request'))
+
+ def test_newstyle_class_init_firstname_request_with_secondname(self):
+ class foo(object):
+ def __init__(self, request, two):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_newstyle_class_init_noargs(self):
+ class foo(object):
+ def __init__():
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_oldstyle_class_no_init(self):
+ class foo:
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_oldstyle_class_init_toomanyargs(self):
+ class foo:
+ def __init__(self, context, request):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_oldstyle_class_init_onearg_named_request(self):
+ class foo:
+ def __init__(self, request):
+ """ """
+ self.assertTrue(self._callFUT(foo))
+
+ def test_oldstyle_class_init_onearg_named_somethingelse(self):
+ class foo:
+ def __init__(self, req):
+ """ """
+ self.assertTrue(self._callFUT(foo))
+
+ def test_oldstyle_class_init_defaultargs_firstname_not_request(self):
+ class foo:
+ def __init__(self, context, request=None):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_oldstyle_class_init_defaultargs_firstname_request(self):
+ class foo:
+ def __init__(self, request, foo=1, bar=2):
+ """ """
+ self.assertTrue(self._callFUT(foo, argname='request'), True)
+
+ def test_oldstyle_class_init_noargs(self):
+ class foo:
+ def __init__():
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_function_toomanyargs(self):
+ def foo(context, request):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_function_with_attr_false(self):
+ def bar(context, request):
+ """ """
+ def foo(context, request):
+ """ """
+ foo.bar = bar
+ self.assertFalse(self._callFUT(foo, 'bar'))
+
+ def test_function_with_attr_true(self):
+ def bar(context, request):
+ """ """
+ def foo(request):
+ """ """
+ foo.bar = bar
+ self.assertTrue(self._callFUT(foo, 'bar'))
+
+ def test_function_onearg_named_request(self):
+ def foo(request):
+ """ """
+ self.assertTrue(self._callFUT(foo))
+
+ def test_function_onearg_named_somethingelse(self):
+ def foo(req):
+ """ """
+ self.assertTrue(self._callFUT(foo))
+
+ def test_function_defaultargs_firstname_not_request(self):
+ def foo(context, request=None):
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_function_defaultargs_firstname_request(self):
+ def foo(request, foo=1, bar=2):
+ """ """
+ self.assertTrue(self._callFUT(foo, argname='request'))
+
+ def test_function_noargs(self):
+ def foo():
+ """ """
+ self.assertFalse(self._callFUT(foo))
+
+ def test_instance_toomanyargs(self):
+ class Foo:
+ def __call__(self, context, request):
+ """ """
+ foo = Foo()
+ self.assertFalse(self._callFUT(foo))
+
+ def test_instance_defaultargs_onearg_named_request(self):
+ class Foo:
+ def __call__(self, request):
+ """ """
+ foo = Foo()
+ self.assertTrue(self._callFUT(foo))
+
+ def test_instance_defaultargs_onearg_named_somethingelse(self):
+ class Foo:
+ def __call__(self, req):
+ """ """
+ foo = Foo()
+ self.assertTrue(self._callFUT(foo))
+
+ def test_instance_defaultargs_firstname_not_request(self):
+ class Foo:
+ def __call__(self, context, request=None):
+ """ """
+ foo = Foo()
+ self.assertFalse(self._callFUT(foo))
+
+ def test_instance_defaultargs_firstname_request(self):
+ class Foo:
+ def __call__(self, request, foo=1, bar=2):
+ """ """
+ foo = Foo()
+ self.assertTrue(self._callFUT(foo, argname='request'), True)
+
+ def test_instance_nocall(self):
+ class Foo: pass
+ foo = Foo()
+ self.assertFalse(self._callFUT(foo))
+
+ def test_method_onearg_named_request(self):
+ class Foo:
+ def method(self, request):
+ """ """
+ foo = Foo()
+ self.assertTrue(self._callFUT(foo.method))
+
+ def test_function_annotations(self):
+ def foo(bar):
+ """ """
+ # avoid SyntaxErrors in python2, this if effectively nop
+ getattr(foo, '__annotations__', {}).update({'bar': 'baz'})
+ self.assertTrue(self._callFUT(foo))
+
+
+class TestSimpleSerializer(unittest.TestCase):
+ def _makeOne(self):
+ from pyramid.util import SimpleSerializer
+ return SimpleSerializer()
+
+ def test_loads(self):
+ inst = self._makeOne()
+ self.assertEqual(inst.loads(b'abc'), text_('abc'))
+
+ def test_dumps(self):
+ inst = self._makeOne()
+ self.assertEqual(inst.dumps('abc'), bytes_('abc'))
diff --git a/pyramid/util.py b/pyramid/util.py
index 77a0f306b..6655455bf 100644
--- a/pyramid/util.py
+++ b/pyramid/util.py
@@ -6,26 +6,25 @@ try:
except ImportError: # pragma: no cover
compare_digest = None
import inspect
-import traceback
import weakref
-from zope.interface import implementer
-
from pyramid.exceptions import (
ConfigurationError,
CyclicDependencyError,
)
from pyramid.compat import (
+ getargspec,
+ im_func,
is_nonstr_iter,
integer_types,
string_types,
+ bytes_,
text_,
PY2,
native_
)
-from pyramid.interfaces import IActionInfo
from pyramid.path import DottedNameResolver as _DottedNameResolver
_marker = object()
@@ -528,76 +527,6 @@ class TopologicalSorter(object):
return result
-def viewdefaults(wrapped):
- """ Decorator for add_view-like methods which takes into account
- __view_defaults__ attached to view it is passed. Not a documented API but
- used by some external systems."""
- def wrapper(self, *arg, **kw):
- defaults = {}
- if arg:
- view = arg[0]
- else:
- view = kw.get('view')
- view = self.maybe_dotted(view)
- if inspect.isclass(view):
- defaults = getattr(view, '__view_defaults__', {}).copy()
- if '_backframes' not in kw:
- kw['_backframes'] = 1 # for action_method
- defaults.update(kw)
- return wrapped(self, *arg, **defaults)
- return functools.wraps(wrapped)(wrapper)
-
-@implementer(IActionInfo)
-class ActionInfo(object):
- def __init__(self, file, line, function, src):
- self.file = file
- self.line = line
- self.function = function
- self.src = src
-
- def __str__(self):
- srclines = self.src.split('\n')
- src = '\n'.join(' %s' % x for x in srclines)
- return 'Line %s of file %s:\n%s' % (self.line, self.file, src)
-
-def action_method(wrapped):
- """ Wrapper to provide the right conflict info report data when a method
- that calls Configurator.action calls another that does the same. Not a
- documented API but used by some external systems."""
- def wrapper(self, *arg, **kw):
- if self._ainfo is None:
- self._ainfo = []
- info = kw.pop('_info', None)
- # backframes for outer decorators to actionmethods
- backframes = kw.pop('_backframes', 0) + 2
- if is_nonstr_iter(info) and len(info) == 4:
- # _info permitted as extract_stack tuple
- info = ActionInfo(*info)
- if info is None:
- try:
- f = traceback.extract_stack(limit=4)
-
- # Work around a Python 3.5 issue whereby it would insert an
- # extra stack frame. This should no longer be necessary in
- # Python 3.5.1
- last_frame = ActionInfo(*f[-1])
- if last_frame.function == 'extract_stack': # pragma: no cover
- f.pop()
- info = ActionInfo(*f[-backframes])
- except Exception: # pragma: no cover
- info = ActionInfo(None, 0, '', '')
- self._ainfo.append(info)
- try:
- result = wrapped(self, *arg, **kw)
- finally:
- self._ainfo.pop()
- return result
-
- if hasattr(wrapped, '__name__'):
- functools.update_wrapper(wrapper, wrapped)
- wrapper.__docobj__ = wrapped
- return wrapper
-
def get_callable_name(name):
"""
@@ -662,3 +591,61 @@ def make_contextmanager(fn):
def wrapper(*a, **kw):
yield fn(*a, **kw)
return wrapper
+
+
+def takes_one_arg(callee, attr=None, argname=None):
+ ismethod = False
+ if attr is None:
+ attr = '__call__'
+ if inspect.isroutine(callee):
+ fn = callee
+ elif inspect.isclass(callee):
+ try:
+ fn = callee.__init__
+ except AttributeError:
+ return False
+ ismethod = hasattr(fn, '__call__')
+ else:
+ try:
+ fn = getattr(callee, attr)
+ except AttributeError:
+ return False
+
+ try:
+ argspec = getargspec(fn)
+ except TypeError:
+ return False
+
+ args = argspec[0]
+
+ if hasattr(fn, im_func) or ismethod:
+ # it's an instance method (or unbound method on py2)
+ if not args:
+ return False
+ args = args[1:]
+
+ if not args:
+ return False
+
+ if len(args) == 1:
+ return True
+
+ if argname:
+
+ defaults = argspec[3]
+ if defaults is None:
+ defaults = ()
+
+ if args[0] == argname:
+ if len(args) - len(defaults) == 1:
+ return True
+
+ return False
+
+
+class SimpleSerializer(object):
+ def loads(self, bstruct):
+ return native_(bstruct)
+
+ def dumps(self, appstruct):
+ return bytes_(appstruct)
diff --git a/pyramid/viewderivers.py b/pyramid/viewderivers.py
index d2869b162..d914a4752 100644
--- a/pyramid/viewderivers.py
+++ b/pyramid/viewderivers.py
@@ -28,18 +28,14 @@ from pyramid.compat import (
is_unbound_method,
)
-from pyramid.config.util import (
- DEFAULT_PHASH,
- MAX_ORDER,
- takes_one_arg,
- )
-
from pyramid.exceptions import (
ConfigurationError,
- PredicateMismatch,
)
from pyramid.httpexceptions import HTTPForbidden
-from pyramid.util import object_description
+from pyramid.util import (
+ object_description,
+ takes_one_arg,
+)
from pyramid.view import render_view_to_response
from pyramid import renderers
@@ -353,49 +349,6 @@ def _authdebug_view(view, info):
return wrapped_view
-def predicated_view(view, info):
- preds = info.predicates
- if not preds:
- return view
- def predicate_wrapper(context, request):
- for predicate in preds:
- if not predicate(context, request):
- view_name = getattr(view, '__name__', view)
- raise PredicateMismatch(
- 'predicate mismatch for view %s (%s)' % (
- view_name, predicate.text()))
- return view(context, request)
- def checker(context, request):
- return all((predicate(context, request) for predicate in
- preds))
- predicate_wrapper.__predicated__ = checker
- predicate_wrapper.__predicates__ = preds
- return predicate_wrapper
-
-def attr_wrapped_view(view, info):
- accept, order, phash = (info.options.get('accept', None),
- getattr(info, 'order', MAX_ORDER),
- getattr(info, 'phash', DEFAULT_PHASH))
- # this is a little silly but we don't want to decorate the original
- # function with attributes that indicate accept, order, and phash,
- # so we use a wrapper
- if (
- (accept is None) and
- (order == MAX_ORDER) and
- (phash == DEFAULT_PHASH)
- ):
- return view # defaults
- def attr_view(context, request):
- return view(context, request)
- attr_view.__accept__ = accept
- attr_view.__order__ = order
- attr_view.__phash__ = phash
- attr_view.__view_attr__ = info.options.get('attr')
- attr_view.__permission__ = info.options.get('permission')
- return attr_view
-
-attr_wrapped_view.options = ('accept', 'attr', 'permission')
-
def rendered_view(view, info):
# one way or another this wrapper must produce a Response (unless
# the renderer is a NullRendererHelper)