PyPI / sqlalchemy / 2.1.5

sqlalchemy 2.1.5

Source
https://github.com/sqlalchemy/sqlalchemy
Tag scanned
rel_2_1_5
Compared with
rel_2_1_4 (0 signals introduced since)
Files
879 scanned, 17 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 46 info
Scan time
37.3 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 42 of 42 warn and critical signals; 42 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-17 00:42

Signals

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

  1. info critical → info by review dynamic-import examples/performance/__init__.py:335:21

    `__import__` called on a non-literal expression (ast pass, confidence 0.90)

                    try:
                        __import__(__name__ + "." + potential_name)
                    except ImportError:
                        pass
    likely benign LLM, confidence 0.80 Dynamic import of a sibling example module by constructed name.
    Reasoning

    Dynamic __import__ of a module name built from a loop variable inside an example profiler package. It loads sibling modules by name in a test/example harness, a common plugin pattern with no sign of obfuscation or malicious intent.

  2. info critical → info by review dynamic-import examples/performance/__init__.py:394:13

    `__import__` called on a non-literal expression (ast pass, confidence 0.90)

            if cls.name is None:
                __import__(__name__ + "." + args.name)
    
            Profiler(args).run()
    likely benign LLM, confidence 0.80 Dynamic import of a profiler module selected by CLI argument.
    Reasoning

    Imports a named profiler module chosen from a command-line argument. This is a developer-facing example script; the input is local and the pattern is ordinary plugin loading.

  3. info critical → info by review dynamic-import lib/sqlalchemy/dialects/__init__.py:48:22

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

            else:
                module = __import__("sqlalchemy.dialects.%s" % (dialect,)).dialects
                module = getattr(module, dialect)
        except ImportError:
    likely benign LLM, confidence 0.90 Loads a database dialect module by name within SQLAlchemy.
    Reasoning

    Standard SQLAlchemy dialect loader that imports sqlalchemy.dialects.<name> for a configured dialect name. This is the documented plugin mechanism of the library.

  4. info critical → info by review dynamic-import lib/sqlalchemy/dialects/mysql/mariadb.py:49:19

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

    def loader(driver: str) -> type[MariaDBDialect]:
        dialect_mod = __import__(
            "sqlalchemy.dialects.mysql.%s" % driver
        ).dialects.mysql
    likely benign LLM, confidence 0.90 Loads the MariaDB driver dialect module by driver name.
    Reasoning

    Driver-specific dialect loader that imports a fixed sqlalchemy.dialects.mysql submodule by driver name. Ordinary library code.

  5. info critical → info by review dynamic-import lib/sqlalchemy/dialects/mysql/mariadbconnector.py:210:32

    `__import__` called on a non-literal expression (ast pass, confidence 0.90)

                try:
                    CLIENT_FLAGS = __import__(
                        self.dbapi.__name__ + ".constants.CLIENT"
                    ).constants.CLIENT
    likely benign LLM, confidence 0.90 Imports the DBAPI constants module to read client flags.
    Reasoning

    Imports the constants module of the already-loaded DBAPI object's package to read CLIENT flags. Uses the dbapi's own __name__, so it is a routine compatibility shim.

  6. info critical → info by review dynamic-import lib/sqlalchemy/dialects/mysql/mysqldb.py:260:32

    `__import__` called on a non-literal expression (ast pass, confidence 0.90)

                try:
                    CLIENT_FLAGS = __import__(
                        self.dbapi.__name__ + ".constants.CLIENT"
                    ).constants.CLIENT
    likely benign LLM, confidence 0.90 Imports the MySQLdb constants module to read client flags.
    Reasoning

    Same DBAPI constants lookup as the mariadbconnector dialect, derived from the loaded dbapi module name. Routine library code.

  7. info critical → info by review dynamic-import lib/sqlalchemy/engine/default.py:742:13

    `__import__` called on a non-literal expression (ast pass, confidence 0.90)

            try:
                __import__(package + ".provision")
            except ImportError:
                pass
    likely benign LLM, confidence 0.90 Optionally imports a package's provisioning module.
    Reasoning

    Optional import of a package's provision submodule inside a try/except ImportError, used by the test provisioning framework. Ordinary optional-module loading.

  8. info warn → info by review dynamic-attribute lib/sqlalchemy/event/base.py:335:9

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

            # establish pickle capability by adding it to this module
            globals()[klass.__name__] = klass
    likely benign LLM, confidence 0.90 Registers a class in module globals so it can be pickled.
    Reasoning

    The comment states the purpose is to make classes picklable by registering them in module globals. This is a well-known Python idiom, not concealment.

  9. info warn → info by review dynamic-execution lib/sqlalchemy/orm/clsregistry.py:592:21

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

                try:
                    x = eval(self.arg, globals(), self._dict)
    
                    if isinstance(x, _GetColumns):
    likely benign LLM, confidence 0.85 Evaluates ORM relationship expression strings against the class registry.
    Reasoning

    eval of a string argument in a restricted namespace resolves ORM class-name expressions in relationship strings. It is a documented SQLAlchemy feature and the input comes from developer-authored model code, not untrusted data.

  10. info warn → info by review dynamic-attribute lib/sqlalchemy/sql/annotation.py:562:5

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

        )
        globals()["Annotated%s" % cls.__name__] = anno_cls
    
        if "_traverse_internals" in cls.__dict__:
    likely benign LLM, confidence 0.90 Registers a generated annotated class in module globals.
    Reasoning

    Registers a generated Annotated<ClassName> class in module globals so it can be pickled. Standard metaprogramming in the library.

  11. info warn → info by review dynamic-attribute lib/sqlalchemy/sql/coercions.py:1366:20

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

            if name in globals():
                impl = globals()[name](cls)
                _impl_lookup[cls] = impl
    likely benign LLM, confidence 0.90 Instantiates a coercion implementation class looked up in globals.
    Reasoning

    Looks up a coercion implementation class by name in module globals and instantiates it. Internal registry dispatch with no external input.

  12. info warn → info by review dynamic-execution lib/sqlalchemy/sql/lambdas.py:1264:9

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

            vars_ = {"o%d" % i: cell_values[i] for i in argrange}
            exec(code, vars_, vars_)
            closure = vars_["make_cells"]()
    likely benign LLM, confidence 0.85 Executes generated code to construct closure cells for lambda statements.
    Reasoning

    exec of internally generated code that builds closure cells for lambda caching. The code is generated from fixed templates over internal values, so this is a known library technique rather than hidden payload execution.

  13. info critical → info by review dynamic-import lib/sqlalchemy/testing/engines.py:250:17

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

                mod = getattr(
                    __import__("sqlalchemy.dialects.%s" % name).dialects, name
                )
            yield mod.dialect()
    likely benign LLM, confidence 0.90 Imports a dialect module by name for test engine setup.
    Reasoning

    Imports a dialect test module by name inside the testing engine helper. Ordinary test-infrastructure code.

  14. info warn → info by review frame-introspection lib/sqlalchemy/testing/fixtures/mypy.py:118:27

    `inspect.stack` — call-stack frame introspection (ast pass, confidence 0.70)

            else:
                caller_path = inspect.stack()[1].filename
                path = os.path.join(os.path.dirname(caller_path), dirname)
            files = list(Path(path).glob("**/*.py"))
    likely benign LLM, confidence 0.90 Reads the caller's file path via stack inspection in a test fixture.
    Reasoning

    Uses inspect.stack to find the caller's file path so tests can locate files relative to it. Common and benign in test fixtures.

  15. info critical → info by review dynamic-import lib/sqlalchemy/testing/plugin/plugin_base.py:487:11

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

        # late
        mod = __import__(modname)
        for component in modname.split(".")[1:]:
            mod = getattr(mod, component)
    likely benign LLM, confidence 0.90 Dynamically imports a test plugin module by dotted name.
    Reasoning

    Imports a module from a dotted name in the test plugin and walks its attributes. Standard dynamic loading in pytest plugin code.

  16. info warn → info by review dynamic-execution lib/sqlalchemy/testing/plugin/pytestplugin.py:671:9

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

            # in format_argpsec_plus()
            exec(code, env)
            return env[fn_name]
    likely benign LLM, confidence 0.85 Execs generated code to create a function with a given signature for tests.
    Reasoning

    exec builds a function with a matching signature for test argument formatting, using code produced internally by the library. This is a known pattern for generating wrappers in test tooling.

  17. info warn → info by review frame-introspection lib/sqlalchemy/testing/schema.py:192:18

    `sys._getframe` — call-stack frame introspection (ast pass, confidence 0.70)

        try:
            module = sys._getframe(1).f_globals.get("__name__", "__main__")
        except (AttributeError, ValueError):
            pass
    likely benign LLM, confidence 0.90 Reads caller's module name via frame introspection in SQLAlchemy testing schema helper.
    Reasoning

    sys._getframe(1) to read the caller's __name__ is a common idiom for determining the calling module in test schema helpers; no suspicious use.

  18. identifier `é試蛇ẟΩ` mixes scripts: Latin + Han + Greek (in string/comment) (raw pass, confidence 0.40)

                metadata,
                Column("unicode", Integer, comment="é試蛇ẟΩ"),
                Column("emoji", Integer, comment="☁⟨U+FE0F⟩✨"),
                comment="試蛇ẟΩ✨",
  19. identifier `試蛇ẟΩ` mixes scripts: Han + Latin + Greek (in string/comment) (raw pass, confidence 0.40)

                Column("emoji", Integer, comment="☁⟨U+FE0F⟩✨"),
                comment="試蛇ẟΩ✨",
            )
  20. identifier `試蛇ẟΩ` mixes scripts: Han + Latin + Greek (in string/comment) (raw pass, confidence 0.40)

            tc = insp.get_table_comment("unicode_comments")
            eq_(tc, {"text": "試蛇ẟΩ✨"})
    
            cols = insp.get_columns("unicode_comments")
  21. identifier `é試蛇ẟΩ` mixes scripts: Latin + Han + Greek (in string/comment) (raw pass, confidence 0.40)

            value = {c["name"]: c["comment"] for c in cols}
            exp = {"unicode": "é試蛇ẟΩ", "emoji": "☁⟨U+FE0F⟩✨"}
            eq_(value, exp)
  22. info warn → info by review dynamic-execution lib/sqlalchemy/util/langhelpers.py:453:16

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

                linecache_cache[filename] = entry
            code = compile(code, filename, "exec")
    
        exec(code, env)
    likely benign LLM, confidence 0.90 Compiles generated Python source for dynamically created wrapper functions.
    Reasoning

    compile of generated function source in SQLAlchemy's decorator generator (decorator-style wrapper creation with linecache registration) is a known legitimate metaprogramming pattern; the code is internally generated, not attacker-supplied.

  23. info warn → info by review dynamic-execution lib/sqlalchemy/util/langhelpers.py:455:5

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

    
        exec(code, env)
        fn = env[fn_name]
    likely benign LLM, confidence 0.88 Executes generated wrapper function source in a local namespace.
    Reasoning

    exec of internally generated function source into a local env is the standard decorator-generation mechanism in SQLAlchemy; the code string is built from the function signature of the decorated function, not external input.

  24. info critical → info by review dynamic-import lib/sqlalchemy/util/langhelpers.py:507:19

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

            def load():
                mod = __import__(modulepath)
                for token in modulepath.split(".")[1:]:
                    mod = getattr(mod, token)
    likely benign LLM, confidence 0.85 Dynamically imports a module by path for lazy loading.
    Reasoning

    Lazy module loading by dotted path from a developer-supplied constant is a standard pattern for deferred imports in SQLAlchemy; no obfuscation or remote input involved, though the critical severity overstates it.

  25. info critical → info by review frame-introspection lib/sqlalchemy/util/langhelpers.py:2060:17

    `sys._getframe` — call-stack frame introspection — file also calls `sys.exit`/`exec`/`eval` (anti-analysis shape) (ast pass, confidence 0.85)

        try:
            frame = sys._getframe(stacklevel)
        except ValueError:
            # being called from less than 3 (or given) stacklevels, weird,
    likely benign LLM, confidence 0.85 Walks the call stack to locate a caller frame for warning attribution.
    Reasoning

    sys._getframe with a stacklevel to find the caller for warnings is a standard pattern; the co-occurrence flag with exec in the same file reflects SQLAlchemy's own generated-code helpers, not anti-analysis.

  26. info warn → info by review dynamic-execution lib/sqlalchemy/util/langhelpers.py:2163:5

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

        env = locals().copy()
        exec(code, env)
        return env["set"]
    likely benign LLM, confidence 0.88 Executes generated source to construct a helper function.
    Reasoning

    exec of generated source with a copied locals dict to build a set-like function is legitimate code generation in SQLAlchemy's utility module.

  27. info critical → info by review dynamic-import lib/sqlalchemy/util/preloaded.py:142:17

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

                ) and key not in self.__dict__:
                    __import__(module, globals(), locals())
                    self.__dict__[key] = globals()[key] = sys.modules[module]
    likely benign LLM, confidence 0.85 Lazily imports a named module and caches it on the instance.
    Reasoning

    Preloaded-module mechanism imports a module named by a fixed key and caches it in __dict__; this is an intentional lazy import helper, not malicious.

  28. info warn → info by review dynamic-attribute lib/sqlalchemy/util/preloaded.py:143:38

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

                    __import__(module, globals(), locals())
                    self.__dict__[key] = globals()[key] = sys.modules[module]
    likely benign LLM, confidence 0.80 Caches a lazily imported module in globals and sys.modules lookup.
    Reasoning

    Writing the imported module into globals() is the documented caching step of the preloaded lazy-import helper; reaching sys.modules by known name is ordinary.

  29. info warn → info by review dynamic-execution lib/sqlalchemy/util/typing.py:265:26

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

    
                annotation = eval(expression, cls_namespace, locals_)
            else:
                annotation = eval(expression, base_globals, locals_)
    likely benign LLM, confidence 0.85 Evaluates a string type annotation in the class namespace.
    Reasoning

    eval of string type annotations with class namespace is how Python resolves forward references in typing utilities; standard behavior in SQLAlchemy.

  30. info warn → info by review dynamic-execution lib/sqlalchemy/util/typing.py:267:26

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

            else:
                annotation = eval(expression, base_globals, locals_)
        except Exception as err:
            raise NameError(
    likely benign LLM, confidence 0.85 Evaluates a string type annotation against base globals.
    Reasoning

    Same forward-reference evaluation of annotation strings against module globals; legitimate typing introspection.

  31. info warn → info by review dynamic-execution test/base/test_typing_utils.py:243:5

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

        scope = {}
        exec(code, None, scope)
        if len(vars) == 1:
            return scope[vars[0]]
    likely benign LLM, confidence 0.80 Executes test snippet code in a scratch namespace to extract variables.
    Reasoning

    Test helper executes a test code snippet in an isolated scope to check typing behavior; test-only and not attacker-facing.

  32. info critical → info by review dynamic-execution test/conftest.py:56: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 Executes a repository bootstrap file at conftest import time.
    Reasoning

    Compiles and executes a bootstrap.py file from the repository at import time for pytest plugin setup; this is a known pattern in SQLAlchemy's conftest, and the file is in-repo, but module-scope exec of a sibling file is worth a note since it runs on import.

  33. info critical → info by review dynamic-execution test/conftest.py:58: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())
        from sqla_pytestplugin import *  # noqa
    likely benign LLM, confidence 0.70 Runs the repository bootstrap code into the conftest namespace.
    Reasoning

    Same bootstrap exec in conftest; the source is the in-repo bootstrap.py, consistent with SQLAlchemy's test setup, so benign unless bootstrap.py itself is tampered with, which this snippet does not show.

  34. info warn → info by review dynamic-execution test/dialect/mysql/test_types.py:202:29

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

            # test that repr() copies out all arguments
            self.assert_compile(eval("mysql.%r" % type_inst), res)
    
        @testing.combinations(
    likely benign LLM, confidence 0.85 Evaluates a type repr string in a test asserting repr round-trip.
    Reasoning

    eval of a repr string generated from a type instance in a test verifying repr round-trips; test-only, input is internally produced.

  35. info critical → info by review dynamic-import test/dialect/postgresql/test_dialect.py:1271:40

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

            if psycopg.__version__.startswith("3"):
                TransactionRollbackError = __import__(
                    "%s.errors" % psycopg.__name__
                ).errors.TransactionRollback
    likely benign LLM, confidence 0.85 Imports psycopg errors module by version-dependent name in a test.
    Reasoning

    Conditional import of the psycopg errors module based on version in a test; the module name derives from the installed library, standard compatibility shim.

  36. info critical → info by review dynamic-import test/dialect/postgresql/test_dialect.py:1275:40

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

            else:
                TransactionRollbackError = __import__(
                    "%s.extensions" % psycopg.__name__
                ).extensions.TransactionRollbackError
    likely benign LLM, confidence 0.85 Imports psycopg2 extensions module by name in a test shim.
    Reasoning

    Version-conditional import of psycopg2 extensions in a test compatibility branch; benign.

  37. info critical → info by review dynamic-import test/dialect/test_all.py:9:21

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

            return [
                getattr(__import__("sqlalchemy.dialects.%s" % d).dialects, d)
                for d in dialects.__all__
                if not d.startswith("_")
    likely benign LLM, confidence 0.90 Test helper that dynamically imports SQLAlchemy dialect submodules by name.
    Reasoning

    Imports each SQLAlchemy dialect module by name from dialects.__all__, a fixed list in the package. This is standard dynamic import for a test harness, with no network, encoding or payload behaviour.

  38. info warn → info by review dynamic-execution test/engine/test_parseconnect.py:541:13

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

            ):
                exec(
                    "from sqlalchemy.dialects import %s\ndialect = "
                    "%s.dialect()" % (name, name),
    likely benign LLM, confidence 0.90 Test executes generated code that imports and instantiates a SQLAlchemy dialect.
    Reasoning

    Builds a small Python snippet importing an SQLAlchemy dialect and executes it to check that dialect loading works. The name comes from the test's own parameters, so this is ordinary test scaffolding.

  39. info warn → info by review decoder-import-with-exec test/ext/test_associationproxy.py:918:21

    file imports decoder module(s) pickle and calls `exec`/`eval`/`compile` — multi-stage payload shape (ast pass, confidence 0.80)

    
                        exec("p.children %s other" % op)
                        exec("control %s other" % op)
    likely benign LLM, confidence 0.85 Test file that imports pickle and builds comparison expressions with exec over operator strings.
    Reasoning

    The pickle import is incidental. The exec calls build comparison expressions from a fixed operator string in a test. The multi-stage payload pattern does not fit: there is no decode or fetch step.

  40. info warn → info by review dynamic-execution test/ext/test_associationproxy.py:918:21

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

    
                        exec("p.children %s other" % op)
                        exec("control %s other" % op)
    likely benign LLM, confidence 0.90 exec of a format string built from a test-parameter comparison operator.
    Reasoning

    exec runs a format string whose only variable is an operator from the test's parameter list. It is a test that checks operator overloading on proxies, with no external input.

  41. info warn → info by review dynamic-execution test/ext/test_associationproxy.py:919:21

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

                        exec("p.children %s other" % op)
                        exec("control %s other" % op)
    
                        try:
    likely benign LLM, confidence 0.90 exec of a format string built from a test-parameter comparison operator.
    Reasoning

    Same pattern as the preceding finding: exec of a string built from a fixed comparison operator in a unit test.

  42. info warn → info by review dynamic-execution test/orm/test_inspect.py:513:9

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

    
            exec(code, glbls)
            return names, glbls[clsname]
    likely benign LLM, confidence 0.90 Test helper that execs generated class source to construct a mapped class.
    Reasoning

    Compiles and runs generated class source into a provided globals dict, then reads back the class. This is a common technique for testing ORM class-construction behaviour, and the code is test-authored.

  43. info critical → info by review dynamic-execution test/perf/orm2010.py:167:9

    `os.system` called on a non-literal command — runtime-determined shell invocation (ast pass, confidence 0.85)

        if runsnake:
            os.system("runsnake %s" % filename)
    likely benign LLM, confidence 0.75 Performance script that optionally shells out to the runsnake profiler viewer on a file.
    Reasoning

    The shell call is gated on a runsnake flag and runs a profiling viewer on a local filename. It is an unquoted shell interpolation, a minor injection risk in a dev script, but not malicious or obfuscated.

  44. info warn → info by review dynamic-execution test/sql/test_lambdas.py:2220:9

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

            d = {"A": A, "__name__": "lambda_fake"}
            exec(code, d)
            generate_lambda_stmt = d["generate_lambda_stmt"]
    likely benign LLM, confidence 0.90 Test execs generated lambda source to exercise SQL lambda statement behaviour.
    Reasoning

    Executes generated lambda source into a dict to test SQL lambda statement caching. The code is authored inside the test, so this is a legitimate testing technique.

  45. info warn → info by review decoder-import-with-exec test/sql/test_metadata.py:7745:13

    file imports decoder module(s) pickle and calls `exec`/`eval`/`compile` — multi-stage payload shape (ast pass, confidence 0.80)

            # the repr round trips
            eq_(eval(repr(fk)).target_tokens, fk.target_tokens)
    
        def test_no_such_column_error_message(self):
    likely benign LLM, confidence 0.90 Test evals a ForeignKey repr to verify the repr round-trips.
    Reasoning

    eval of repr(fk) checks that a ForeignKey repr round-trips. The eval target is the object's own repr in a test, with no external input and no decoder step.

  46. info warn → info by review dynamic-execution test/sql/test_metadata.py:7745:13

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

            # the repr round trips
            eq_(eval(repr(fk)).target_tokens, fk.target_tokens)
    
        def test_no_such_column_error_message(self):
    likely benign LLM, confidence 0.90 eval of a ForeignKey repr to verify round-trip behaviour in a test.
    Reasoning

    Same eval(repr(fk)) round-trip check as the preceding finding, a standard repr test.

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.0.0
git clone https://github.com/sqlalchemy/sqlalchemy sqlalchemy && cd sqlalchemy
git checkout rel_2_1_5
disclude scan --severity info --diff rel_2_1_4 .