From: Mike Bayer Date: Wed, 29 May 2019 21:32:57 +0000 (-0400) Subject: Use vendored getargspec() X-Git-Tag: rel_1_0_11~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41b100e6300e0680e9457149ac6f36ad7f78909e;p=thirdparty%2Fsqlalchemy%2Falembic.git Use vendored getargspec() Replaced the Python compatbility routines for ``getargspec()`` with a fully vendored version based on ``getfullargspec()`` from Python 3.3. Originally, Python was emitting deprecation warnings for this function in Python 3.8 alphas. While this change was reverted, it was observed that Python 3 implementations for ``getfullargspec()`` are an order of magnitude slower as of the 3.4 series where it was rewritten against ``Signature``. While Python plans to improve upon this situation, SQLAlchemy projects for now are using a simple replacement to avoid any future issues. Change-Id: If5f3e2f6cc0df8d89e6c3035e024df3319964bf9 Fixes: #563 --- diff --git a/alembic/util/compat.py b/alembic/util/compat.py index 994cbc9a..d57df9e3 100644 --- a/alembic/util/compat.py +++ b/alembic/util/compat.py @@ -1,3 +1,5 @@ +import collections +import inspect import io import sys @@ -11,6 +13,41 @@ py33 = sys.version_info >= (3, 3) py35 = sys.version_info >= (3, 5) py36 = sys.version_info >= (3, 6) + +ArgSpec = collections.namedtuple( + "ArgSpec", ["args", "varargs", "keywords", "defaults"] +) + + +def inspect_getargspec(func): + """getargspec based on fully vendored getfullargspec from Python 3.3.""" + + if inspect.ismethod(func): + func = func.__func__ + if not inspect.isfunction(func): + raise TypeError("{!r} is not a Python function".format(func)) + + co = func.__code__ + if not inspect.iscode(co): + raise TypeError("{!r} is not a code object".format(co)) + + nargs = co.co_argcount + names = co.co_varnames + nkwargs = co.co_kwonlyargcount if py3k else 0 + args = list(names[:nargs]) + + nargs += nkwargs + varargs = None + if co.co_flags & inspect.CO_VARARGS: + varargs = co.co_varnames[nargs] + nargs = nargs + 1 + varkw = None + if co.co_flags & inspect.CO_VARKEYWORDS: + varkw = co.co_varnames[nargs] + + return ArgSpec(args, varargs, varkw, func.__defaults__) + + if py3k: from io import StringIO else: @@ -55,22 +92,6 @@ if py33: else: import collections as collections_abc # noqa -if py3k: - import collections - - ArgSpec = collections.namedtuple( - "ArgSpec", ["args", "varargs", "keywords", "defaults"] - ) - - from inspect import getfullargspec as inspect_getfullargspec - - def inspect_getargspec(func): - return ArgSpec(*inspect_getfullargspec(func)[0:4]) - - -else: - from inspect import getargspec as inspect_getargspec # noqa - if py35: from inspect import formatannotation diff --git a/docs/build/unreleased/563.rst b/docs/build/unreleased/563.rst new file mode 100644 index 00000000..63d23dff --- /dev/null +++ b/docs/build/unreleased/563.rst @@ -0,0 +1,13 @@ +.. change:: + :tags: bug, py3k + :tickets: 563 + + Replaced the Python compatbility routines for ``getargspec()`` with a fully + vendored version based on ``getfullargspec()`` from Python 3.3. + Originally, Python was emitting deprecation warnings for this function in + Python 3.8 alphas. While this change was reverted, it was observed that + Python 3 implementations for ``getfullargspec()`` are an order of magnitude + slower as of the 3.4 series where it was rewritten against ``Signature``. + While Python plans to improve upon this situation, SQLAlchemy projects for + now are using a simple replacement to avoid any future issues. +