Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
7d6f470
ruff conf: exclude pyi from linting
evertlammerts Sep 9, 2025
db57889
Ruff UP006: dont use typing module for dict and list typehints
evertlammerts Sep 9, 2025
c23b65d
Ruff ANN204: return type annotations
evertlammerts Sep 9, 2025
83cdb9c
Ruff config: line-length to 120 and fixable no longer top level
evertlammerts Sep 9, 2025
d10c477
Ruff format fixes
evertlammerts Sep 9, 2025
0ec0572
Ruff linter fixes
evertlammerts Sep 9, 2025
c499e40
Ruff format fixes
evertlammerts Sep 9, 2025
cde722e
Ruff config: dont add future annotations
evertlammerts Sep 9, 2025
89c6387
Ruff config: temporarily skip import checks
evertlammerts Sep 9, 2025
6370653
Ruff EM: Error messages assigned to a var first
evertlammerts Sep 9, 2025
6445bde
Ruff D: Docstring fixes
evertlammerts Sep 9, 2025
2119fb0
Ruff D301: Make docstring raw if they contain backslashes
evertlammerts Sep 9, 2025
b6fb52a
Fix testfixture yield
evertlammerts Sep 10, 2025
4ff4147
Ruff config: disable docstring checks for tests
evertlammerts Sep 10, 2025
f983b69
Ruff noqa D205 on tests: no need to check newline between summary and
evertlammerts Sep 10, 2025
12c0f48
Ruff noqa D205: dont need the newline in docstrings for existing code
evertlammerts Sep 10, 2025
c0a94d2
Ruff config: will not check sqlogic
evertlammerts Sep 10, 2025
5cea343
Ruff config: will not check scripts for D
evertlammerts Sep 10, 2025
a1675c8
Ruff noqa D10x: ignore docstring issues in existing code
evertlammerts Sep 10, 2025
5a6deb4
Ruff config: F403 ignore * imports in pyspark tests
evertlammerts Sep 10, 2025
0041aab
Ruff F403: fix star imports
evertlammerts Sep 10, 2025
ebe92af
Ruff format
evertlammerts Sep 10, 2025
7301a4d
Ruff linting fixes
evertlammerts Sep 10, 2025
664c37b
Ruff F401: fixed unused imports
evertlammerts Sep 10, 2025
f7930af
Ruff config: disable ANN001 for tests and scripts, no need for type h…
evertlammerts Sep 10, 2025
63b902c
Ruff ANN001: fixed missing annotations for function args
evertlammerts Sep 10, 2025
a6e9d4e
Ruff linting
evertlammerts Sep 10, 2025
25d3ab0
Ruff format
evertlammerts Sep 10, 2025
6561517
Ruff config: ANN201 no need for return value type hints in tests and …
evertlammerts Sep 10, 2025
efe66bb
Ruff ANN201: fixed return value type annotations
evertlammerts Sep 10, 2025
6fae540
Ruff F841: fixes and noqa for unused variables
evertlammerts Sep 11, 2025
a88cb67
Ruff linting
evertlammerts Sep 11, 2025
052be91
Ruff config: dont check E402 (imports at top of file) for spark tests…
evertlammerts Sep 11, 2025
888c9d7
Ruff E402: imports must be at top of file
evertlammerts Sep 11, 2025
d0120bf
Ruff format
evertlammerts Sep 11, 2025
000d0bc
Ruff E501: fixed and noqa'd too long lines
evertlammerts Sep 11, 2025
1bac4fa
Ruff C419: Unsafe-fixed all unneeded list comprehensions
evertlammerts Sep 11, 2025
6db0c58
Ruff ANN202: Unsafe-fixed return type annotations in tests only
evertlammerts Sep 11, 2025
c36ac0f
Ruff ANN202: Unsafe-fixed return type annotations
evertlammerts Sep 11, 2025
ad82673
Ruff ANN202: no need for private return value annotations in tests
evertlammerts Sep 11, 2025
d72bd4c
Ruff ANN202: fixed private function return value type annotations
evertlammerts Sep 11, 2025
74bc341
Ruff linting
evertlammerts Sep 11, 2025
694115f
Ruff PTH118: pathlib everywhere except for tests, which get a noqa fo…
evertlammerts Sep 11, 2025
a899e5e
Ruff linting & format
evertlammerts Sep 11, 2025
908675f
Ruff B018: fixed useless expressions
evertlammerts Sep 11, 2025
8c02e95
Ruff ANN401: specialized Any type hints where possible
evertlammerts Sep 12, 2025
8a88e98
Ruff FBT001: Spark API is out of our hands and may include boolean pa…
evertlammerts Sep 12, 2025
339eb85
Ruff FBT001: fixed most boolean params
evertlammerts Sep 12, 2025
42a6f2f
Ruff linting
evertlammerts Sep 12, 2025
69cc744
Ruff format
evertlammerts Sep 12, 2025
f783f6b
Ruff format
evertlammerts Sep 18, 2025
15226c7
Ruff linting
evertlammerts Sep 18, 2025
4fc1323
Ruff E722: no empty except
evertlammerts Sep 18, 2025
b0519be
Ruff E711: compare to None should be identity equality (is), not valu…
evertlammerts Sep 18, 2025
92c2990
Ruff PTH120: Use pathlib instead of os.path
evertlammerts Sep 18, 2025
af4d663
Ruff TD001: Replace invalid FIXME tag with TODO
evertlammerts Sep 18, 2025
2ac0176
Ruff TD002 and TD003: added noqa for author and issue links in existi…
evertlammerts Sep 18, 2025
6356b2a
Ruff E712: don't compare with True or False
evertlammerts Sep 18, 2025
dc2b16b
Remove >=py310 only union syntax
evertlammerts Sep 18, 2025
facdde1
Ruff PT009: don't use pytest's assertEqual, prefer the assert builtin
evertlammerts Sep 18, 2025
44c18a4
Ruff UP031: replace percent style string interpolation with string fo…
evertlammerts Sep 18, 2025
fb99768
Ruff linting: replaced format strings with f-strings where possible
evertlammerts Sep 18, 2025
ed4f181
Ruff PTH: moved to pathlib anywhere I could
evertlammerts Sep 18, 2025
7ea544f
Ruff PT003: removed unneeded implicit fixture scope
evertlammerts Sep 18, 2025
86c1066
Ruff PT018: broke up multi-part asserts
evertlammerts Sep 18, 2025
f6f118e
Ruff PT013: no subpackage import of pytest
evertlammerts Sep 18, 2025
d02d0f5
Ruff PT007: give pytest.parameterize list of tuples
evertlammerts Sep 18, 2025
f2ab732
Ruff PT006: fir param for pytest.parameterize should be a tuple, not …
evertlammerts Sep 18, 2025
2a2a8b4
Ruff PT012: pytest.raises contextmanagers should only have a single s…
evertlammerts Sep 18, 2025
ed90ded
Ruff format
evertlammerts Sep 18, 2025
735cf0a
Making tests pass
evertlammerts Sep 18, 2025
9849a19
Ruff format
evertlammerts Sep 18, 2025
863e043
Ruff PT: fixed remaining pytest linting issues
evertlammerts Sep 18, 2025
11b0851
Ruff linting
evertlammerts Sep 18, 2025
5ad0a0e
Ruff B: Fixed last bugbear linting issues
evertlammerts Sep 18, 2025
7f0ff48
Ruff C416: use list() instead of comprehension where possible
evertlammerts Sep 18, 2025
7ad26fb
Ruff config: ignore C901, function complexity
evertlammerts Sep 18, 2025
16fcbbc
Ruff C408: rewrite dict() calls as literals
evertlammerts Sep 18, 2025
d65d2b6
Ruff C417: changed map() to comprehensions and generator where possible
evertlammerts Sep 18, 2025
92a0698
Ruff format
evertlammerts Sep 18, 2025
c86008b
Ruff ignore ANN002 and ANN003
evertlammerts Sep 18, 2025
928b4f8
Ruff ANN: fixed remaining annotation linting issues
evertlammerts Sep 18, 2025
13d2e08
Fix tests
evertlammerts Sep 18, 2025
7f3104b
Ruff SIM: fixed all remaining simplify linting issues
evertlammerts Sep 18, 2025
61ba166
Ruff RUF: fixed all remaining ruff specific linter issues
evertlammerts Sep 18, 2025
a0e2b04
Ruff ignore PERF for duckdb_packaging
evertlammerts Sep 18, 2025
6de2ab7
Ruff PERF: fixed all remaining performance linting issues
evertlammerts Sep 18, 2025
1ee6b42
Ruff format
evertlammerts Sep 18, 2025
dc95538
Ruff linting - remaining unsafe fixes
evertlammerts Sep 18, 2025
534bd76
Ruff linting - fixed all remaining issues
evertlammerts Sep 18, 2025
4016ae1
Ruff format
evertlammerts Sep 18, 2025
bbac5a5
Fixed test
evertlammerts Sep 18, 2025
cd396c8
Added pre-commit
evertlammerts Sep 18, 2025
bd2469f
Added ruff and clang-format to pre-commit
evertlammerts Sep 18, 2025
9adacb5
Added cmake-format to pre-commit
evertlammerts Sep 18, 2025
b9c1bd4
Added post-checkout hook to pre-commit config
evertlammerts Sep 18, 2025
c13599a
Run pre-commit on-push
evertlammerts Sep 18, 2025
cdf0ee0
Very subtle typing problem in the tests
evertlammerts Sep 18, 2025
ba86441
Add code quality workflow
evertlammerts Sep 18, 2025
da516cb
fix sdist build
evertlammerts Sep 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
45 changes: 45 additions & 0 deletions .github/workflows/code_quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Code Quality Checks
on:
workflow_dispatch:
inputs:
git_ref:
type: string
description: Git ref of the DuckDB python package
required: false
workflow_call:
inputs:
git_ref:
type: string
description: Git ref of the DuckDB python package
required: false

defaults:
run:
shell: bash

jobs:
run_checks:
name: Run linting and formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.git_ref }}
fetch-depth: 0
persist-credentials: false

- name: Install Astral UV
uses: astral-sh/setup-uv@v6
with:
version: "0.7.14"
python-version: 3.9

- name: pre-commit (cache)
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}

- name: pre-commit (--all-files)
run: |
uvx pre-commit run --show-diff-on-failure --color=always --all-files
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,4 @@ jobs:
echo "### C++ Coverage Summary" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$SUMMARY_CPP" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
9 changes: 7 additions & 2 deletions .github/workflows/on_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ jobs:
name: Make sure submodule is in a sane state
uses: ./.github/workflows/submodule_sanity.yml

code_quality:
name: Code-quality checks
needs: submodule_sanity_guard
uses: ./.github/workflows/code_quality.yml

packaging_test:
name: Build a minimal set of packages and run all tests on them
needs: submodule_sanity_guard
needs: code_quality
# Skip packaging tests for draft PRs
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
uses: ./.github/workflows/packaging.yml
Expand All @@ -36,7 +41,7 @@ jobs:

coverage_test:
name: Run coverage tests
needs: submodule_sanity_guard
needs: code_quality
# Only run coverage test for draft PRs
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.draft == true }}
uses: ./.github/workflows/coverage.yml
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/on_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ concurrency:
cancel-in-progress: true

jobs:
code_quality:
name: Code-quality checks
uses: ./.github/workflows/code_quality.yml

test:
name: Run coverage tests
needs: code_quality
uses: ./.github/workflows/coverage.yml
with:
git_ref: ${{ github.ref }}
Expand Down
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.13.0
hooks:
# Run the linter.
- id: ruff-check
# Run the formatter.
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v18.1.8 # pick the version of clang-format you want
hooks:
- id: clang-format
files: \.(c|cpp|cc|h|hpp|cxx|hxx)$

- repo: https://github.com/cheshirekow/cmake-format-precommit
rev: v0.6.13
hooks:
- id: cmake-format

- repo: local
hooks:
- id: post-checkout-submodules
name: Update submodule post-checkout
entry: .githooks/post-checkout
language: script
stages: [ post-checkout ]
49 changes: 26 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,50 +48,53 @@ duckdb_add_library(duckdb_target)

# Bundle in INTERFACE library
add_library(_duckdb_dependencies INTERFACE)
target_link_libraries(_duckdb_dependencies INTERFACE
pybind11::pybind11
duckdb_target
)
target_link_libraries(_duckdb_dependencies INTERFACE pybind11::pybind11
duckdb_target)
# Also add include directory
target_include_directories(_duckdb_dependencies INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/duckdb_py/include>
target_include_directories(
_duckdb_dependencies
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/duckdb_py/include>
)

# ────────────────────────────────────────────
# Descend into the real DuckDB‑Python sources
# ────────────────────────────────────────────
add_subdirectory(src/duckdb_py)

pybind11_add_module(_duckdb
$<TARGET_OBJECTS:python_src>
$<TARGET_OBJECTS:python_arrow>
$<TARGET_OBJECTS:python_common>
$<TARGET_OBJECTS:python_functional>
$<TARGET_OBJECTS:python_jupyter>
$<TARGET_OBJECTS:python_native>
$<TARGET_OBJECTS:python_numpy>
$<TARGET_OBJECTS:python_pandas>
$<TARGET_OBJECTS:python_pybind11>
$<TARGET_OBJECTS:python_connection>
$<TARGET_OBJECTS:python_expression>
$<TARGET_OBJECTS:python_relation>
$<TARGET_OBJECTS:python_type>
)
pybind11_add_module(
_duckdb
$<TARGET_OBJECTS:python_src>
$<TARGET_OBJECTS:python_arrow>
$<TARGET_OBJECTS:python_common>
$<TARGET_OBJECTS:python_functional>
$<TARGET_OBJECTS:python_jupyter>
$<TARGET_OBJECTS:python_native>
$<TARGET_OBJECTS:python_numpy>
$<TARGET_OBJECTS:python_pandas>
$<TARGET_OBJECTS:python_pybind11>
$<TARGET_OBJECTS:python_connection>
$<TARGET_OBJECTS:python_expression>
$<TARGET_OBJECTS:python_relation>
$<TARGET_OBJECTS:python_type>)
# add _duckdb_dependencies
target_link_libraries(_duckdb PRIVATE _duckdb_dependencies)

# ────────────────────────────────────────────
# Put the object file in the correct place
# ────────────────────────────────────────────

# If we're not building through scikit-build-core then we have to set a different dest dir
# If we're not building through scikit-build-core then we have to set a
# different dest dir
include(GNUInstallDirs)
if(DEFINED SKBUILD_PLATLIB_DIR)
set(_DUCKDB_PY_INSTALL_DIR "${SKBUILD_PLATLIB_DIR}")
elseif(DEFINED Python_SITEARCH)
set(_DUCKDB_PY_INSTALL_DIR "${Python_SITEARCH}")
else()
message(WARNING "Could not determine Python install dir. Falling back to CMAKE_INSTALL_LIBDIR.")
message(
WARNING
"Could not determine Python install dir. Falling back to CMAKE_INSTALL_LIBDIR."
)
set(_DUCKDB_PY_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
endif()

Expand Down
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,22 @@ git fetch --all

### Submodule update hook

If you'll be switching between branches that are have the submodule set to different refs, then make your life
easier and add the git hooks in the .githooks directory to your local config:
If you'll be switching between branches that are have the submodule set to different refs, then make your life
easier and add the git hooks in the .githooks directory to your git hooks:
```shell
git config --local core.hooksPath .githooks/
cp .githooks/post-checkout .git/hooks/
```


### Editable installs (general)

It's good to be aware of the following when performing an editable install:
- `uv sync` or `uv run [tool]` perform an editable install by default. We have
configured the project so that scikit-build-core will use a persistent build-dir, but since the build itself
happens in an isolated, ephemeral environment, cmake's paths will point to non-existing directories. CMake itself
- `uv sync` or `uv run [tool]` perform an editable install by default. We have
configured the project so that scikit-build-core will use a persistent build-dir, but since the build itself
happens in an isolated, ephemeral environment, cmake's paths will point to non-existing directories. CMake itself
will be missing.
- You should install all development dependencies, and then build the project without build isolation, in two separate
steps. After this you can happily keep building and running, as long as you don't forget to pass in the
- You should install all development dependencies, and then build the project without build isolation, in two separate
steps. After this you can happily keep building and running, as long as you don't forget to pass in the
`--no-build-isolation` flag.

```bash
Expand All @@ -93,9 +93,9 @@ uv sync --no-build-isolation

### Editable installs (IDEs)

If you're using an IDE then life is a little simpler. You install build dependencies and the project in the two
steps outlined above, and from that point on you can rely on e.g. CLion's cmake capabilities to do incremental
compilation and editable rebuilds. This will skip scikit-build-core's build backend and all of uv's dependency
If you're using an IDE then life is a little simpler. You install build dependencies and the project in the two
steps outlined above, and from that point on you can rely on e.g. CLion's cmake capabilities to do incremental
compilation and editable rebuilds. This will skip scikit-build-core's build backend and all of uv's dependency
management, so for "real" builds you better revert to the CLI. However, this should work fine for coding and debugging.


Expand Down Expand Up @@ -139,7 +139,7 @@ uv run --no-build-isolation pytest ./tests --verbose --ignore=./tests/slow
COVERAGE=1 uv run --no-build-isolation coverage run -m pytest ./tests --verbose
```

The `COVERAGE` env var will compile the extension with `--coverage`, allowing us to collect coverage stats of C++
The `COVERAGE` env var will compile the extension with `--coverage`, allowing us to collect coverage stats of C++
code as well as Python code.

Check coverage for Python code:
Expand All @@ -148,7 +148,7 @@ uvx coverage html -d htmlcov-python
uvx coverage report --format=markdown
```

Check coverage for C++ code (note: this will clutter your project dir with html files, consider saving them in some
Check coverage for C++ code (note: this will clutter your project dir with html files, consider saving them in some
other place):
```bash
uvx gcovr \
Expand Down Expand Up @@ -275,7 +275,7 @@ versioning scheme.
```toml
[tool.scikit-build]
metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"

[tool.setuptools_scm]
version_scheme = "duckdb_packaging._setuptools_scm_version:version_scheme"
```
Expand Down
5 changes: 2 additions & 3 deletions adbc_driver_duckdb/dbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
# specific language governing permissions and limitations
# under the License.

"""
DBAPI 2.0-compatible facade for the ADBC DuckDB driver.
"""
"""DBAPI 2.0-compatible facade for the ADBC DuckDB driver."""

import typing

import adbc_driver_manager
import adbc_driver_manager.dbapi

import adbc_driver_duckdb

__all__ = [
Expand Down
30 changes: 18 additions & 12 deletions cmake/compiler_launcher.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,25 @@ include(CMakeParseArguments)
# Function to look for ccache and sccache to speed up builds, if available
# ────────────────────────────────────────────
function(setup_compiler_launcher_if_available)
if(NOT DEFINED CMAKE_C_COMPILER_LAUNCHER AND NOT DEFINED ENV{CMAKE_C_COMPILER_LAUNCHER})
find_program(COMPILER_LAUNCHER NAMES ccache sccache)
if(COMPILER_LAUNCHER)
message(STATUS "Using ${COMPILER_LAUNCHER} as C compiler launcher")
set(CMAKE_C_COMPILER_LAUNCHER "${COMPILER_LAUNCHER}" CACHE STRING "" FORCE)
endif()
if(NOT DEFINED CMAKE_C_COMPILER_LAUNCHER AND NOT DEFINED
ENV{CMAKE_C_COMPILER_LAUNCHER})
find_program(COMPILER_LAUNCHER NAMES ccache sccache)
if(COMPILER_LAUNCHER)
message(STATUS "Using ${COMPILER_LAUNCHER} as C compiler launcher")
set(CMAKE_C_COMPILER_LAUNCHER
"${COMPILER_LAUNCHER}"
CACHE STRING "" FORCE)
endif()
endif()

if(NOT DEFINED CMAKE_CXX_COMPILER_LAUNCHER AND NOT DEFINED ENV{CMAKE_CXX_COMPILER_LAUNCHER})
find_program(COMPILER_LAUNCHER NAMES ccache sccache)
if(COMPILER_LAUNCHER)
message(STATUS "Using ${COMPILER_LAUNCHER} as C++ compiler launcher")
set(CMAKE_CXX_COMPILER_LAUNCHER "${COMPILER_LAUNCHER}" CACHE STRING "" FORCE)
endif()
if(NOT DEFINED CMAKE_CXX_COMPILER_LAUNCHER
AND NOT DEFINED ENV{CMAKE_CXX_COMPILER_LAUNCHER})
find_program(COMPILER_LAUNCHER NAMES ccache sccache)
if(COMPILER_LAUNCHER)
message(STATUS "Using ${COMPILER_LAUNCHER} as C++ compiler launcher")
set(CMAKE_CXX_COMPILER_LAUNCHER
"${COMPILER_LAUNCHER}"
CACHE STRING "" FORCE)
endif()
endif()
endfunction()
Loading