PyPI / duckdb / 2.0.0

duckdb 2.0.0

Source
https://github.com/duckdb/duckdb-python
Tag scanned
v2.0.0
Compared with
v1.5.6 (6 signals introduced since)
Files
574 scanned, 24 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 17 info
Scan time
8.5 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 6 of 6 warn and critical signals; 6 demoted to info.
Disclude version
4.1.0
Scanned (UTC)
2026-10-22 07:29

Signals

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

  1. info warn → info by review dynamic-execution benchmarks/README.md:20:3 new in this release

    [embedded bash] command name is a variable (`$P`) not set in this file — the caller or environment decides what runs (ast pass, confidence 0.70)

    for P in ../main/.venv-release/bin/python .venv-release/bin/python; do
      $P -m pytest benchmarks/<module>.py --codspeed --codspeed-mode=walltime -o addopts= -p no:cacheprovider
    done
    likely benign LLM, confidence 0.85 A README loop that runs benchmark pytest under a local or release virtualenv Python.
    Reasoning

    The loop runs pytest for benchmark modules under two interpreter paths the developer chose, in a documentation example. The variable command is a normal way to document running with a venv, and nothing in the snippet is hidden or malicious.

  2. info warn → info by review frame-introspection duckdb/_relation.py:444:31 new in this release

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

        level = 1
        frame: FrameType | None = sys._getframe(1)
        while frame is not None and frame.f_globals.get("__name__") == __name__:
            level += 1
    likely benign LLM, confidence 0.92 Frame walk to locate the external caller of the module's own functions.
    Reasoning

    Walking up the stack with sys._getframe while skipping frames from the same module is a standard way to find the real caller for warnings or stack-level adjustment. It is a common library pattern, not evasion.

  3. info warn → info by review dynamic-attribute duckdb/experimental/spark/sql/functions.py:6859:9 new in this release

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

        ):
            globals()[_function_name] = _spark_named(_function)
    likely benign LLM, confidence 0.90 Module-level registration of Spark-compatible function wrappers via globals().
    Reasoning

    Assigning generated wrapper functions into globals() during module setup is how this PySpark-compatibility layer exposes many named functions. The names come from a known list of Spark functions, so this is ordinary dynamic module construction.

  4. info warn → info by review dynamic-attribute duckdb/experimental/spark/sql/functions.py:6903:9 new in this release

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

        ):
            globals()[_name] = _carry_markers(_function)
    likely benign LLM, confidence 0.90 Second globals() registration of a marker-carrying wrapper function.
    Reasoning

    This is the same globals() registration pattern as the earlier finding, wrapping a function and storing it under a name. It is consistent with building a compatibility API and does not hide behaviour.

  5. info warn → info by review frame-introspection tests/fast/arrow/test_dbapi_arrow.py:702:16 new in this release

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

            method = getattr(duckdb_cursor, form)
            line = inspect.currentframe().f_lineno + 2
            with warns(form) as record:
                method()
    likely benign LLM, confidence 0.93 Test computes the current line number to check where a warning is attributed.
    Reasoning

    In a test, inspect.currentframe().f_lineno is used to compute the expected line number for a warning assertion. It is a routine testing technique with no execution or concealment involved.

  6. info warn → info by review dynamic-execution tests/fast/test_versioning.py:668:9 new in this release

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

            namespace: dict = {}
            exec(path.read_text(encoding="utf-8"), namespace)
            assert namespace["PACKAGE_COMMIT"] == PACKAGE_COMMIT
    likely benign LLM, confidence 0.80 Test execs a version source file to read its PACKAGE_COMMIT value.
    Reasoning

    The exec runs the contents of a file read from a path into a namespace, then checks PACKAGE_COMMIT. This is a plausible way to load a generated version module in a test. The source is a local file, not a network or encoded payload, but exec on file content is still worth a note, so confidence is moderate.

  7. file mixes tab and space indentation (2 tab-indented and 45 space-indented lines) (raw pass, confidence 0.40)

    class Database(NamedTuple):  # noqa: D101
        name: str
        description: str | None
        locationUri: str
  8. info whitespace-anomaly tests/fast/arrow/test_14344.py:9:1

    file mixes tab and space indentation (8 tab-indented and 8 space-indented lines) (raw pass, confidence 0.40)

    def test_14344(duckdb_cursor):
        my_table = pa.Table.from_pydict({"foo": pa.array([hashlib.sha256(b"foo").digest()], type=pa.binary())})  # noqa: F841
        my_table2 = pa.Table.from_pydict(  # noqa: F841
            {"foo": pa.array([hashlib.sha256(b"foo").digest()], type=pa.binary()), "a": ["123"]}
  9. info whitespace-anomaly tests/fast/arrow/test_5547.py:11:1

    file mixes tab and space indentation (1 tab-indented and 22 space-indented lines) (raw pass, confidence 0.40)

    def test_5547():
        num_rows = 2**17 + 1
    
        tbl = pa.Table.from_pandas(
  10. info whitespace-anomaly tests/fast/arrow/test_6796.py:10:1

    file mixes tab and space indentation (4 tab-indented and 11 space-indented lines) (raw pass, confidence 0.40)

    def test_6796():
        conn = duckdb.connect()
        input_df = pd.DataFrame({"foo": ["bar"]})
        conn.register("input_df", input_df)
  11. file mixes tab and space indentation (2 tab-indented and 12 space-indented lines) (raw pass, confidence 0.40)

    class TestArrowFixedBinary:
        def test_arrow_fixed_binary(self, duckdb_cursor):
            ids = [
                None,
  12. file mixes tab and space indentation (4 tab-indented and 24 space-indented lines) (raw pass, confidence 0.40)

    def test_nested(duckdb_cursor):
        res = run(duckdb_cursor, "select 42::UNION(name VARCHAR, attr UNION(age INT, veteran BOOL)) as res")
        assert pyarrow.types.is_union(res.type)
        assert res.value.value == pyarrow.scalar(42, type=pyarrow.int32())
  13. file mixes tab and space indentation (7 tab-indented and 5 space-indented lines) (raw pass, confidence 0.40)

    class TestColumnOrder:
        def test_column_order(self, duckdb_cursor):
            to_execute = """
    		CREATE OR REPLACE TABLE t1 AS (
  14. file mixes tab and space indentation (9 tab-indented and 26 space-indented lines) (raw pass, confidence 0.40)

    def con():
        conn = duckdb.connect()
        conn.execute(
            """
  15. file mixes tab and space indentation (9 tab-indented and 693 space-indented lines) (raw pass, confidence 0.40)

    def setup_and_teardown_of_table(duckdb_cursor):
        duckdb_cursor.execute("create table win(id int, v int, t int, f float, s varchar);")
        duckdb_cursor.execute(
            """
  16. file mixes tab and space indentation (11 tab-indented and 120 space-indented lines) (raw pass, confidence 0.40)

    if USE_ACTUAL_SPARK:
        pytest.skip(
            "Skipping these tests as they use test_all_types() which is specific to DuckDB", allow_module_level=True
        )
  17. info whitespace-anomaly tests/fast/test_union.py:5:1

    file mixes tab and space indentation (30 tab-indented and 30 space-indented lines) (raw pass, confidence 0.40)

    class TestUnion:
        def test_union_by_all(self):
            connection = duckdb.connect()

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/duckdb/duckdb-python duckdb-python && cd duckdb-python
git checkout v2.0.0
disclude scan --severity info --diff v1.5.6 .