zzzeek · GitHub

There's an import artifact of some kind that is changing the behavior of @contextlib.contextmanager in one environment, such that inspect.getargspec(fn) of the function is returning it's full set of keyword defaults, rather than a generic *arg, **kw. We can simulate this by removing it from the method in question:

diff --git a/alembic/operations/base.py b/alembic/operations/base.py
index 90b3500..a5b0706 100644
--- a/alembic/operations/base.py
+++ b/alembic/operations/base.py
@@ -171,7 +171,7 @@ class Operations(util.ModuleClsProxy):
         yield op
         op._remove_proxy()
-    @contextmanager
+    #@contextmanager
     def batch_alter_table(
         self,
         table_name,

then we get a simple import error:

$ PYTHONPATH=~/dev/sqlalchemy/lib/ python -m alembic
Traceback (most recent call last):
  File "/opt/python-3.7.0/lib/python3.7/runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/opt/python-3.7.0/lib/python3.7/runpy.py", line 142, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "/opt/python-3.7.0/lib/python3.7/runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "/home/classic/dev/alembic/alembic/__init__.py", line 5, in <module>
    from . import op  # noqa
  File "/home/classic/dev/alembic/alembic/op.py", line 5, in <module>
    Operations.create_module_class_proxy(globals(), locals())
  File "/home/classic/dev/alembic/alembic/util/langhelpers.py", line 56, in create_module_class_proxy
    cls._setup_proxy(globals_, locals_, attr_names)
  File "/home/classic/dev/alembic/alembic/util/langhelpers.py", line 61, in _setup_proxy
    cls._add_proxied_attribute(methname, globals_, locals_, attr_names)
  File "/home/classic/dev/alembic/alembic/util/langhelpers.py", line 69, in _add_proxied_attribute
    methname, globals_, locals_
  File "/home/classic/dev/alembic/alembic/util/langhelpers.py", line 176, in _create_method_proxy
    exec_(func_text, globals_, lcl)
  File "<string>", line 1, in <module>
NameError: name 'immutabledict' is not defined

because it doesn't have the "util" prefix that the actual code does:

    def batch_alter_table(
        self,
        table_name,
        schema=None,
        recreate="auto",
        copy_from=None,
        table_args=(),
        table_kwargs=util.immutabledict(),
        reflect_args=(),
        reflect_kwargs=util.immutabledict(),
        naming_convention=None,
    ):

Read the original on github.com ↗