summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt3
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--docs/narr/commandline.rst2
-rw-r--r--pyramid/compat.py5
-rw-r--r--pyramid/config/util.py3
-rw-r--r--pyramid/decorator.py8
-rw-r--r--pyramid/security.py14
-rw-r--r--pyramid/tests/test_config/test_util.py7
-rw-r--r--pyramid/tests/test_decorator.py18
-rw-r--r--setup.py2
-rw-r--r--tox.ini8
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
diff --git a/setup.py b/setup.py
index 629b77f3d..3233193e7 100644
--- a/setup.py
+++ b/setup.py
@@ -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=[
diff --git a/tox.ini b/tox.ini
index 714c5b6d3..29bd48639 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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