Merge pull request #3125 from mmerickel/backport-3124-to-1.8-branch
fix circular import in pyramid.viewderivers
| | |
| | | unreleased |
| | | ========== |
| | | |
| | | - Fix a circular import which made it impossible to import |
| | | ``pyramid.viewderivers`` before ``pyramid.config``. |
| | | See https://github.com/Pylons/pyramid/pull/3125 |
| | | |
| | | .. _changes_1.8.4: |
| | | |
| | | 1.8.4 (2017-06-11) |
| | |
| | | from hashlib import md5 |
| | | import inspect |
| | | |
| | | from pyramid.compat import ( |
| | | bytes_, |
| | | getargspec, |
| | | is_nonstr_iter |
| | | ) |
| | | |
| | | from pyramid.compat import im_func |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.registry import predvalseq |
| | | |
| | |
| | | TopologicalSorter, |
| | | action_method, |
| | | ActionInfo, |
| | | takes_one_arg, |
| | | ) |
| | | |
| | | from pyramid.viewderivers import ( |
| | | MAX_ORDER, |
| | | DEFAULT_PHASH, |
| | | ) |
| | | |
| | | action_method = action_method # support bw compat imports |
| | | ActionInfo = ActionInfo # support bw compat imports |
| | | |
| | | MAX_ORDER = 1 << 30 |
| | | DEFAULT_PHASH = md5().hexdigest() |
| | | MAX_ORDER = MAX_ORDER # support bw compat imports |
| | | DEFAULT_PHASH = DEFAULT_PHASH # support bw compat imports |
| | | |
| | | takes_one_arg = takes_one_arg # support bw compat imports |
| | | |
| | | class not_(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 |
| | |
| | | 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 |
| | |
| | | self.assertTrue('foo' not in obj.__dict__) |
| | | |
| | | |
| | | 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)) |
| | | |
| | | |
| | | def dummyfunc(): pass |
| | | |
| | | |
| | |
| | | ) |
| | | |
| | | from pyramid.compat import ( |
| | | getargspec, |
| | | im_func, |
| | | is_nonstr_iter, |
| | | integer_types, |
| | | string_types, |
| | |
| | | return (pattern[0] == "." and |
| | | (host.endswith(pattern) or host == pattern[1:]) or |
| | | pattern == host) |
| | | |
| | | |
| | | 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 |
| | |
| | | from hashlib import md5 |
| | | import inspect |
| | | |
| | | from zope.interface 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 |
| | | |
| | | |
| | | MAX_ORDER = 1 << 30 |
| | | DEFAULT_PHASH = md5().hexdigest() |
| | | |
| | | def view_description(view): |
| | | try: |
| | | return view.__text__ |