PyPI / alembic / 1.20.1

alembic 1.20.1

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

Signals

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

  1. critical 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())
    inconclusive LLM, confidence 0.50 Module-level compile and exec of a local bootstrap file during test setup.
    Reasoning

    Reads a bootstrap file from a path and compiles and execs it at import time, injecting into module globals. The file is local and in the repo, so this is a loader pattern rather than a remote payload. The module-scope execution is unusual and warrants a look at what bootstrap_file contains, which the snippet does not show.

  2. critical 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:
    inconclusive LLM, confidence 0.50 Executes the local bootstrap code at module import.
    Reasoning

    Executes the compiled bootstrap code in module globals at import time. It is the same loader as the preceding compile, and it reads only a repo-local file. Whether that file is trustworthy depends on its contents, which are not shown.

  3. info warn → info by review dynamic-attribute alembic/autogenerate/render.py:943: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 Name-based dispatch to type-rendering helper functions.
    Reasoning

    Looks up a locally defined _render_<visit_name>_type function by name from globals to dispatch on a type's visit name. This is a common, legitimate dispatch pattern, and the name is built from a fixed type attribute, not attacker input.

  4. 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.80 Generates operation method bodies from text via exec.
    Reasoning

    exec builds a function from generated source text with explicit globals and a local namespace, then attaches it to a class. This matches alembic's generation of operation method signatures and docs. The text is produced internally, not from untrusted input.

  5. 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.80 Builds a callable from generated source text using exec.
    Reasoning

    exec compiles a function from locally generated source text into a namespace and returns it. This is a known helper for building functions with specific signatures. Nothing in the snippet shows external or encoded input.

  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.85 Test evaluates rendered migration code to verify output.
    Reasoning

    eval runs generated Python source in a test to check that rendered migration code is valid and produces the expected operations. This is a standard round-trip test technique with no external input.

  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.85 Test evaluates rendered migration code and asserts on the SQL.
    Reasoning

    Same round-trip test pattern: eval of rendered py_code followed by an assertion on the emitted SQL. The input is generated by the library under test.

  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.85 Test evaluates rendered constraint code and checks the ALTER TABLE output.
    Reasoning

    Same eval-based round-trip test for rendered foreign key constraint code. It is a benign testing construct.

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_1
disclude scan --severity info --diff rel_1_20_0 .