]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Vendor python3 formatargspec
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 28 Jun 2018 15:49:02 +0000 (11:49 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 28 Jun 2018 15:49:02 +0000 (11:49 -0400)
Replaced the usage of inspect.formatargspec() with a vendored version
copied from the Python standard library, as inspect.formatargspec()
is deprecated and as of Python 3.7.0 is emitting a warning.

Change-Id: I751652fac7f605a3a10b547ba8c5f34fef1de945
Fixes: #4291
doc/build/changelog/unreleased_12/4291.rst [new file with mode: 0644]
lib/sqlalchemy/util/compat.py
lib/sqlalchemy/util/langhelpers.py

diff --git a/doc/build/changelog/unreleased_12/4291.rst b/doc/build/changelog/unreleased_12/4291.rst
new file mode 100644 (file)
index 0000000..0fd5e7c
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, py3k
+    :tickets: 4291
+
+    Replaced the usage of inspect.formatargspec() with a vendored version
+    copied from the Python standard library, as inspect.formatargspec()
+    is deprecated and as of Python 3.7.0 is emitting a warning.
index 2d952c63f766c45f74e5579a328a8880b76a0d07..bc0c3e6e0639861a2788e97592dc8e32774ba4e2 100644 (file)
@@ -17,6 +17,7 @@ except ImportError:
 
 py36 = sys.version_info >= (3, 6)
 py33 = sys.version_info >= (3, 3)
+py35 = sys.version_info >= (3, 5)
 py32 = sys.version_info >= (3, 2)
 py3k = sys.version_info >= (3, 0)
 py2k = sys.version_info < (3, 0)
@@ -166,6 +167,67 @@ else:
     itertools_imap = itertools.imap
     from itertools import izip_longest as zip_longest
 
+if py35:
+    from inspect import formatannotation
+
+    def inspect_formatargspec(
+            args, varargs=None, varkw=None, defaults=None,
+            kwonlyargs=(), kwonlydefaults={}, annotations={},
+            formatarg=str,
+            formatvarargs=lambda name: '*' + name,
+            formatvarkw=lambda name: '**' + name,
+            formatvalue=lambda value: '=' + repr(value),
+            formatreturns=lambda text: ' -> ' + text,
+            formatannotation=formatannotation):
+        """Copy formatargspec from python 3.7 standard library.
+
+        Python 3 has deprecated formatargspec and requested that Signature
+        be used instead, however this requires a full reimplementation
+        of formatargspec() in terms of creating Parameter objects and such.
+        Instead of introducing all the object-creation overhead and having
+        to reinvent from scratch, just copy their compatibility routine.
+
+        Utimately we would need to rewrite our "decorator" routine completely
+        which is not really worth it right now, until all Python 2.x support
+        is dropped.
+
+        """
+
+        def formatargandannotation(arg):
+            result = formatarg(arg)
+            if arg in annotations:
+                result += ': ' + formatannotation(annotations[arg])
+            return result
+        specs = []
+        if defaults:
+            firstdefault = len(args) - len(defaults)
+        for i, arg in enumerate(args):
+            spec = formatargandannotation(arg)
+            if defaults and i >= firstdefault:
+                spec = spec + formatvalue(defaults[i - firstdefault])
+            specs.append(spec)
+        if varargs is not None:
+            specs.append(formatvarargs(formatargandannotation(varargs)))
+        else:
+            if kwonlyargs:
+                specs.append('*')
+        if kwonlyargs:
+            for kwonlyarg in kwonlyargs:
+                spec = formatargandannotation(kwonlyarg)
+                if kwonlydefaults and kwonlyarg in kwonlydefaults:
+                    spec += formatvalue(kwonlydefaults[kwonlyarg])
+                specs.append(spec)
+        if varkw is not None:
+            specs.append(formatvarkw(formatargandannotation(varkw)))
+        result = '(' + ', '.join(specs) + ')'
+        if 'return' in annotations:
+            result += formatreturns(formatannotation(annotations['return']))
+        return result
+
+else:
+    from inspect import formatargspec as inspect_formatargspec
+
+
 
 import time
 if win32 or jython:
@@ -232,8 +294,6 @@ def with_metaclass(meta, *bases):
     return metaclass('temporary_class', None, {})
 
 
-
-
 @contextmanager
 def nested(*managers):
     """Implement contextlib.nested, mostly for unit tests.
index 213f3a0ad7f3f8ee02d05afcaa1bd8d69b1a8035..81bfee30acb3893de0af3c62f2d600a16ec88227 100644 (file)
@@ -9,8 +9,8 @@
 modules, classes, hierarchies, attributes, functions, and methods.
 
 """
-import itertools
 import inspect
+import itertools
 import operator
 import re
 import sys
@@ -280,7 +280,7 @@ try:
 
 except ImportError:
     def inspect_func_args(fn):
-        names, _, has_kw, _ = inspect.getargspec(fn)
+        names, _, has_kw, _ = compat.inspect_getargspec(fn)
         return names, bool(has_kw)
 
 
@@ -371,7 +371,7 @@ def format_argspec_plus(fn, grouped=True):
     else:
         # we accept an existing argspec...
         spec = fn
-    args = inspect.formatargspec(*spec)
+    args = compat.inspect_formatargspec(*spec)
     if spec[0]:
         self_arg = spec[0][0]
     elif spec[1]:
@@ -380,8 +380,8 @@ def format_argspec_plus(fn, grouped=True):
         self_arg = None
 
     if compat.py3k:
-        apply_pos = inspect.formatargspec(spec[0], spec[1],
-                                          spec[2], None, spec[4])
+        apply_pos = compat.inspect_formatargspec(
+            spec[0], spec[1], spec[2], None, spec[4])
         num_defaults = 0
         if spec[3]:
             num_defaults += len(spec[3])
@@ -389,7 +389,7 @@ def format_argspec_plus(fn, grouped=True):
             num_defaults += len(spec[4])
         name_args = spec[0] + spec[4]
     else:
-        apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2])
+        apply_pos = compat.inspect_formatargspec(spec[0], spec[1], spec[2])
         num_defaults = 0
         if spec[3]:
             num_defaults += len(spec[3])
@@ -400,9 +400,9 @@ def format_argspec_plus(fn, grouped=True):
     else:
         defaulted_vals = ()
 
-    apply_kw = inspect.formatargspec(name_args, spec[1], spec[2],
-                                     defaulted_vals,
-                                     formatvalue=lambda x: '=' + x)
+    apply_kw = compat.inspect_formatargspec(
+        name_args, spec[1], spec[2], defaulted_vals,
+        formatvalue=lambda x: '=' + x)
     if grouped:
         return dict(args=args, self_arg=self_arg,
                     apply_pos=apply_pos, apply_kw=apply_kw)
@@ -646,8 +646,8 @@ def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None,
             continue
         try:
             spec = compat.inspect_getargspec(fn)
-            fn_args = inspect.formatargspec(spec[0])
-            d_args = inspect.formatargspec(spec[0][1:])
+            fn_args = compat.inspect_formatargspec(spec[0])
+            d_args = compat.inspect_formatargspec(spec[0][1:])
         except TypeError:
             fn_args = '(self, *args, **kw)'
             d_args = '(*args, **kw)'