diff options
| -rw-r--r-- | CHANGES.txt | 3 | ||||
| -rw-r--r-- | CONTRIBUTORS.txt | 2 | ||||
| -rw-r--r-- | docs/narr/commandline.rst | 2 | ||||
| -rw-r--r-- | pyramid/compat.py | 5 | ||||
| -rw-r--r-- | pyramid/config/util.py | 3 | ||||
| -rw-r--r-- | pyramid/decorator.py | 8 | ||||
| -rw-r--r-- | pyramid/security.py | 14 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_util.py | 7 | ||||
| -rw-r--r-- | pyramid/tests/test_decorator.py | 18 | ||||
| -rw-r--r-- | setup.py | 2 | ||||
| -rw-r--r-- | tox.ini | 8 |
11 files changed, 48 insertions, 24 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index b1bd36904..22c7a20c2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -77,6 +77,9 @@ Features output by showing the module instead of just ``__repr__``. See https://github.com/Pylons/pyramid/pull/1488 +- Support keyword-only arguments and function annotations in views in + Python 3. See https://github.com/Pylons/pyramid/pull/1556 + Bug Fixes --------- diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e4132cda5..adf2224a5 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -238,3 +238,5 @@ Contributors - Hugo Branquinho, 2014/11/25 - Adrian Teng, 2014/12/17 + +- Ilja Everila, 2015/02/05 diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 3dcb092e2..1fe2d9278 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -325,7 +325,7 @@ For example: multiview /multiview app1.standard_views.multiview GET,PATCH not_post /not_post app1.standard_views.multview !POST,* -``proutes`` generates a table with three columns: *Name*, *Pattern*, *Method*, +``proutes`` generates a table with four columns: *Name*, *Pattern*, *Method*, and *View*. The items listed in the Name column are route names, the items listed in the Pattern column are route patterns, and the items listed in the View column are representations of the diff --git a/pyramid/compat.py b/pyramid/compat.py index bfa345b88..5909debf2 100644 --- a/pyramid/compat.py +++ b/pyramid/compat.py @@ -244,3 +244,8 @@ else: def is_bound_method(ob): return inspect.ismethod(ob) and getattr(ob, im_self, None) is not None +# support annotations and keyword-only arguments in PY3 +if PY3: + from inspect import getfullargspec as getargspec +else: + from inspect import getargspec diff --git a/pyramid/config/util.py b/pyramid/config/util.py index 892592196..23cdc6be8 100644 --- a/pyramid/config/util.py +++ b/pyramid/config/util.py @@ -3,6 +3,7 @@ import inspect from pyramid.compat import ( bytes_, + getargspec, is_nonstr_iter, ) @@ -201,7 +202,7 @@ def takes_one_arg(callee, attr=None, argname=None): return False try: - argspec = inspect.getargspec(fn) + argspec = getargspec(fn) except TypeError: return False diff --git a/pyramid/decorator.py b/pyramid/decorator.py index 0d17bc398..df30c5e10 100644 --- a/pyramid/decorator.py +++ b/pyramid/decorator.py @@ -1,3 +1,6 @@ +import functools + + class reify(object): """ Use as a class method decorator. It operates almost exactly like the Python ``@property`` decorator, but it puts the result of the method it @@ -26,10 +29,7 @@ class reify(object): """ def __init__(self, wrapped): self.wrapped = wrapped - try: - self.__doc__ = wrapped.__doc__ - except: # pragma: no cover - pass + functools.update_wrapper(self, wrapped) def __get__(self, inst, objtype=None): if inst is None: diff --git a/pyramid/security.py b/pyramid/security.py index cbb4b895f..f993ef353 100644 --- a/pyramid/security.py +++ b/pyramid/security.py @@ -126,7 +126,7 @@ def remember(request, userid=_marker, **kw): current :term:`authentication policy`. Common usage might look like so within the body of a view function (``response`` is assumed to be a :term:`WebOb` -style :term:`response` object - computed previously by the view code):: + computed previously by the view code): .. code-block:: python @@ -170,12 +170,14 @@ def forget(request): possessed by the currently authenticated user. A common usage might look like so within the body of a view function (``response`` is assumed to be an :term:`WebOb` -style - :term:`response` object computed previously by the view code):: + :term:`response` object computed previously by the view code): - from pyramid.security import forget - headers = forget(request) - response.headerlist.extend(headers) - return response + .. code-block:: python + + from pyramid.security import forget + headers = forget(request) + response.headerlist.extend(headers) + return response If no :term:`authentication policy` is in use, this function will always return an empty sequence. diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py index bb61714ae..ccf7fa260 100644 --- a/pyramid/tests/test_config/test_util.py +++ b/pyramid/tests/test_config/test_util.py @@ -568,6 +568,13 @@ class Test_takes_one_arg(unittest.TestCase): 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 diff --git a/pyramid/tests/test_decorator.py b/pyramid/tests/test_decorator.py index 9ab1b7229..0a98a512d 100644 --- a/pyramid/tests/test_decorator.py +++ b/pyramid/tests/test_decorator.py @@ -15,15 +15,19 @@ class TestReify(unittest.TestCase): self.assertEqual(inst.__dict__['wrapped'], 'a') def test___get__noinst(self): - decorator = self._makeOne(None) + def wrapped(inst): + return 'a' # pragma: no cover + decorator = self._makeOne(wrapped) result = decorator.__get__(None) self.assertEqual(result, decorator) - def test___doc__copied(self): - def wrapped(inst): - """My doc""" - decorator = self._makeOne(wrapped) - self.assertEqual(decorator.__doc__, "My doc") - + 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 @@ -68,7 +68,7 @@ testing_extras = tests_require + [ ] setup(name='pyramid', - version='1.6dev', + version='1.6.dev0', description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ @@ -4,15 +4,15 @@ envlist = [testenv] commands = - python setup.py dev - python setup.py test -q + python setup.py -q dev + python setup.py -q test -q [testenv:cover] basepython = python2.6 commands = - python setup.py dev - python setup.py nosetests --with-xunit --with-xcoverage + python setup.py -q dev + nosetests --with-xunit --with-xcoverage deps = nosexcover |
