pyramid icon indicating copy to clipboard operation
pyramid copied to clipboard

partials as view callables behave differently under python 2.7 and python 3.4

Open xrotwang opened this issue 9 years ago • 4 comments

Compare

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
>>> from pyramid.config.util import takes_one_arg
>>> from functools import partial
>>> def v(a, b, c):
...   return
... 
>>> takes_one_arg(partial(v, 1))
False
>>> takes_one_arg(partial(v, 1, 2))
False
>>> takes_one_arg(partial(v, 1, 2, 3))
False

with

Python 3.4.1 (default, Jul  7 2014, 09:21:41) 
[GCC 4.6.3] on linux
>>> from pyramid.config.util import takes_one_arg
>>> from functools import partial
>>> def v(a, b, c):
...   return
... 
>>> takes_one_arg(partial(v, 1))
True
>>> takes_one_arg(partial(v, 1, 2))
True
>>> takes_one_arg(partial(v, 1, 2, 3))
True

I was using a partial accepting two positional arguments as callable and my tests failed on python 3.4. So I think either partials should be disallowed as view callables, or takes_one_arg should be fixed to exhibit the same behaviour under both python 2.7 and python 3.4.

xrotwang avatar Oct 14 '14 10:10 xrotwang

FWIW, the difference lies in the Python stdlib. Under Python 3.3.:

-> argspec = inspect.getargspec(fn)
(Pdb) 
TypeError: <method-wrapper '__call__' of functools.partial object at ...> is not a Python function

while under Python 3.4:

-> argspec = inspect.getargspec(fn)
(Pdb) 
-> args = argspec[0]
(Pdb) pp argspec
ArgSpec(args=['self'], varargs='args', keywords='kwargs', defaults=None)

tseaver avatar Oct 14 '14 12:10 tseaver

hmmm, this one is a little bit tricky, partial from python2.7 is implemented as a C module, but since 3 it's in pure python code. Not sure if I can manage to fix this, I think the best solution I can think of is to try to see if it's a partial, and if it is.

https://github.com/python/cpython/blob/3.6/Lib/functools.py#L246

try to get func, args, calculate how many arguments left after partial's decoration.

fangpenlin avatar May 22 '17 22:05 fangpenlin

after looking into it a while, I felt the situation is a little bit overwhelming complex, given there is anattr argument, not sure how that should be applied on functools.partial object. will leave it here and trying to pick up other stuff first.

fangpenlin avatar May 22 '17 22:05 fangpenlin

I am addressing this on https://github.com/Pylons/pyramid/pull/3378

jsbueno avatar Oct 06 '18 20:10 jsbueno