bareduckdb 0.20.200a3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. bareduckdb-0.20.200a3/.github/dependabot.yml +16 -0
  2. bareduckdb-0.20.200a3/.github/workflows/README_ACT.md +70 -0
  3. bareduckdb-0.20.200a3/.github/workflows/benchmarks.yml +100 -0
  4. bareduckdb-0.20.200a3/.github/workflows/build_wheels.yml +146 -0
  5. bareduckdb-0.20.200a3/.github/workflows/dev_versions.yml +305 -0
  6. bareduckdb-0.20.200a3/.github/workflows/graalpy.yml +290 -0
  7. bareduckdb-0.20.200a3/.github/workflows/sanitizers.yml +311 -0
  8. bareduckdb-0.20.200a3/.gitignore +251 -0
  9. bareduckdb-0.20.200a3/.gitmodules +5 -0
  10. bareduckdb-0.20.200a3/.pre-commit-config.yaml +53 -0
  11. bareduckdb-0.20.200a3/.sanitizer-thread-suppressions.txt +23 -0
  12. bareduckdb-0.20.200a3/.vscode/settings.json +30 -0
  13. bareduckdb-0.20.200a3/CLAUDE.md +495 -0
  14. bareduckdb-0.20.200a3/CMakeLists.txt +260 -0
  15. bareduckdb-0.20.200a3/LICENSE +21 -0
  16. bareduckdb-0.20.200a3/PKG-INFO +222 -0
  17. bareduckdb-0.20.200a3/README.md +176 -0
  18. bareduckdb-0.20.200a3/README_GRAALPY.md +116 -0
  19. bareduckdb-0.20.200a3/README_PROGRESS.md +194 -0
  20. bareduckdb-0.20.200a3/pyproject.toml +306 -0
  21. bareduckdb-0.20.200a3/run_benchmarks.sh +151 -0
  22. bareduckdb-0.20.200a3/src/bareduckdb/__init__.py +133 -0
  23. bareduckdb-0.20.200a3/src/bareduckdb/_duckdb_fetch.py +113 -0
  24. bareduckdb-0.20.200a3/src/bareduckdb/_duckdb_runtime.py +159 -0
  25. bareduckdb-0.20.200a3/src/bareduckdb/_utils.py +5 -0
  26. bareduckdb-0.20.200a3/src/bareduckdb/_version.py +24 -0
  27. bareduckdb-0.20.200a3/src/bareduckdb/aio/__init__.py +5 -0
  28. bareduckdb-0.20.200a3/src/bareduckdb/aio/async_connection.py +168 -0
  29. bareduckdb-0.20.200a3/src/bareduckdb/capi/__init__.py +0 -0
  30. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/__init__.py +0 -0
  31. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/_probe.pyx +21 -0
  32. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/arrow.pyx +218 -0
  33. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/arrow_c_data.h +73 -0
  34. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/atomics.pxd +72 -0
  35. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/connection.pxd +91 -0
  36. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/connection.pyx +1488 -0
  37. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/duckdb_v2.pxd +992 -0
  38. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/errors.pxd +23 -0
  39. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/errors.pyx +97 -0
  40. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/result.pxd +53 -0
  41. bareduckdb-0.20.200a3/src/bareduckdb/capi/impl/result.pyx +1750 -0
  42. bareduckdb-0.20.200a3/src/bareduckdb/capi/include/HEADER_VERSION.txt +10 -0
  43. bareduckdb-0.20.200a3/src/bareduckdb/capi/include/duckdb_v2.h +12811 -0
  44. bareduckdb-0.20.200a3/src/bareduckdb/compat/__init__.py +10 -0
  45. bareduckdb-0.20.200a3/src/bareduckdb/compat/connection_compat.py +288 -0
  46. bareduckdb-0.20.200a3/src/bareduckdb/compat/module_api.py +63 -0
  47. bareduckdb-0.20.200a3/src/bareduckdb/compat/result_compat.py +515 -0
  48. bareduckdb-0.20.200a3/src/bareduckdb/core/__init__.py +11 -0
  49. bareduckdb-0.20.200a3/src/bareduckdb/core/appender.py +100 -0
  50. bareduckdb-0.20.200a3/src/bareduckdb/core/arrow_timetz.py +117 -0
  51. bareduckdb-0.20.200a3/src/bareduckdb/core/connection_api.py +285 -0
  52. bareduckdb-0.20.200a3/src/bareduckdb/core/connection_base.py +398 -0
  53. bareduckdb-0.20.200a3/src/bareduckdb/functional/__init__.py +28 -0
  54. bareduckdb-0.20.200a3/src/bareduckdb/install_duckdb.py +44 -0
  55. bareduckdb-0.20.200a3/src/bareduckdb/progress.py +82 -0
  56. bareduckdb-0.20.200a3/tests/__init__.py +0 -0
  57. bareduckdb-0.20.200a3/tests/aio/test_aio_basic.py +21 -0
  58. bareduckdb-0.20.200a3/tests/aio/test_aio_cancel.py +33 -0
  59. bareduckdb-0.20.200a3/tests/aio/test_aio_pool.py +126 -0
  60. bareduckdb-0.20.200a3/tests/capi/__init__.py +0 -0
  61. bareduckdb-0.20.200a3/tests/capi/test_arrow.py +782 -0
  62. bareduckdb-0.20.200a3/tests/capi/test_atomics.py +189 -0
  63. bareduckdb-0.20.200a3/tests/capi/test_connection.py +101 -0
  64. bareduckdb-0.20.200a3/tests/capi/test_declarations.py +288 -0
  65. bareduckdb-0.20.200a3/tests/capi/test_duckdb_runtime.py +159 -0
  66. bareduckdb-0.20.200a3/tests/capi/test_errors.py +26 -0
  67. bareduckdb-0.20.200a3/tests/capi/test_freethreading.py +26 -0
  68. bareduckdb-0.20.200a3/tests/capi/test_lifetime.py +125 -0
  69. bareduckdb-0.20.200a3/tests/capi/test_locking.py +190 -0
  70. bareduckdb-0.20.200a3/tests/capi/test_no_runtime_deps.py +34 -0
  71. bareduckdb-0.20.200a3/tests/capi/test_register.py +371 -0
  72. bareduckdb-0.20.200a3/tests/capi/test_register_memory.py +34 -0
  73. bareduckdb-0.20.200a3/tests/capi/test_result.py +669 -0
  74. bareduckdb-0.20.200a3/tests/comparison/__init__.py +0 -0
  75. bareduckdb-0.20.200a3/tests/comparison/conftest.py +336 -0
  76. bareduckdb-0.20.200a3/tests/comparison/test_arrow_duckdb_parquet.py +319 -0
  77. bareduckdb-0.20.200a3/tests/comparison/test_arrow_schema_compatibility.py +70 -0
  78. bareduckdb-0.20.200a3/tests/comparison/test_dbapi.py +217 -0
  79. bareduckdb-0.20.200a3/tests/comparison/test_registration.py +91 -0
  80. bareduckdb-0.20.200a3/tests/compat/conftest.py +36 -0
  81. bareduckdb-0.20.200a3/tests/compat/test_arrow_reader_contract.py +72 -0
  82. bareduckdb-0.20.200a3/tests/compat/test_compat_basic.py +58 -0
  83. bareduckdb-0.20.200a3/tests/compat/test_connection_surface.py +262 -0
  84. bareduckdb-0.20.200a3/tests/compat/test_cursor_shared_database.py +159 -0
  85. bareduckdb-0.20.200a3/tests/compat/test_dbapi_no_pyarrow_import.py +64 -0
  86. bareduckdb-0.20.200a3/tests/compat/test_default_output_type_surfaces.py +42 -0
  87. bareduckdb-0.20.200a3/tests/compat/test_deferred_conversion.py +199 -0
  88. bareduckdb-0.20.200a3/tests/compat/test_install_load_extension.py +121 -0
  89. bareduckdb-0.20.200a3/tests/conftest.py +114 -0
  90. bareduckdb-0.20.200a3/tests/core/test_arrow_corruption_fixes.py +101 -0
  91. bareduckdb-0.20.200a3/tests/core/test_arrow_export_model.py +97 -0
  92. bareduckdb-0.20.200a3/tests/core/test_arrow_in.py +73 -0
  93. bareduckdb-0.20.200a3/tests/core/test_arrow_lossless_conversion.py +89 -0
  94. bareduckdb-0.20.200a3/tests/core/test_arrow_upstream_conformance.py +32 -0
  95. bareduckdb-0.20.200a3/tests/core/test_bignum_roundtrip.py +93 -0
  96. bareduckdb-0.20.200a3/tests/core/test_config.py +68 -0
  97. bareduckdb-0.20.200a3/tests/core/test_connect.py +45 -0
  98. bareduckdb-0.20.200a3/tests/core/test_connection_base_cursor.py +64 -0
  99. bareduckdb-0.20.200a3/tests/core/test_data_kwarg.py +58 -0
  100. bareduckdb-0.20.200a3/tests/core/test_decimal_validation.py +30 -0
  101. bareduckdb-0.20.200a3/tests/core/test_infinite_date_parts.py +28 -0
  102. bareduckdb-0.20.200a3/tests/core/test_interrupt_progress.py +177 -0
  103. bareduckdb-0.20.200a3/tests/core/test_json_ignore_errors.py +98 -0
  104. bareduckdb-0.20.200a3/tests/core/test_module_surface.py +144 -0
  105. bareduckdb-0.20.200a3/tests/core/test_parameters.py +22 -0
  106. bareduckdb-0.20.200a3/tests/core/test_parquet_variant_gzip.py +54 -0
  107. bareduckdb-0.20.200a3/tests/core/test_readonly_query.py +56 -0
  108. bareduckdb-0.20.200a3/tests/core/test_register.py +57 -0
  109. bareduckdb-0.20.200a3/tests/core/test_registration_contract.py +341 -0
  110. bareduckdb-0.20.200a3/tests/core/test_streaming_lifetime.py +99 -0
  111. bareduckdb-0.20.200a3/tests/core/test_timetz_exporter_conformance.py +109 -0
  112. bareduckdb-0.20.200a3/tests/core/test_timetz_utc_opt_in.py +134 -0
  113. bareduckdb-0.20.200a3/tests/core/test_type_roundtrip_matrix.py +651 -0
  114. bareduckdb-0.20.200a3/tests/core/test_uuid_types.py +74 -0
  115. bareduckdb-0.20.200a3/tests/core/test_variant_arrow_unsupported.py +43 -0
  116. bareduckdb-0.20.200a3/tests/dataset/basic/__init__.py +0 -0
  117. bareduckdb-0.20.200a3/tests/dataset/basic/test_dataset_basic.py +115 -0
  118. bareduckdb-0.20.200a3/tests/dataset/basic/test_explain.py +121 -0
  119. bareduckdb-0.20.200a3/tests/dataset/basic/test_join_filter_pushdown.py +82 -0
  120. bareduckdb-0.20.200a3/tests/dataset/basic/test_registration_replacement.py +164 -0
  121. bareduckdb-0.20.200a3/tests/dataset/conftest.py +61 -0
  122. bareduckdb-0.20.200a3/tests/dataset/filter/__init__.py +0 -0
  123. bareduckdb-0.20.200a3/tests/dataset/filter/test_filter_pushdown_types.py +327 -0
  124. bareduckdb-0.20.200a3/tests/dataset/filter/test_nan_filter_pushdown.py +192 -0
  125. bareduckdb-0.20.200a3/tests/dataset/filter/test_pushdown_never_underfilters.py +84 -0
  126. bareduckdb-0.20.200a3/tests/dataset/projection/__init__.py +0 -0
  127. bareduckdb-0.20.200a3/tests/dataset/test_dataset_backend.py +134 -0
  128. bareduckdb-0.20.200a3/tests/downstream/__init__.py +0 -0
  129. bareduckdb-0.20.200a3/tests/downstream/conftest.py +21 -0
  130. bareduckdb-0.20.200a3/tests/downstream/test_ibis.py +298 -0
  131. bareduckdb-0.20.200a3/tests/downstream/test_jupysql.py +178 -0
  132. bareduckdb-0.20.200a3/tests/downstream/test_magic_duckdb.py +177 -0
  133. bareduckdb-0.20.200a3/tests/downstream/test_sqlalchemy.py +285 -0
  134. bareduckdb-0.20.200a3/tests/lazyframe/test_lazyframe_pushdown.py +142 -0
  135. bareduckdb-0.20.200a3/tests/polars/__init__.py +0 -0
  136. bareduckdb-0.20.200a3/tests/polars/test_polars_native.py +252 -0
  137. bareduckdb-0.20.200a3/tests/polars/test_polars_no_pyarrow_import.py +55 -0
  138. bareduckdb-0.20.200a3/tests/polars_only/__init__.py +0 -0
  139. bareduckdb-0.20.200a3/tests/polars_only/test_dbapi_nodep.py +94 -0
  140. bareduckdb-0.20.200a3/tests/polars_only/test_nodep.py +18 -0
  141. bareduckdb-0.20.200a3/tests/polars_only/test_register_nodep.py +70 -0
  142. bareduckdb-0.20.200a3/tests/polars_pushdown/__init__.py +0 -0
  143. bareduckdb-0.20.200a3/tests/polars_pushdown/test_dynamic_predicate_pushdown.py +115 -0
  144. bareduckdb-0.20.200a3/tests/polars_pushdown/test_polars_agg.py +38 -0
  145. bareduckdb-0.20.200a3/tests/polars_pushdown/test_polars_basic.py +39 -0
  146. bareduckdb-0.20.200a3/tests/polars_pushdown/test_polars_filters.py +290 -0
  147. bareduckdb-0.20.200a3/tests/polars_pushdown/test_polars_types.py +51 -0
  148. bareduckdb-0.20.200a3/tests/statistics/conftest.py +5 -0
  149. bareduckdb-0.20.200a3/tests/statistics/test_arrow_statistics.py +273 -0
  150. bareduckdb-0.20.200a3/tests/statistics/test_default_statistics.py +65 -0
  151. bareduckdb-0.20.200a3/tests/statistics/test_pandas_statistics.py +42 -0
  152. bareduckdb-0.20.200a3/tests/statistics/test_polars_statistics.py +59 -0
  153. bareduckdb-0.20.200a3/tests/statistics/test_polars_with_without_stats.py +34 -0
  154. bareduckdb-0.20.200a3/tests/test_pl_lazy.py +183 -0
  155. bareduckdb-0.20.200a3/tests/udtfs/__init__.py +0 -0
  156. bareduckdb-0.20.200a3/tests/udtfs/conftest.py +5 -0
  157. bareduckdb-0.20.200a3/tests/udtfs/test_dml_statements.py +203 -0
  158. bareduckdb-0.20.200a3/tests/udtfs/test_replacement_scan.py +94 -0
  159. bareduckdb-0.20.200a3/tests/udtfs/test_udtf_basic.py +243 -0
  160. bareduckdb-0.20.200a3/tests/udtfs/test_udtf_edge_cases.py +117 -0
  161. bareduckdb-0.20.200a3/tests/vortexdata/__init__.py +0 -0
  162. bareduckdb-0.20.200a3/tests/vortexdata/test_core_vortex.py +32 -0
  163. bareduckdb-0.20.200a3/tools/fetch_duckdb.py +84 -0
  164. bareduckdb-0.20.200a3/typings/polars/__init__.pyi +10 -0
  165. bareduckdb-0.20.200a3/typings/polars/io/__init__.pyi +3 -0
  166. bareduckdb-0.20.200a3/typings/polars/io/plugins.pyi +3 -0
  167. bareduckdb-0.20.200a3/uv.lock +1557 -0
@@ -0,0 +1,16 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "uv" # See documentation for possible values
9
+ directory: "/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
12
+
13
+ - package-ecosystem: "github-actions" # Actions used by .github/workflows
14
+ directory: "/" # Workflows are discovered under .github/workflows
15
+ schedule:
16
+ interval: "weekly"
@@ -0,0 +1,70 @@
1
+ # Running GitHub Actions Locally with nektos/act
2
+
3
+ This guide explains how to run GitHub Actions workflows locally using [nektos/act](https://github.com/nektos/act), which allows you to test workflows before pushing to GitHub.
4
+
5
+ ## Prerequisites
6
+
7
+ - Docker must be installed and running
8
+ - Install the `act` binary, `curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash`
9
+
10
+ ## Quick Start
11
+
12
+ ### List Available Workflows
13
+
14
+ ```bash
15
+ ../act/bin/act --list
16
+ ```
17
+
18
+ ### Run the Dev Versions Workflow
19
+
20
+ To run the complete dev_versions workflow:
21
+
22
+ ```bash
23
+ ../act/bin/act -W .github/workflows/dev_versions.yml --matrix python-version:3.15t --matrix os:ubuntu-latest -P ubuntu-latest=catthehacker/ubuntu:act-24.04 --reuse
24
+ ```
25
+
26
+ `--matrix` values have to exist in the workflow. `dev_versions.yml` currently defines
27
+ `python-version` as `3.14` and `3.15t` only, across `ubuntu-latest`, `macos-latest` and
28
+ `windows-latest`; `3.12` and `3.14t` are not in it. Re-read the matrix before copying a
29
+ command from here.
30
+
31
+ ### 3. Run Specific Jobs
32
+
33
+ `dev_versions.yml` has four jobs: `dev_versions`, `musl`, `graalpy` and `benchmarks`. The
34
+ last two are calls into the reusable workflows `graalpy.yml` and `benchmarks.yml`, and all
35
+ three are chained behind `dev_versions` with `needs:`. To run just the first:
36
+
37
+ ```bash
38
+ ../act/bin/act -W .github/workflows/dev_versions.yml --matrix python-version:3.14 -P ubuntu-latest=catthehacker/ubuntu:act-latest -j dev_versions --artifact-server-path /tmp/artifacts --reuse
39
+ ```
40
+
41
+ ### Run the GraalPy job on its own
42
+
43
+ `graalpy.yml` also accepts `workflow_dispatch`, so it runs standalone without the CPython
44
+ matrix in front of it. The stock runner image has no cmake, so build a derived one first.
45
+
46
+ ```bash
47
+ ../act/bin/act -W .github/workflows/graalpy.yml -j graalpy -P ubuntu-latest=<image with cmake, ninja and build-essential> --reuse
48
+ ```
49
+
50
+ ## Common Options
51
+
52
+ - -n : dry run
53
+ - -v : verbose
54
+ - --reuse
55
+
56
+ ## Known act gaps
57
+
58
+ Three things bite locally that do not bite on a GitHub runner:
59
+
60
+ - **`catthehacker/ubuntu:act-24.04` has no `cmake`**, so any job that invokes CMake outside
61
+ scikit-build-core's own bootstrap dies with `cmake: command not found`. Derive an image:
62
+ `FROM catthehacker/ubuntu:act-24.04` plus
63
+ `apt-get install -y cmake ninja-build build-essential`, then pass it with
64
+ `-P ubuntu-latest=<that image>`.
65
+ - **`--reuse` reuses the container, not the image.** After changing the `-P` image you must
66
+ `docker rm -f` the existing `act-...` container or act silently keeps the old one.
67
+ - **In a git worktree, `setuptools-scm` cannot see `.git`**, because it is a file pointing at
68
+ a gitdir outside the bind mount, and the build fails with "unable to detect version".
69
+ Pass `--env SETUPTOOLS_SCM_PRETEND_VERSION=0.1.dev0`. `actions/checkout` on a real runner
70
+ produces a normal `.git` directory, so this is local-only.
@@ -0,0 +1,100 @@
1
+ name: Benchmarks
2
+
3
+ on:
4
+ workflow_call:
5
+ pull_request:
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ benchmark:
10
+ name: 'Benchmarks'
11
+ runs-on: ubuntu-latest
12
+ timeout-minutes: 60
13
+
14
+ permissions:
15
+ contents: read
16
+ pull-requests: write
17
+
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v7.0.1
21
+ with:
22
+ fetch-depth: 0
23
+ submodules: false
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v7.0.0
27
+ with:
28
+ python-version: '3.12'
29
+
30
+ - name: Install UV
31
+ uses: astral-sh/setup-uv@v10.0.1
32
+ with:
33
+ enable-cache: true
34
+ cache-suffix: -benchmarks
35
+ - name: Check resources
36
+ run: |
37
+ cat /proc/meminfo | head -5
38
+ ulimit -a
39
+ nproc
40
+ # gcc-14/g++-14 are preinstalled, so this only selects them via CC/CXX.
41
+ - name: Setup Compiler
42
+ shell: bash
43
+ run: |
44
+ gcc-14 --version
45
+ g++-14 --version
46
+ echo "CC=gcc-14" >> $GITHUB_ENV
47
+ echo "CXX=g++-14" >> $GITHUB_ENV
48
+
49
+ - name: Verify the lock matches pyproject
50
+ run: uv lock --check
51
+
52
+ - name: Build current repo
53
+ run: uv sync
54
+
55
+ - name: Run benchmarks
56
+ id: bench
57
+ shell: bash
58
+ run: |
59
+ set -u
60
+ status=0
61
+ ./run_benchmarks.sh || status=$?
62
+ echo "status=$status" >> "$GITHUB_OUTPUT"
63
+
64
+ - name: Upload results
65
+ if: always()
66
+ uses: actions/upload-artifact@v7.0.1
67
+ with:
68
+ name: benchmark-results-${{ github.sha }}
69
+ path: benchmark-results/
70
+
71
+ - name: Generate comparison
72
+ id: comparison
73
+ if: always()
74
+ shell: bash
75
+ run: |
76
+ set -u
77
+ status=0
78
+ uv run python tests/benchmarks/compare_results.py benchmark-results > comparison.md || status=$?
79
+ cat comparison.md
80
+ echo "status=$status" >> "$GITHUB_OUTPUT"
81
+
82
+ # Fork PRs get a read-only token, so only comment on same-repo PRs.
83
+ - name: Comment on PR
84
+ if: >-
85
+ always() &&
86
+ github.event_name == 'pull_request' &&
87
+ github.event.pull_request.head.repo.full_name == github.repository
88
+ env:
89
+ GH_TOKEN: ${{ github.token }}
90
+ run: |
91
+ gh pr comment ${{ github.event.pull_request.number }} --body-file comparison.md
92
+
93
+ - name: Fail on benchmark error
94
+ if: >-
95
+ always() &&
96
+ (steps.bench.outputs.status != '0' ||
97
+ steps.comparison.outputs.status != '0')
98
+ run: |
99
+ echo "run_benchmarks.sh exited ${{ steps.bench.outputs.status }}, compare_results.py exited ${{ steps.comparison.outputs.status }}."
100
+ exit 1
@@ -0,0 +1,146 @@
1
+ name: Build Wheels
2
+ permissions:
3
+ contents: read
4
+
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }}
13
+
14
+ jobs:
15
+ build_wheels:
16
+ name: 'Wheel: ${{ matrix.python }}-${{ matrix.platform.cibw_system }}_${{ matrix.platform.arch }}'
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python: [cp312, cp314t, cp315t]
21
+ platform:
22
+ - { os: ubuntu-latest, arch: x86_64, cibw_system: manylinux }
23
+ - { os: ubuntu-24.04-arm, arch: aarch64, cibw_system: manylinux }
24
+ - { os: ubuntu-latest, arch: x86_64, cibw_system: musllinux }
25
+ - { os: ubuntu-24.04-arm, arch: aarch64, cibw_system: musllinux }
26
+ - { os: macos-latest, arch: arm64, cibw_system: macosx }
27
+ - { os: windows-latest, arch: AMD64, cibw_system: win }
28
+ # - { os: macos-13, arch: x86_64, cibw_system: macosx }
29
+ runs-on: ${{ matrix.platform.os }}
30
+
31
+ steps:
32
+ - name: Checkout code
33
+ uses: actions/checkout@v7.0.1
34
+ with:
35
+ fetch-depth: 0
36
+ submodules: false
37
+
38
+ - name: Install Astral UV
39
+ uses: astral-sh/setup-uv@v10.0.1
40
+ with:
41
+ enable-cache: true
42
+ cache-suffix: -${{ matrix.python }}-${{ matrix.platform.cibw_system }}_${{ matrix.platform.arch }}
43
+
44
+ - name: Build and test wheels
45
+ if: matrix.platform.cibw_system != 'musllinux'
46
+ uses: pypa/cibuildwheel@v4.2.1
47
+ env:
48
+ CIBW_TEST_COMMAND: pytest {project}/tests --import-mode=importlib --ignore={project}/tests/experimental --ignore={project}/tests/downstream --ignore={project}/tests/comparison --ignore={project}/tests/benchmarks -v -n auto --cov=bareduckdb --cov-report=term-missing
49
+ CIBW_TEST_EXTRAS: "test"
50
+ CIBW_TEST_REQUIRES: filelock
51
+ CIBW_ARCHS: ${{ matrix.platform.arch }}
52
+ CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform.cibw_system }}_${{ matrix.platform.arch }}
53
+
54
+ - name: Build and test wheels (musllinux)
55
+ if: matrix.platform.cibw_system == 'musllinux'
56
+ uses: pypa/cibuildwheel@v4.2.1
57
+ env:
58
+ CIBW_TEST_COMMAND: |
59
+ set -e
60
+ LIB={project}/src/bareduckdb/_libs/libduckdb.so
61
+ test -f "$LIB" || { echo "ERROR: $LIB missing after build"; exit 1; }
62
+ PKG=$(python -c "import importlib.util as u; print(u.find_spec('bareduckdb').submodule_search_locations[0])")
63
+ mkdir -p "$PKG/_libs"
64
+ cp -f "$LIB" "$PKG/_libs/"
65
+ pytest {project}/tests --import-mode=importlib --ignore={project}/tests/experimental --ignore={project}/tests/downstream --ignore={project}/tests/comparison --ignore={project}/tests/benchmarks -v -n auto --cov=bareduckdb --cov-report=term-missing
66
+ CIBW_TEST_EXTRAS: "test"
67
+ CIBW_TEST_REQUIRES: filelock
68
+ CIBW_ARCHS: ${{ matrix.platform.arch }}
69
+ CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform.cibw_system }}_${{ matrix.platform.arch }}
70
+
71
+ - name: Upload wheel
72
+ uses: actions/upload-artifact@v7.0.1
73
+ with:
74
+ name: wheel-${{ matrix.python }}-${{ matrix.platform.cibw_system }}_${{ matrix.platform.arch }}
75
+ path: wheelhouse/*.whl
76
+ compression-level: 0
77
+
78
+ sdist:
79
+ name: Build sdist
80
+ runs-on: ubuntu-latest
81
+
82
+ steps:
83
+ - name: Checkout code
84
+ uses: actions/checkout@v7.0.1
85
+ with:
86
+ fetch-depth: 0 # setuptools-scm needs the tags to compute a version
87
+ submodules: false
88
+
89
+ - name: Install Astral UV
90
+ uses: astral-sh/setup-uv@v10.0.1
91
+
92
+ - name: Build sdist
93
+ run: uv build --sdist --out-dir dist
94
+
95
+ - name: Upload sdist
96
+ uses: actions/upload-artifact@v7.0.1
97
+ with:
98
+ name: sdist
99
+ path: dist/*.tar.gz
100
+ compression-level: 0
101
+
102
+ # cibuildwheel doesn't support 25.3 yet
103
+ graalpy_wheel:
104
+ name: GraalPy wheel
105
+ uses: ./.github/workflows/graalpy.yml
106
+ permissions:
107
+ contents: read
108
+
109
+ publish-wheels:
110
+ name: Publish Wheels to PyPI
111
+ needs: [build_wheels, graalpy_wheel, sdist]
112
+ runs-on: ubuntu-latest
113
+ if: startsWith(github.ref, 'refs/tags/v')
114
+ permissions:
115
+ id-token: write
116
+
117
+ steps:
118
+ - name: Download wheels
119
+ uses: actions/download-artifact@v8.0.1
120
+ with:
121
+ path: dist/
122
+ pattern: "*wheel*"
123
+ merge-multiple: true
124
+
125
+ - name: Download sdist
126
+ uses: actions/download-artifact@v8.0.1
127
+ with:
128
+ path: dist/
129
+ name: sdist
130
+
131
+ - name: List distributables
132
+ run: |
133
+ ls -lhR dist/
134
+ test -n "$(ls dist/*.tar.gz 2>/dev/null)" || { echo "ERROR: no sdist"; exit 1; }
135
+ test -n "$(ls dist/*graalpy*.whl 2>/dev/null)" || { echo "ERROR: no GraalPy wheel"; exit 1; }
136
+ # Anything else in packages-dir fails the upload
137
+ stray=$(find dist -mindepth 1 ! -name '*.whl' ! -name '*.tar.gz')
138
+ test -z "$stray" || { echo "ERROR: unexpected entries in dist/:"; echo "$stray"; exit 1; }
139
+ # PyPI rejects bare linux_* tags. Fail first.
140
+ bad=$(find dist \( -name '*-linux_x86_64.whl' -o -name '*-linux_aarch64.whl' -o -name '*-linux_i686.whl' \))
141
+ test -z "$bad" || { echo "ERROR: unrepaired linux tag, PyPI will reject:"; echo "$bad"; exit 1; }
142
+
143
+ - name: Publish to PyPI
144
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
145
+ with:
146
+ packages-dir: dist/
@@ -0,0 +1,305 @@
1
+ name: Extensive Tests
2
+
3
+ # This tests is a more extensive suite that's likely more fragile and slower:
4
+ # - parallel thread safety tests
5
+ # - Nightly builds of pyarrow and pandas
6
+ # - Downstream integration tests for common libraries
7
+ # - Ensures pyarrow capsules (via polars) works without importing pyarrow
8
+ on:
9
+ # branches: filters out tag pushes, which otherwise ran the whole matrix again.
10
+ push:
11
+ branches: ['**']
12
+ # schedule:
13
+ # - cron: '0 6 * * *'
14
+ workflow_dispatch:
15
+
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: true
19
+
20
+ jobs:
21
+ dev_versions:
22
+ name: 'Full Tests - Python ${{ matrix.python-version }} - ${{ matrix.os }}'
23
+ runs-on: ${{ matrix.os }}
24
+
25
+ permissions:
26
+ contents: read
27
+
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ include:
32
+ - os: ubuntu-latest
33
+ python-version: '3.14'
34
+ - os: ubuntu-latest
35
+ python-version: '3.15t'
36
+ # - os: macos-latest
37
+ # python-version: '3.12'
38
+ - os: macos-latest
39
+ python-version: '3.15t'
40
+ - os: windows-latest
41
+ python-version: '3.14'
42
+ - os: windows-latest
43
+ python-version: '3.15t'
44
+ steps:
45
+ - name: Checkout code
46
+ uses: actions/checkout@v7.0.1
47
+ with:
48
+ fetch-depth: 0
49
+ submodules: false
50
+
51
+ - name: Set up Python
52
+ uses: actions/setup-python@v7.0.0
53
+ with:
54
+ python-version: ${{ matrix.python-version }}
55
+ allow-prereleases: true
56
+
57
+ - name: Install UV
58
+ uses: astral-sh/setup-uv@v10.0.1
59
+ with:
60
+ enable-cache: true
61
+ cache-suffix: -dev-versions-${{ matrix.python-version }}
62
+
63
+ - name: Setup Compiler
64
+ shell: bash
65
+ run: |
66
+ if [ "${{ runner.os }}" = "Windows" ]; then
67
+ # Windows: MSVC ships with the runner and matches DuckDB's prebuilt DLL
68
+ echo "Using MSVC"
69
+ elif [ "${{ matrix.os }}" = "macos-latest" ]; then
70
+ # macOS: Use AppleClang (default) to match DuckDB's build
71
+ # DuckDB prebuilt binaries are compiled with AppleClang
72
+ echo "Using default AppleClang compiler"
73
+ cc --version
74
+ c++ --version
75
+ else
76
+ # Ubuntu: Install and configure GCC 14
77
+ sudo apt-get update
78
+ sudo apt-get install -y gcc-14 g++-14
79
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100
80
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100
81
+ echo "CC=gcc-14" >> $GITHUB_ENV
82
+ echo "CXX=g++-14" >> $GITHUB_ENV
83
+ gcc --version
84
+ g++ --version
85
+ fi
86
+
87
+ # Scheduled and manual runs re-resolve
88
+ - name: Refresh lock for nightly deps
89
+ if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
90
+ run: uv lock --upgrade
91
+
92
+ - name: Verify the lock matches pyproject
93
+ if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
94
+ run: uv lock --check
95
+
96
+ - name: Build
97
+ shell: bash
98
+ run: |
99
+ # No --no-build: pyyaml ships no cp315 wheel and must build from its sdist
100
+ uv sync --no-install-project
101
+ uv sync --reinstall-package bareduckdb -v
102
+
103
+ - name: Install GIL-only deps (polars, vortex-data)
104
+ shell: bash
105
+ run: |
106
+ if uv run --no-sync python -c "import sysconfig, sys; sys.exit(1 if sysconfig.get_config_var('Py_GIL_DISABLED') else 0)"; then
107
+ uv pip install --group dev-gil --only-binary :all:
108
+ else
109
+ echo "free-threaded interpreter: skipping the dev-gil group"
110
+ fi
111
+
112
+ - name: Run core tests 1
113
+ shell: bash
114
+ run: |
115
+ uv run --no-sync pytest tests --ignore=tests/experimental --ignore=tests/downstream --ignore=tests/comparison --ignore=tests/benchmarks -v -n auto
116
+
117
+ - name: Run parallel thread safety tests
118
+ shell: bash
119
+ run: |
120
+ NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu)
121
+ THREADS=$((NPROC - 1))
122
+ THREADS=$((THREADS < 1 ? 1 : THREADS)) # Ensure at least 1 thread
123
+ # Capped for OOM issues / DEFAULT_TABLE_BATCH_ROWS
124
+ THREADS=$((THREADS > 4 ? 4 : THREADS))
125
+ echo "NPROC: $NPROC"
126
+ echo "THREADS: $THREADS"
127
+ uv run --no-sync pytest tests/ -n 0 --parallel-threads=$THREADS --iterations=5 --tb=short -v -m "not asyncio and not parallel_threads" --ignore=tests/experimental --ignore=tests/comparison --ignore=tests/downstream --ignore=tests/benchmarks --cov=bareduckdb --cov-append
128
+
129
+ - name: Test PyArrow is Optional
130
+ # TODO: 3.15: pola-rs/polars#28347
131
+ if: matrix.python-version != '3.14t' && !startsWith(matrix.python-version, '3.15')
132
+ shell: bash
133
+ run: |
134
+ # Test that bareduckdb works with polars without pyarrow installed
135
+ uv pip uninstall pyarrow
136
+ # Assert polars is importable first, and assert pyarrow is not, otherwise tests skipped
137
+ uv run --no-sync python -c "import polars; print('polars', polars.__version__)"
138
+ uv run --no-sync python -c "
139
+ import importlib.util, sys
140
+ if importlib.util.find_spec('pyarrow') is not None:
141
+ sys.exit('pyarrow is still installed; the uninstall above did not take effect')
142
+ print('pyarrow absent, as intended')
143
+ "
144
+ # -n 0: xdist reports a missing path as "0 items"
145
+ uv run --no-sync pytest tests/polars_only -n 0 -v --cov=bareduckdb --cov-append
146
+ uv pip install pyarrow
147
+
148
+ - name: Run DuckDB comparison tests
149
+ # duckdb has no 3.14t or 3.15 wheels yet.
150
+ if: matrix.python-version != '3.14t' && !startsWith(matrix.python-version, '3.15')
151
+ shell: bash
152
+ run: |
153
+ uv pip install "duckdb==1.5.*" --pre
154
+ uv run --no-sync pytest tests/comparison -v --tb=short --cov=bareduckdb --cov-append
155
+ uv pip uninstall duckdb
156
+
157
+ # - name: Test PyPI DuckDB extensions
158
+ # if: matrix.python-version != '3.14t'
159
+ # shell: bash
160
+ # run: |
161
+ # uv pip install duckdb-extensions==1.4.2 duckdb-extension-httpfs
162
+
163
+ # uv run --no-sync python -c "
164
+ # import bareduckdb
165
+ # conn = bareduckdb.Connection()
166
+
167
+ # conn.load_extension('httpfs')
168
+
169
+ # result = conn.execute('''SELECT * FROM duckdb_extensions() WHERE extension_name = 'httpfs' ''').fetchall()
170
+ # assert len(result) > 0, 'httpfs extension not loaded'
171
+
172
+ # extension_info = result[0]
173
+ # assert extension_info[1] is False
174
+ # assert extension_info[2] is True
175
+
176
+ # conn.close()
177
+ # "
178
+
179
+ # uv pip uninstall duckdb-extensions duckdb-extension-httpfs
180
+
181
+ - name: Run downstream integration tests
182
+ # TODO: No duckdb 3.15
183
+ if: matrix.python-version != '3.14t' && !startsWith(matrix.python-version, '3.15')
184
+ shell: bash
185
+ run: |
186
+ # magic-duckdb
187
+ uv sync --group downstream
188
+
189
+ # Run tests separately to avoid module contamination
190
+ uv run --no-sync pytest tests/downstream/test_sqlalchemy.py tests/downstream/test_magic_duckdb.py -v --cov=bareduckdb --cov-append
191
+ uv run --no-sync pytest tests/downstream/test_jupysql.py -v --cov=bareduckdb --cov-append
192
+
193
+ - name: Generate coverage report
194
+ if: always()
195
+ shell: bash
196
+ run: |
197
+ uv run --no-sync coverage report --show-missing
198
+
199
+ - name: Count Lines of Code (cloc)
200
+ uses: djdefi/cloc-action@d4a7e15e4ff5219692f79ba71685af08955dcfc0 # 6
201
+ if: matrix.os == 'ubuntu-latest'
202
+ with:
203
+ options: --exclude-dir=tests,external,.git,.github,benchmarks,notebooks,include
204
+
205
+ - name: Upload test results
206
+ if: always()
207
+ uses: actions/upload-artifact@v7.0.1
208
+ with:
209
+ name: dev-versions-test-results-${{ matrix.python-version }}
210
+ path: |
211
+ .pytest_cache/
212
+ retention-days: 7
213
+
214
+ musl:
215
+ name: 'Musl Tests - ${{ matrix.python }} - musllinux_1_2'
216
+ runs-on: ubuntu-latest
217
+ needs: dev_versions
218
+
219
+ permissions:
220
+ contents: read
221
+
222
+ strategy:
223
+ fail-fast: false
224
+ matrix:
225
+ include:
226
+ - { python: cp314, pydir: cp314-cp314 }
227
+ - { python: cp315t, pydir: cp315-cp315t }
228
+
229
+ steps:
230
+ # Checkout on the glibc host
231
+ - name: Checkout code
232
+ uses: actions/checkout@v7.0.1
233
+ with:
234
+ fetch-depth: 0
235
+ submodules: false
236
+
237
+ - name: Cache uv downloads
238
+ uses: actions/cache@v6.1.0
239
+ with:
240
+ path: .uv-cache
241
+ key: uv-musl-${{ matrix.python }}-${{ hashFiles('uv.lock') }}
242
+ restore-keys: uv-musl-${{ matrix.python }}-
243
+
244
+ - name: Build and test in musllinux_1_2
245
+ shell: bash
246
+ # Same image cibuildwheel uses
247
+ run: |
248
+ docker run --rm -v "$PWD:/build" -w /build \
249
+ -e UV_CACHE_DIR=/build/.uv-cache \
250
+ quay.io/pypa/musllinux_1_2_x86_64 sh -c '
251
+ set -e
252
+ PY=/opt/python/${{ matrix.pydir }}/bin/python
253
+ test -x "$PY" || { echo "ERROR: no interpreter at $PY"; ls /opt/python; exit 1; }
254
+ gcc --version | head -1
255
+ export UV_PYTHON="$PY"
256
+ # TODO(cp315): delete this block once pandas/pyarrow ship stable cp315 wheels
257
+ if [ "${{ matrix.python }}" = cp315t ]; then
258
+ uv lock --upgrade-package pandas --upgrade-package pyarrow
259
+ fi
260
+ uv sync --no-default-groups --extra test --reinstall-package bareduckdb
261
+
262
+ # libduckdb must be the musl build, not glibc
263
+ LIB=$(find src/bareduckdb/_libs -name "libduckdb.so")
264
+ readelf -d "$LIB" | grep -q "libc.musl" || { echo "ERROR: $LIB is not musl-linked"; exit 1; }
265
+ echo "OK: $LIB is musl-linked"
266
+
267
+ SRC_DIR=$(cd "$(dirname "$LIB")" && pwd)
268
+ # cd+pwd rather than realpath -m: busybox realpath has no -m.
269
+ DEST_DIR=$(uv run --no-sync python -c "import os, sysconfig; print(os.path.join(sysconfig.get_paths()[\"platlib\"], \"bareduckdb\", \"_libs\"))")
270
+ if [ "$DEST_DIR" != "$SRC_DIR" ]; then
271
+ mkdir -p "$DEST_DIR"
272
+ # Hard link, so musl dedupes it by inode against the preloaded copy and maps
273
+ # DuckDB once; cp is the cross-device fallback.
274
+ ln -f "$SRC_DIR/libduckdb.so" "$DEST_DIR/libduckdb.so" 2>/dev/null \
275
+ || cp -f "$SRC_DIR/libduckdb.so" "$DEST_DIR/"
276
+ echo "Linked $SRC_DIR/libduckdb.so into $DEST_DIR"
277
+ fi
278
+
279
+ uv run --no-sync pytest tests --ignore=tests/experimental --ignore=tests/downstream \
280
+ --ignore=tests/comparison --ignore=tests/benchmarks \
281
+ -o addopts="" -q -n auto
282
+
283
+ # Drop the pre-built wheels that are cheaper to refetch than to store.
284
+ uv cache prune --ci
285
+ '
286
+
287
+ - name: Make the uv cache readable by the runner
288
+ if: always()
289
+ shell: bash
290
+ run: sudo chown -R "$(id -u):$(id -g)" .uv-cache || true
291
+
292
+ graalpy:
293
+ name: GraalPy
294
+ needs: dev_versions
295
+ uses: ./.github/workflows/graalpy.yml
296
+ permissions:
297
+ contents: read
298
+
299
+ benchmarks:
300
+ name: Benchmarks
301
+ needs: dev_versions
302
+ uses: ./.github/workflows/benchmarks.yml
303
+ permissions:
304
+ contents: read
305
+ pull-requests: write