internally make varnames() deal with classes's __init__,
although it's not needed by pytest itself atm. Also fix caching. Fixes issue376.
This commit is contained in:
parent
dde0a81677
commit
9b21d3f206
|
@ -48,6 +48,10 @@ Unreleased
|
|||
- xfail a test on pypy that checks wrong encoding/ascii (pypy does
|
||||
not error out). fixes issue385.
|
||||
|
||||
- internally make varnames() deal with classes's __init__,
|
||||
although it's not needed by pytest itself atm. Also
|
||||
fix caching. Fixes issue376.
|
||||
|
||||
Changes between 2.4.1 and 2.4.2
|
||||
-----------------------------------
|
||||
|
||||
|
|
|
@ -304,19 +304,36 @@ class MultiCall:
|
|||
return kwargs
|
||||
|
||||
def varnames(func):
|
||||
""" return argument name tuple for a function, method, class or callable.
|
||||
|
||||
In case of a class, its "__init__" method is considered.
|
||||
For methods the "self" parameter is not included unless you are passing
|
||||
an unbound method with Python3 (which has no supports for unbound methods)
|
||||
"""
|
||||
cache = getattr(func, "__dict__", {})
|
||||
try:
|
||||
return func._varnames
|
||||
except AttributeError:
|
||||
return cache["_varnames"]
|
||||
except KeyError:
|
||||
pass
|
||||
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
||||
func = getattr(func, '__call__', func)
|
||||
ismethod = inspect.ismethod(func)
|
||||
if inspect.isclass(func):
|
||||
try:
|
||||
func = func.__init__
|
||||
except AttributeError:
|
||||
return ()
|
||||
ismethod = True
|
||||
else:
|
||||
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
||||
func = getattr(func, '__call__', func)
|
||||
ismethod = inspect.ismethod(func)
|
||||
rawcode = py.code.getrawcode(func)
|
||||
try:
|
||||
x = rawcode.co_varnames[ismethod:rawcode.co_argcount]
|
||||
except AttributeError:
|
||||
x = ()
|
||||
py.builtin._getfuncdict(func)['_varnames'] = x
|
||||
try:
|
||||
cache["_varnames"] = x
|
||||
except TypeError:
|
||||
pass
|
||||
return x
|
||||
|
||||
class HookRelay:
|
||||
|
|
|
@ -438,6 +438,15 @@ def test_varnames():
|
|||
assert varnames(A().f) == ('y',)
|
||||
assert varnames(B()) == ('z',)
|
||||
|
||||
def test_varnames_class():
|
||||
class C:
|
||||
def __init__(self, x):
|
||||
pass
|
||||
class D:
|
||||
pass
|
||||
assert varnames(C) == ("x",)
|
||||
assert varnames(D) == ()
|
||||
|
||||
class TestMultiCall:
|
||||
def test_uses_copy_of_methods(self):
|
||||
l = [lambda: 42]
|
||||
|
@ -654,8 +663,7 @@ def test_default_markers(testdir):
|
|||
|
||||
def test_importplugin_issue375(testdir):
|
||||
testdir.makepyfile(qwe="import aaaa")
|
||||
with pytest.raises(ImportError) as excinfo:
|
||||
importplugin("qwe")
|
||||
excinfo = pytest.raises(ImportError, lambda: importplugin("qwe"))
|
||||
assert "qwe" not in str(excinfo.value)
|
||||
assert "aaaa" in str(excinfo.value)
|
||||
|
||||
|
|
Loading…
Reference in New Issue