summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2021-09-17 13:23:00 +0000
committerGerrit Code Review <gerrit@ci3.zzzcomputing.com>2021-09-17 13:23:00 +0000
commita2a9e197ca41bc9f5f61ff22646485871348e8da (patch)
tree375108ee539da883f067ff147efd5bbd17f71d89
parent921249d610d3a6e4c9028f459fa981492c50e724 (diff)
parentb08447862388ae4064c36dcc1f0c91d84fa3c06f (diff)
downloadalembic-a2a9e197ca41bc9f5f61ff22646485871348e8da.tar.gz
Merge "render 3rd party module annotations as forward references"
-rw-r--r--alembic/operations/base.py7
-rw-r--r--alembic/util/compat.py13
-rw-r--r--docs/build/unreleased/920.rst10
3 files changed, 29 insertions, 1 deletions
diff --git a/alembic/operations/base.py b/alembic/operations/base.py
index 59bbfc4..07ddd5a 100644
--- a/alembic/operations/base.py
+++ b/alembic/operations/base.py
@@ -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(
diff --git a/alembic/util/compat.py b/alembic/util/compat.py
index 1e435a8..91b5cf9 100644
--- a/alembic/util/compat.py
+++ b/alembic/util/compat.py
@@ -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
index 0000000..017ce89
--- /dev/null
+++ b/docs/build/unreleased/920.rst
@@ -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.