duckdb-kql 0.0.1.dev1__tar.gz → 0.0.1.dev2__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 (103) hide show
  1. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/CONTRIBUTING.md +11 -1
  2. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/PKG-INFO +8 -4
  3. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/README.md +3 -2
  4. duckdb_kql-0.0.1.dev2/demo/duckdb-kql-demo.ipynb +1339 -0
  5. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/api.md +6 -6
  6. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/cli.md +1 -1
  7. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/public-api-and-typing.md +2 -2
  8. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/getting-started.md +7 -7
  9. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/implementation-plan.md +1 -1
  10. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/kql-support.md +2 -2
  11. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/test-plan.md +2 -2
  12. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/pyproject.toml +26 -6
  13. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/__init__.py +6 -6
  14. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_version.py +2 -2
  15. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/engine.py +23 -19
  16. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/schema.py +1 -1
  17. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/translate/functions.py +1 -1
  18. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_behavior.py +1 -1
  19. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_column_order_and_null_sort.py +9 -9
  20. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_datetime_traps.py +1 -1
  21. duckdb_kql-0.0.1.dev2/tests/test_demo_notebook.py +91 -0
  22. duckdb_kql-0.0.1.dev2/tests/test_devcontainers.py +129 -0
  23. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_docs.py +34 -0
  24. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_dynamic.py +3 -3
  25. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_join.py +1 -1
  26. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_let.py +2 -2
  27. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_null_semantics.py +3 -3
  28. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_query_parameters.py +13 -13
  29. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_range_in_render.py +4 -4
  30. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_summarize.py +1 -1
  31. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_typing.py +3 -3
  32. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_workflows.py +44 -7
  33. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/gen_support_matrix.py +2 -2
  34. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/.gitignore +0 -0
  35. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/CODE_OF_CONDUCT.md +0 -0
  36. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/LICENSE +0 -0
  37. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/SECURITY.md +0 -0
  38. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/THIRD-PARTY-NOTICES.md +0 -0
  39. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/TRANSLATION.md +0 -0
  40. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/ai-cost-strategy.md +0 -0
  41. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/azure-monitor-profile.md +0 -0
  42. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/README.md +0 -0
  43. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/kusto-client-compat.md +0 -0
  44. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/review-2026-08-04.md +0 -0
  45. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/security-and-injection.md +0 -0
  46. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/testing-oracle-and-fixtures.md +0 -0
  47. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/tooling-packaging-ci-docs.md +0 -0
  48. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/code-review/translation-correctness.md +0 -0
  49. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/frequency-scan-results.md +0 -0
  50. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/implementation-options.md +0 -0
  51. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/kql-on-duckdb-landscape.md +0 -0
  52. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/kusto-client.md +0 -0
  53. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/lessons-from-bun-rewrite.md +0 -0
  54. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/licensing.md +0 -0
  55. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/m0-grammar-spike.md +0 -0
  56. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/docs/oracle-harness.md +0 -0
  57. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/grammar/Kql.g4 +0 -0
  58. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/grammar/KqlTokens.g4 +0 -0
  59. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/grammar/UPSTREAM.md +0 -0
  60. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/__main__.py +0 -0
  61. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/Kql.interp +0 -0
  62. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/Kql.tokens +0 -0
  63. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/KqlLexer.interp +0 -0
  64. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/KqlLexer.py +0 -0
  65. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/KqlLexer.tokens +0 -0
  66. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/KqlListener.py +0 -0
  67. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/KqlParser.py +0 -0
  68. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/KqlVisitor.py +0 -0
  69. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/_antlr/__init__.py +0 -0
  70. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/cli.py +0 -0
  71. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/comparison.py +0 -0
  72. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/errors.py +0 -0
  73. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/fixtures.py +0 -0
  74. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/ir.py +0 -0
  75. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/__init__.py +0 -0
  76. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/_models.py +0 -0
  77. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/client.py +0 -0
  78. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/client_request_properties.py +0 -0
  79. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/exceptions.py +0 -0
  80. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/helpers.py +0 -0
  81. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/kusto/response.py +0 -0
  82. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/lower.py +0 -0
  83. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/oracle.py +0 -0
  84. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/params.py +0 -0
  85. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/parser.py +0 -0
  86. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/py.typed +0 -0
  87. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/src/duckdb_kql/translate/__init__.py +0 -0
  88. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/conftest.py +0 -0
  89. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/profiles/azure-monitor.json +0 -0
  90. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_cli.py +0 -0
  91. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_comparison.py +0 -0
  92. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_corpus.py +0 -0
  93. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_fixtures.py +0 -0
  94. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_kusto_client.py +0 -0
  95. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_parse.py +0 -0
  96. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_profile_azure_monitor.py +0 -0
  97. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tests/test_support_matrix.py +0 -0
  98. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/check_profile.py +0 -0
  99. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/frequency_scan.py +0 -0
  100. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/harvest_docs.py +0 -0
  101. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/make_fixtures.py +0 -0
  102. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/regen_expectations.py +0 -0
  103. {duckdb_kql-0.0.1.dev1 → duckdb_kql-0.0.1.dev2}/tools/regen_parser.sh +0 -0
@@ -24,7 +24,7 @@ Docker, DuckDB and the emulator yourself.
24
24
  Before opening a pull request:
25
25
 
26
26
  ```bash
27
- ruff check src tools tests
27
+ ruff check src tools tests demo
28
28
  mypy
29
29
  pytest
30
30
  ```
@@ -87,6 +87,7 @@ report waiting to be filed against someone else's report.
87
87
  | Links in the docs resolve | Including the absolute ones the README uses for PyPI. |
88
88
  | A consumer's type checker sees real types | The package ships `py.typed`, so `Any` in a public signature is a promise broken silently. `tests/test_typing.py` checks from the outside; `mypy` alone cannot. |
89
89
  | The committed parser matches `grammar/Kql.g4` | The generated parser is committed so installs need no Java. |
90
+ | The demo notebook still executes | `demo/` ships with its outputs, so a broken demo keeps looking authoritative. |
90
91
 
91
92
  ## The emulator
92
93
 
@@ -155,6 +156,15 @@ The whole procedure:
155
156
  1. Go to **Releases → Draft a new release**, create the tag `vX.Y.Z` on `main`,
156
157
  click **Generate release notes**, and publish.
157
158
 
159
+ **The tag is used verbatim**, so any PEP 440 version works — `v0.2.0`,
160
+ `v0.2.0rc1`, `v0.0.1.dev1`. This is `version_scheme = "only-version"` in
161
+ `pyproject.toml`, and it is deliberate: `setuptools_scm`'s default invents a
162
+ version for untagged commits by guessing the next release and appending
163
+ `.dev<distance>`, which makes a tag that already ends in `.devN` unbuildable and
164
+ breaks *every commit after it*. Taking the tag as written avoids the guess
165
+ entirely; untagged builds are told apart by a local segment naming the commit
166
+ (`0.0.1.dev1+gfe285ea`) rather than by counting commits.
167
+
158
168
  That is it. The release workflow builds the sdist and wheel, verifies the built
159
169
  version equals the tag, smoke-tests the wheel in a clean environment, uploads to
160
170
  PyPI via [Trusted Publishing][oidc], and attaches the artifacts to the release.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: duckdb-kql
3
- Version: 0.0.1.dev1
3
+ Version: 0.0.1.dev2
4
4
  Summary: Run Kusto KQL queries on DuckDB, from Python
5
5
  Project-URL: Homepage, https://github.com/mmaitre314/duckdb-kql
6
6
  Project-URL: Documentation, https://github.com/mmaitre314/duckdb-kql/blob/main/docs/getting-started.md
@@ -58,7 +58,10 @@ Provides-Extra: arrow
58
58
  Requires-Dist: pyarrow; extra == 'arrow'
59
59
  Provides-Extra: dev
60
60
  Requires-Dist: duckdb>=0.10; extra == 'dev'
61
+ Requires-Dist: ipykernel; extra == 'dev'
61
62
  Requires-Dist: mypy>=1.11; extra == 'dev'
63
+ Requires-Dist: nbclient; extra == 'dev'
64
+ Requires-Dist: nbformat; extra == 'dev'
62
65
  Requires-Dist: pandas; extra == 'dev'
63
66
  Requires-Dist: pandas-stubs; extra == 'dev'
64
67
  Requires-Dist: pyarrow; extra == 'dev'
@@ -163,7 +166,7 @@ runs without a database.
163
166
  import duckdb_kql
164
167
 
165
168
  con = duckdb_kql.connect("analytics.duckdb") # duckdb.connect + TimeZone=UTC
166
- rel = duckdb_kql.sql(con, "StormEvents | summarize n = count() by State")
169
+ rel = duckdb_kql.kql(con, "StormEvents | summarize n = count() by State")
167
170
  rel.fetchall()
168
171
  ```
169
172
 
@@ -198,7 +201,7 @@ values; they are bound as values, so the generated SQL contains no
198
201
  caller-controlled text at all.
199
202
 
200
203
  ```python
201
- duckdb_kql.sql(con, """
204
+ duckdb_kql.kql(con, """
202
205
  declare query_parameters(state:string);
203
206
  StormEvents | where State == state
204
207
  """, {"state": user_input}) # safe whatever user_input contains
@@ -256,6 +259,7 @@ approximation.
256
259
  | [`docs/m0-grammar-spike.md`](https://github.com/mmaitre314/duckdb-kql/blob/main/docs/m0-grammar-spike.md) | Grammar viability result |
257
260
  | [`docs/frequency-scan-results.md`](https://github.com/mmaitre314/duckdb-kql/blob/main/docs/frequency-scan-results.md) | What KQL constructs actually get used |
258
261
  | [`docs/licensing.md`](https://github.com/mmaitre314/duckdb-kql/blob/main/docs/licensing.md) | Third-party licensing review |
262
+ | [demo/](https://github.com/mmaitre314/duckdb-kql/blob/main/demo/duckdb-kql-demo.ipynb) | Notebook tour of all three layers, with outputs |
259
263
  | [CONTRIBUTING.md](https://github.com/mmaitre314/duckdb-kql/blob/main/CONTRIBUTING.md) | How to add a mapping, and when not to |
260
264
  | [SECURITY.md](https://github.com/mmaitre314/duckdb-kql/blob/main/SECURITY.md) | Reporting vulnerabilities; what is in scope |
261
265
  | [Releases](https://github.com/mmaitre314/duckdb-kql/releases) | What changed, and when |
@@ -85,7 +85,7 @@ runs without a database.
85
85
  import duckdb_kql
86
86
 
87
87
  con = duckdb_kql.connect("analytics.duckdb") # duckdb.connect + TimeZone=UTC
88
- rel = duckdb_kql.sql(con, "StormEvents | summarize n = count() by State")
88
+ rel = duckdb_kql.kql(con, "StormEvents | summarize n = count() by State")
89
89
  rel.fetchall()
90
90
  ```
91
91
 
@@ -120,7 +120,7 @@ values; they are bound as values, so the generated SQL contains no
120
120
  caller-controlled text at all.
121
121
 
122
122
  ```python
123
- duckdb_kql.sql(con, """
123
+ duckdb_kql.kql(con, """
124
124
  declare query_parameters(state:string);
125
125
  StormEvents | where State == state
126
126
  """, {"state": user_input}) # safe whatever user_input contains
@@ -178,6 +178,7 @@ approximation.
178
178
  | [`docs/m0-grammar-spike.md`](https://github.com/mmaitre314/duckdb-kql/blob/main/docs/m0-grammar-spike.md) | Grammar viability result |
179
179
  | [`docs/frequency-scan-results.md`](https://github.com/mmaitre314/duckdb-kql/blob/main/docs/frequency-scan-results.md) | What KQL constructs actually get used |
180
180
  | [`docs/licensing.md`](https://github.com/mmaitre314/duckdb-kql/blob/main/docs/licensing.md) | Third-party licensing review |
181
+ | [demo/](https://github.com/mmaitre314/duckdb-kql/blob/main/demo/duckdb-kql-demo.ipynb) | Notebook tour of all three layers, with outputs |
181
182
  | [CONTRIBUTING.md](https://github.com/mmaitre314/duckdb-kql/blob/main/CONTRIBUTING.md) | How to add a mapping, and when not to |
182
183
  | [SECURITY.md](https://github.com/mmaitre314/duckdb-kql/blob/main/SECURITY.md) | Reporting vulnerabilities; what is in scope |
183
184
  | [Releases](https://github.com/mmaitre314/duckdb-kql/releases) | What changed, and when |