From 522df0133d06dd8de36a11e2bcffc62e03f271fe Mon Sep 17 00:00:00 2001 From: alex argunov Date: Sun, 14 Feb 2016 03:57:55 +0300 Subject: [PATCH 1/2] CLN: change getargspec -> signature Change signature in compat to be able to return defaults, varargs, kwargs Closes #12171 --- pandas/compat/__init__.py | 27 +++++++++++++++++++++++++-- pandas/tests/series/test_analytics.py | 3 +-- pandas/tests/test_panel.py | 2 +- pandas/util/decorators.py | 5 ++--- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index d991b3f1fb866..e70eb93979e6e 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -71,7 +71,30 @@ def bytes_to_str(b, encoding=None): return b.decode(encoding or 'utf-8') def signature(f): - return list(inspect.signature(f).parameters.keys()) + from collections import namedtuple + sig = inspect.signature(f) + args = [ + p.name for p in sig.parameters.values() + if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD + ] + varargs = [ + p.name for p in sig.parameters.values() + if p.kind == inspect.Parameter.VAR_POSITIONAL + ] + varargs = varargs[0] if varargs else None + keywords = [ + p.name for p in sig.parameters.values() + if p.kind == inspect.Parameter.VAR_KEYWORD + ] + keywords = keywords[0] if keywords else None + defaults = [ + p.default for p in sig.parameters.values() + if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD + and p.default is not p.empty + ] or None + argspec = namedtuple('Signature',['args','defaults', + 'varargs','keywords']) + return argspec(args,defaults,varargs,keywords) # have to explicitly put builtins into the namespace range = range @@ -110,7 +133,7 @@ def bytes_to_str(b, encoding='ascii'): return b def signature(f): - return inspect.getargspec(f).args + return inspect.getargspec(f) # import iterator versions of these functions range = xrange diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index a9dfe07c20856..455e5cda03307 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -1,7 +1,6 @@ # coding=utf-8 # pylint: disable-msg=E1101,W0612 -from inspect import getargspec from itertools import product from distutils.version import LooseVersion @@ -465,7 +464,7 @@ def testit(): self.assertRaises(ValueError, f, self.series, axis=1) # Unimplemented numeric_only parameter. - if 'numeric_only' in getargspec(f).args: + if 'numeric_only' in compat.signature(f).args: self.assertRaisesRegexp(NotImplementedError, name, f, self.series, numeric_only=True) diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py index 9b9f952bb5aea..dd7468723c9c7 100644 --- a/pandas/tests/test_panel.py +++ b/pandas/tests/test_panel.py @@ -201,7 +201,7 @@ def wrapper(x): self.assertRaises(Exception, f, axis=obj.ndim) # Unimplemented numeric_only parameter. - if 'numeric_only' in signature(f): + if 'numeric_only' in signature(f).args: self.assertRaisesRegexp(NotImplementedError, name, f, numeric_only=True) diff --git a/pandas/util/decorators.py b/pandas/util/decorators.py index c2d25b30c2b22..0a59c2e8eb1c3 100644 --- a/pandas/util/decorators.py +++ b/pandas/util/decorators.py @@ -1,4 +1,4 @@ -from pandas.compat import StringIO, callable +from pandas.compat import StringIO, callable, signature from pandas.lib import cache_readonly # noqa import sys import warnings @@ -275,8 +275,7 @@ def make_signature(func): >>> print(_make_signature(f)) a,b,c=2 """ - from inspect import getargspec - spec = getargspec(func) + spec = signature(func) if spec.defaults is None: n_wo_defaults = len(spec.args) defaults = ('',) * n_wo_defaults From e9153d935940ba10a3463417af99baed89eff82a Mon Sep 17 00:00:00 2001 From: alex argunov Date: Wed, 17 Feb 2016 02:45:45 +0300 Subject: [PATCH 2/2] Add reference to Django; import to the top --- pandas/compat/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index e70eb93979e6e..cbdb69d1df8c3 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -36,6 +36,7 @@ from unicodedata import east_asian_width import struct import inspect +from collections import namedtuple PY2 = sys.version_info[0] == 2 PY3 = (sys.version_info[0] >= 3) @@ -70,8 +71,9 @@ def str_to_bytes(s, encoding=None): def bytes_to_str(b, encoding=None): return b.decode(encoding or 'utf-8') + # The signature version below is directly copied from Django, + # https://github.com/django/django/pull/4846 def signature(f): - from collections import namedtuple sig = inspect.signature(f) args = [ p.name for p in sig.parameters.values()