summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/util/compat.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/util/compat.py')
-rw-r--r--lib/sqlalchemy/util/compat.py64
1 files changed, 62 insertions, 2 deletions
diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py
index 2d952c63f..bc0c3e6e0 100644
--- a/lib/sqlalchemy/util/compat.py
+++ b/lib/sqlalchemy/util/compat.py
@@ -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.