Skip to content

create_module_proxy can be fooled when it wraps methods that have explciit arguments #548

@zzzeek

Description

@zzzeek

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,
    ):

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions