diff --git a/_pytest/python.py b/_pytest/python.py index 414ec545e..618aef058 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -32,6 +32,26 @@ exc_clear = getattr(sys, 'exc_clear', lambda: None) # The type of re.compile objects is not exposed in Python. REGEX_TYPE = type(re.compile('')) + +if hasattr(inspect, 'signature'): + def _has_positional_arg(func): + sig = inspect.signature(func) + params = list(sig.parameters.values()) + if len(params): + return params[0].kind in (sig.POSITIONAL_ONLY, sig.POSITIONAL_OR_KEYWORD) + else: + return False + + def _format_args(func): + return str(inspect.signature(func)) +else: + def _has_positional_arg(func): + return inspect.getargspec(func)[0] is not None + + def _format_args(func): + return inspect.formatargspec(*inspect.getargspec(func)) + + def filter_traceback(entry): return entry.path != cutdir1 and not entry.path.relto(cutdir2) @@ -586,7 +606,7 @@ class Module(pytest.File, PyCollector): #XXX: nose compat hack, move to nose plugin # if it takes a positional arg, its probably a pytest style one # so we pass the current module object - if inspect.getargspec(setup_module)[0]: + if _has_positional_arg(setup_module): setup_module(self.obj) else: setup_module() @@ -597,7 +617,7 @@ class Module(pytest.File, PyCollector): #XXX: nose compat hack, move to nose plugin # if it takes a positional arg, it's probably a pytest style one # so we pass the current module object - if inspect.getargspec(fin)[0]: + if _has_positional_arg(fin): finalizer = lambda: fin(self.obj) else: finalizer = fin @@ -1580,7 +1600,7 @@ class FixtureRequest(FuncargnamesCompatAttr): factory = fixturedef.func fs, lineno = getfslineno(factory) p = self._pyfuncitem.session.fspath.bestrelpath(fs) - args = inspect.formatargspec(*inspect.getargspec(factory)) + args = _format_args(factory) lines.append("%s:%d: def %s%s" %( p, lineno, factory.__name__, args)) return lines diff --git a/testing/test_runner.py b/testing/test_runner.py index 3641ab8ca..b01727dbb 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -349,7 +349,10 @@ reporttypes = [ @pytest.mark.parametrize('reporttype', reporttypes, ids=[x.__name__ for x in reporttypes]) def test_report_extra_parameters(reporttype): - args = py.std.inspect.getargspec(reporttype.__init__)[0][1:] + if hasattr(py.std.inspect, 'signature'): + args = list(py.std.inspect.signature(reporttype.__init__).parameters.keys())[1:] + else: + args = py.std.inspect.getargspec(reporttype.__init__)[0][1:] basekw = dict.fromkeys(args, []) report = reporttype(newthing=1, **basekw) assert report.newthing == 1