PyPI / alembic / 1.20.0

alembic 1.20.0

Source
https://github.com/sqlalchemy/alembic
Tag scanned
rel_1_20_0
Compared with
rel_1_19_2 (0 signals introduced since)
Files
149 scanned, 30 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 8 info
Scan time
8.8 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 8 of 8 warn and critical signals; 8 demoted to info.
Disclude version
4.1.0
Scanned (UTC)
2026-10-22 04:21

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review dynamic-attribute alembic/autogenerate/render.py:939:18

    reach-by-name through `globals` (ast pass, confidence 0.60)

            if "_render_%s_type" % type_.__visit_name__ in globals():
                fn = globals()["_render_%s_type" % type_.__visit_name__]
                return fn(type_, autogen_context)
            else:
    likely benign LLM, confidence 0.90 Looks up a _render_<type>_type function by name in module globals to dispatch type rendering.
    Reasoning

    The name is built from a fixed format string using the type's visit name, and the lookup is limited to module globals. This is a routine dispatch pattern for rendering type reprs, with no sign of hidden payload or attacker-controlled input.

  2. info warn → info by review dynamic-execution alembic/operations/base.py:185:13

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

    
                exec(func_text, globals_, lcl)
                setattr(cls, name, lcl[name])
                fn.__func__.__doc__ = (
    likely benign LLM, confidence 0.90 Executes generated source text to create Alembic operation wrapper functions with matching signatures.
    Reasoning

    The exec runs generated function text that Alembic builds from its own operation signatures and docstrings to create wrapper methods on operation classes. This is a known metaprogramming technique in the library, not attacker input.

  3. info warn → info by review dynamic-execution alembic/util/langhelpers.py:214:9

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

    
            exec(func_text, cast("Dict[str, Any]", globals_), lcl)
            return cast("Callable[..., Any]", lcl[name])
    likely benign LLM, confidence 0.90 Execs generated function source to build a callable with a given name for internal use.
    Reasoning

    This is the same internal helper that builds a function from generated source text and returns a named callable. The input is library-generated code with no external source, consistent with a legitimate decorator-generation utility.

  4. info critical → info by review dynamic-execution tests/conftest.py:34:12

    `compile` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

    with open(bootstrap_file) as f:
        code = compile(f.read(), "bootstrap.py", "exec")
        to_bootstrap = "pytest"
        exec(code, globals(), locals())
    likely benign LLM, confidence 0.70 Compiles and execs a bootstrap.py from the repo at test-collection time.
    Reasoning

    At import time the conftest reads a bootstrap.py file from the repository and runs it with exec in the module globals. This matches a known pytest bootstrap pattern, and the file is in-tree. Running code at import is unusual enough that the local bootstrap file should be checked, but the snippet alone shows no sign of malice.

  5. info critical → info by review dynamic-execution tests/conftest.py:36:5

    `exec` at module scope (runs on import) on a non-literal expression (ast pass, confidence 0.80)

        to_bootstrap = "pytest"
        exec(code, globals(), locals())
    
        try:
    likely benign LLM, confidence 0.70 Runs the compiled bootstrap code at module scope during test setup.
    Reasoning

    This is the exec half of the same module-scope bootstrap, running the compiled in-repo bootstrap file. It is benign if bootstrap.py is trusted repository content, and the snippet gives no evidence that it is not.

  6. info warn → info by review dynamic-execution tests/test_autogen_render.py:708:9

    `eval` called on a non-literal expression (ast pass, confidence 0.70)

            context = op_fixture()
            eval(py_code)
            context.assert_(
                "CREATE TABLE b (a_id INTEGER, "
    likely benign LLM, confidence 0.90 Evals rendered migration Python in a test to check the SQL it produces.
    Reasoning

    The eval evaluates py_code the test itself generated and then asserts on the emitted SQL. This is a normal way to check rendered migration code in a test, with no external input involved.

  7. info warn → info by review dynamic-execution tests/test_autogen_render.py:732:9

    `eval` called on a non-literal expression (ast pass, confidence 0.70)

            context = op_fixture()
            eval(py_code)
            context.assert_(
                "CREATE TABLE b (a_id INTEGER, CONSTRAINT "
    likely benign LLM, confidence 0.90 Evals rendered migration Python in a test to verify generated CREATE TABLE SQL.
    Reasoning

    The same test-only pattern: eval of locally rendered migration code followed by an assertion on the resulting CREATE TABLE SQL.

  8. info warn → info by review dynamic-execution tests/test_autogen_render.py:749:9

    `eval` called on a non-literal expression (ast pass, confidence 0.70)

    
            eval(py_code)
            context.assert_(
                "ALTER TABLE b ADD CONSTRAINT fk_a_id "
    likely benign LLM, confidence 0.90 Evals rendered migration Python in a test to verify generated ALTER TABLE SQL.
    Reasoning

    Again a test that evals locally generated migration code and checks the SQL output. No external input or obfuscation is present.

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.1.0
git clone https://github.com/sqlalchemy/alembic alembic && cd alembic
git checkout rel_1_20_0
disclude scan --severity info --diff rel_1_19_2 .