]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
render 3rd party module annotations as forward references
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 15 Sep 2021 20:43:45 +0000 (16:43 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 15 Sep 2021 20:43:45 +0000 (16:43 -0400)
Fixed issue where registration of custom ops was prone to failure due to
the registration process running ``exec()`` on generated code that as of
the 1.7 series includes pep-484 annotations, which in the case of end user
code would result in name resolution errors when the exec occurs. The logic
in question has been altered so that the annotations are rendered as
forward references so that the ``exec()`` can proceed.

Change-Id: I142b89e2f6354b2ce253f3b8109f59fa3aae68ef
Fixes: #920
alembic/operations/base.py
alembic/util/compat.py
docs/build/unreleased/920.rst [new file with mode: 0644]

index 59bbfc4831efbe0485098f7abd97a7c58c90850a..07ddd5afd1cd675338aff5948d8eee31958ee019 100644 (file)
@@ -17,9 +17,11 @@ from . import batch
 from . import schemaobj
 from .. import util
 from ..util import sqla_compat
+from ..util.compat import formatannotation_fwdref
 from ..util.compat import inspect_formatargspec
 from ..util.compat import inspect_getfullargspec
 
+
 NoneType = type(None)
 
 if TYPE_CHECKING:
@@ -121,7 +123,9 @@ class Operations(util.ModuleClsProxy):
 
             name_args[0:2] = ["self"]
 
-            args = inspect_formatargspec(*spec)
+            args = inspect_formatargspec(
+                *spec, formatannotation=formatannotation_fwdref
+            )
             num_defaults = len(spec[3]) if spec[3] else 0
             if num_defaults:
                 defaulted_vals = name_args[0 - num_defaults :]
@@ -134,6 +138,7 @@ class Operations(util.ModuleClsProxy):
                 spec[2],
                 defaulted_vals,
                 formatvalue=lambda x: "=" + x,
+                formatannotation=formatannotation_fwdref,
             )
 
             args = re.sub(
index 1e435a829c568ceef55b0a7b309ac200b0eadf9d..91b5cf9fe3714148cba296842becf71d1179f279 100644 (file)
@@ -41,3 +41,16 @@ def importlib_metadata_get(group):
         return ep.select(group=group)
     else:
         return ep.get(group, ())
+
+
+def formatannotation_fwdref(annotation, base_module=None):
+    """the python 3.7 _formatannotation with an extra repr() for 3rd party
+    modules"""
+
+    if getattr(annotation, "__module__", None) == "typing":
+        return repr(annotation).replace("typing.", "")
+    if isinstance(annotation, type):
+        if annotation.__module__ in ("builtins", base_module):
+            return annotation.__qualname__
+        return repr(annotation.__module__ + "." + annotation.__qualname__)
+    return repr(annotation)
diff --git a/docs/build/unreleased/920.rst b/docs/build/unreleased/920.rst
new file mode 100644 (file)
index 0000000..017ce89
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, regression, ops
+    :tickets: 920
+
+    Fixed issue where registration of custom ops was prone to failure due to
+    the registration process running ``exec()`` on generated code that as of
+    the 1.7 series includes pep-484 annotations, which in the case of end user
+    code would result in name resolution errors when the exec occurs. The logic
+    in question has been altered so that the annotations are rendered as
+    forward references so that the ``exec()`` can proceed.