dirsql 0.4.35__tar.gz → 0.4.37__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 (227) hide show
  1. {dirsql-0.4.35 → dirsql-0.4.37}/Cargo.lock +2 -2
  2. {dirsql-0.4.35 → dirsql-0.4.37}/PKG-INFO +1 -1
  3. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/_async.py +1 -1
  4. dirsql-0.4.37/dirsql/cli/config_paths_from_argv.py +28 -0
  5. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/resolve_config_extensions.py +7 -30
  6. dirsql-0.4.37/dirsql/has_bare_name.py +14 -0
  7. dirsql-0.4.37/dirsql/is_bare_name.py +14 -0
  8. dirsql-0.4.37/dirsql/load_extension_entries.py +28 -0
  9. dirsql-0.4.37/dirsql/platform_patterns.py +12 -0
  10. dirsql-0.4.37/dirsql/resolve_config_extensions.py +39 -0
  11. dirsql-0.4.37/dirsql/resolve_configs_extension_specs.py +36 -0
  12. dirsql-0.4.37/dirsql/resolve_entries.py +20 -0
  13. dirsql-0.4.37/dirsql/resolve_extension.py +38 -0
  14. dirsql-0.4.37/dirsql/resolve_package.py +53 -0
  15. dirsql-0.4.37/dirsql/toml_module.py +21 -0
  16. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/Cargo.toml +1 -1
  17. dirsql-0.4.37/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +3 -0
  18. dirsql-0.4.37/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +3 -0
  19. dirsql-0.4.37/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +3 -0
  20. dirsql-0.4.37/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +3 -0
  21. dirsql-0.4.37/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +7 -0
  22. dirsql-0.4.37/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +7 -0
  23. dirsql-0.4.37/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +7 -0
  24. dirsql-0.4.37/packages/python/e2e-attestations/claude-tackle-1042-py12.json +7 -0
  25. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/testing-conventions.toml +1 -1
  26. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/Cargo.toml +1 -1
  27. dirsql-0.4.35/dirsql/resolve_config_extensions.py +0 -126
  28. dirsql-0.4.35/dirsql/resolve_extension.py +0 -101
  29. {dirsql-0.4.35 → dirsql-0.4.37}/Cargo.toml +0 -0
  30. {dirsql-0.4.35 → dirsql-0.4.37}/README.md +0 -0
  31. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/__init__.py +0 -0
  32. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/_dirsql.pyi +0 -0
  33. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/__init__.py +0 -0
  34. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/discover_plugins/__init__.py +0 -0
  35. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  36. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  37. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  38. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
  39. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  40. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/cli/main.py +0 -0
  41. {dirsql-0.4.35 → dirsql-0.4.37}/dirsql/py.typed +0 -0
  42. {dirsql-0.4.35 → dirsql-0.4.37}/docs/.claude/CLAUDE.md +0 -0
  43. {dirsql-0.4.35 → dirsql-0.4.37}/docs/.vitepress/config.ts +0 -0
  44. {dirsql-0.4.35 → dirsql-0.4.37}/docs/.vitepress/theme/index.ts +0 -0
  45. {dirsql-0.4.35 → dirsql-0.4.37}/docs/.vitepress/theme/lang.ts +0 -0
  46. {dirsql-0.4.35 → dirsql-0.4.37}/docs/AGENTS.md +0 -0
  47. {dirsql-0.4.35 → dirsql-0.4.37}/docs/explanation.md +0 -0
  48. {dirsql-0.4.35 → dirsql-0.4.37}/docs/getting-started.md +0 -0
  49. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/columns-from-paths.md +0 -0
  50. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/define-tables.md +0 -0
  51. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/embed.md +0 -0
  52. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/extract-from-contents.md +0 -0
  53. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/load-extension.md +0 -0
  54. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/parse-files-into-columns.md +0 -0
  55. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/persist.md +0 -0
  56. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/query-json.md +0 -0
  57. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/query-without-config.md +0 -0
  58. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/react-to-changes.md +0 -0
  59. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/search-by-meaning.md +0 -0
  60. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/search-indexes.md +0 -0
  61. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/skip-files.md +0 -0
  62. {dirsql-0.4.35 → dirsql-0.4.37}/docs/howto/write-a-plugin.md +0 -0
  63. {dirsql-0.4.35 → dirsql-0.4.37}/docs/index.md +0 -0
  64. {dirsql-0.4.35 → dirsql-0.4.37}/docs/package.json +0 -0
  65. {dirsql-0.4.35 → dirsql-0.4.37}/docs/plugins.md +0 -0
  66. {dirsql-0.4.35 → dirsql-0.4.37}/docs/pnpm-lock.yaml +0 -0
  67. {dirsql-0.4.35 → dirsql-0.4.37}/docs/pnpm-workspace.yaml +0 -0
  68. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/cli.md +0 -0
  69. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/columns.md +0 -0
  70. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/config.md +0 -0
  71. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/hooks.md +0 -0
  72. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/http-api.md +0 -0
  73. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/path-tables.md +0 -0
  74. {dirsql-0.4.35 → dirsql-0.4.37}/docs/reference/sdk.md +0 -0
  75. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/CHANGELOG.md +0 -0
  76. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/MIGRATIONS.md +0 -0
  77. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/README.md +0 -0
  78. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  79. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  80. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  81. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  82. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  83. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  84. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  85. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  86. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  87. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  88. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  89. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  90. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  91. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  92. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  93. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  94. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  95. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  96. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  97. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/changelog.d/README.md +0 -0
  98. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/conftest.py +0 -0
  99. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/.claude/CLAUDE.md +0 -0
  100. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/.vitepress/config.ts +0 -0
  101. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  102. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  103. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/AGENTS.md +0 -0
  104. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/explanation.md +0 -0
  105. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/getting-started.md +0 -0
  106. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/columns-from-paths.md +0 -0
  107. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/define-tables.md +0 -0
  108. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/embed.md +0 -0
  109. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/extract-from-contents.md +0 -0
  110. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/load-extension.md +0 -0
  111. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  112. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/persist.md +0 -0
  113. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/query-json.md +0 -0
  114. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/query-without-config.md +0 -0
  115. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/react-to-changes.md +0 -0
  116. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/search-by-meaning.md +0 -0
  117. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/search-indexes.md +0 -0
  118. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/skip-files.md +0 -0
  119. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/howto/write-a-plugin.md +0 -0
  120. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/index.md +0 -0
  121. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/package.json +0 -0
  122. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/plugins.md +0 -0
  123. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/pnpm-lock.yaml +0 -0
  124. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/pnpm-workspace.yaml +0 -0
  125. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/cli.md +0 -0
  126. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/columns.md +0 -0
  127. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/config.md +0 -0
  128. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/hooks.md +0 -0
  129. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/http-api.md +0 -0
  130. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/path-tables.md +0 -0
  131. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/docs/reference/sdk.md +0 -0
  132. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  133. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  134. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  135. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  136. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  137. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  138. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  139. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  140. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  141. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  142. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  143. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  144. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  145. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  146. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  147. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  148. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  149. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  150. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  151. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  152. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  153. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  154. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  155. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  156. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  157. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/migrations.d/README.md +0 -0
  158. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/src/lib.rs +0 -0
  159. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/__init__.py +0 -0
  160. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/conftest.py +0 -0
  161. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/e2e/__init__.py +0 -0
  162. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  163. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  164. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/integration/__init__.py +0 -0
  165. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/integration/binding/__init__.py +0 -0
  166. {dirsql-0.4.35 → dirsql-0.4.37}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  167. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/CHANGELOG.md +0 -0
  168. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/MIGRATIONS.md +0 -0
  169. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/README.md +0 -0
  170. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/benches/db_bench.rs +0 -0
  171. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/benches/differ_bench.rs +0 -0
  172. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/benches/matcher_bench.rs +0 -0
  173. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/benches/scanner_bench.rs +0 -0
  174. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/explanation.md +0 -0
  175. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/getting-started.md +0 -0
  176. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  177. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/define-tables.md +0 -0
  178. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/embed.md +0 -0
  179. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  180. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/load-extension.md +0 -0
  181. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  182. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/persist.md +0 -0
  183. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/query-json.md +0 -0
  184. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/query-without-config.md +0 -0
  185. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/react-to-changes.md +0 -0
  186. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  187. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/search-indexes.md +0 -0
  188. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/skip-files.md +0 -0
  189. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  190. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/index.md +0 -0
  191. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/plugins.md +0 -0
  192. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/cli.md +0 -0
  193. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/columns.md +0 -0
  194. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/config.md +0 -0
  195. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/hooks.md +0 -0
  196. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/http-api.md +0 -0
  197. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/path-tables.md +0 -0
  198. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/docs/reference/sdk.md +0 -0
  199. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/bin/dirsql.rs +0 -0
  200. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/execute.rs +0 -0
  201. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/init.rs +0 -0
  202. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/mod.rs +0 -0
  203. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/repl.rs +0 -0
  204. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/router.rs +0 -0
  205. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/run.rs +0 -0
  206. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/serialize.rs +0 -0
  207. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/server.rs +0 -0
  208. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/cli/table.rs +0 -0
  209. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/command.rs +0 -0
  210. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/config.rs +0 -0
  211. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/db.rs +0 -0
  212. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/default_config.toml +0 -0
  213. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/differ.rs +0 -0
  214. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/functions.rs +0 -0
  215. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/infer.rs +0 -0
  216. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/lib.rs +0 -0
  217. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/matcher.rs +0 -0
  218. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/parsed_cache.rs +0 -0
  219. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/parsed_vtab.rs +0 -0
  220. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/path_table.rs +0 -0
  221. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/persist.rs +0 -0
  222. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/progress.rs +0 -0
  223. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/scanner.rs +0 -0
  224. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/sql_literal.rs +0 -0
  225. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/vtab.rs +0 -0
  226. {dirsql-0.4.35 → dirsql-0.4.37}/packages/rust/src/watcher.rs +0 -0
  227. {dirsql-0.4.35 → dirsql-0.4.37}/pyproject.toml +0 -0
@@ -540,7 +540,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
540
540
 
541
541
  [[package]]
542
542
  name = "dirsql"
543
- version = "0.4.35"
543
+ version = "0.4.37"
544
544
  dependencies = [
545
545
  "assert_cmd",
546
546
  "axum",
@@ -583,7 +583,7 @@ dependencies = [
583
583
 
584
584
  [[package]]
585
585
  name = "dirsql-py-ext"
586
- version = "0.4.35"
586
+ version = "0.4.37"
587
587
  dependencies = [
588
588
  "dirsql",
589
589
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.35
3
+ Version: 0.4.37
4
4
  Requires-Dist: tomli>=2 ; python_full_version < '3.11'
5
5
  Requires-Dist: bin-shim>=0.1
6
6
  Summary: Ephemeral SQL index over a local directory
@@ -4,7 +4,7 @@ import asyncio
4
4
  import os
5
5
 
6
6
  from dirsql._dirsql import DirSQL as _RustDirSQL
7
- from dirsql.resolve_config_extensions import resolve_configs_extension_specs
7
+ from dirsql.resolve_configs_extension_specs import resolve_configs_extension_specs
8
8
  from dirsql.resolve_extension import resolve_extension_path
9
9
 
10
10
 
@@ -0,0 +1,28 @@
1
+ """Config-path extraction from the launcher's argv.
2
+
3
+ Every config flag occurrence counts -- ``-c``/``--config`` are repeatable,
4
+ and plugin discovery injects fragments as additional ``-c`` flags -- so the
5
+ scan collects them all, in argv order.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+
11
+ def config_paths_from_argv(argv: list[str]) -> list[str]:
12
+ """Every config value in argv, in order (``--config X``, ``--config=X``,
13
+ ``-c X``, ``-c=X``, ``-cX``), or the default when none are given."""
14
+ paths: list[str] = []
15
+ i = 0
16
+ while i < len(argv):
17
+ a = argv[i]
18
+ if a == "--config" or a == "-c":
19
+ # A bare trailing flag (no following value) yields "".
20
+ paths.append(next(iter(argv[i + 1 :]), ""))
21
+ i += 2
22
+ continue
23
+ if a.startswith("--config="):
24
+ paths.append(a[len("--config=") :])
25
+ elif a.startswith("-c"):
26
+ paths.append(a[len("-c") :].removeprefix("="))
27
+ i += 1
28
+ return paths or ["./.dirsql.toml"]
@@ -3,14 +3,10 @@
3
3
  The compiled ``dirsql`` binary loads a config's extensions literally -- it
4
4
  has no ``importlib``, so it cannot resolve a bare **package name**. When any
5
5
  TOML config in argv names an extension by package name, the shared SDK
6
- resolver (:mod:`dirsql.resolve_config_extensions`) resolves every config's
7
- extensions and this launcher passes the resolved literal paths to the binary
8
- via repeatable ``--extension`` flags; the binary then loads those and ignores
9
- the configs' own extension entries.
10
-
11
- Every config flag occurrence counts -- ``-c``/``--config`` are repeatable,
12
- and plugin discovery injects fragments as additional ``-c`` flags -- so the
13
- scan collects them all, in argv order.
6
+ resolver (:mod:`dirsql.resolve_configs_extension_specs`) resolves every
7
+ config's extensions and this launcher passes the resolved literal paths to
8
+ the binary via repeatable ``--extension`` flags; the binary then loads those
9
+ and ignores the configs' own extension entries.
14
10
 
15
11
  Native-language configs (``.py`` / ``.js`` / ``.mjs`` / ``.cjs``) are untouched:
16
12
  the binary dispatches those to ``dirsql interpret``, whose handshake already
@@ -19,33 +15,14 @@ carries resolved paths.
19
15
 
20
16
  from __future__ import annotations
21
17
 
22
- from ..resolve_config_extensions import resolve_configs_extension_specs
18
+ from ..resolve_configs_extension_specs import resolve_configs_extension_specs
19
+ from .config_paths_from_argv import config_paths_from_argv
23
20
 
24
21
  # Config extensions the binary dispatches to `dirsql interpret`; never
25
22
  # pre-resolved here (that path resolves via the handshake).
26
23
  _NATIVE_SUFFIXES = (".py", ".js", ".mjs", ".cjs")
27
24
 
28
25
 
29
- def _config_paths_from_argv(argv: list[str]) -> list[str]:
30
- """Every config value in argv, in order (``--config X``, ``--config=X``,
31
- ``-c X``, ``-c=X``, ``-cX``), or the default when none are given."""
32
- paths: list[str] = []
33
- i = 0
34
- while i < len(argv):
35
- a = argv[i]
36
- if a == "--config" or a == "-c":
37
- # A bare trailing flag (no following value) yields "".
38
- paths.append(next(iter(argv[i + 1 :]), ""))
39
- i += 2
40
- continue
41
- if a.startswith("--config="):
42
- paths.append(a[len("--config=") :])
43
- elif a.startswith("-c"):
44
- paths.append(a[len("-c") :].removeprefix("="))
45
- i += 1
46
- return paths or ["./.dirsql.toml"]
47
-
48
-
49
26
  def with_resolved_extensions(argv: list[str]) -> list[str]:
50
27
  """Return ``argv`` plus ``--extension`` flags when a TOML config names an
51
28
  extension by package name; otherwise return ``argv`` unchanged. Raises if a
@@ -53,7 +30,7 @@ def with_resolved_extensions(argv: list[str]) -> list[str]:
53
30
  if argv and argv[0] == "init":
54
31
  return argv
55
32
  config_paths = [
56
- p for p in _config_paths_from_argv(argv) if not p.endswith(_NATIVE_SUFFIXES)
33
+ p for p in config_paths_from_argv(argv) if not p.endswith(_NATIVE_SUFFIXES)
57
34
  ]
58
35
  if not config_paths:
59
36
  return argv
@@ -0,0 +1,14 @@
1
+ """Whether any of a config's extension entries names a package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .is_bare_name import is_bare_name
6
+
7
+
8
+ def _has_bare_name(entries):
9
+ return any(
10
+ isinstance(e, dict)
11
+ and isinstance(e.get("path"), str)
12
+ and is_bare_name(e["path"])
13
+ for e in entries
14
+ )
@@ -0,0 +1,14 @@
1
+ """Whether an extension ``path`` names a package rather than a file."""
2
+
3
+ import os
4
+
5
+ # Suffixes that mark a value as "already a file path", so package resolution
6
+ # is never attempted.
7
+ _LOADABLE_SUFFIXES = (".so", ".dylib", ".dll", ".pyd")
8
+
9
+
10
+ def is_bare_name(path):
11
+ """True when ``path`` is a bare package name rather than a file path."""
12
+ if os.sep in path or (os.altsep and os.altsep in path):
13
+ return False
14
+ return not path.endswith(_LOADABLE_SUFFIXES)
@@ -0,0 +1,28 @@
1
+ """Reading one TOML config's ``[[dirsql.extension]]`` array off disk."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ from .toml_module import _toml
8
+
9
+
10
+ def _load_extension_entries(config_path):
11
+ """Return ``(entries, base_dir)`` for a config's ``[[dirsql.extension]]``.
12
+
13
+ ``None`` when the config is missing, unreadable/malformed, or declares no
14
+ extension array -- the caller should leave such configs to the core.
15
+ """
16
+ if not os.path.isfile(config_path):
17
+ return None
18
+ try:
19
+ with open(config_path, "rb") as f:
20
+ doc = _toml.load(f)
21
+ except (OSError, _toml.TOMLDecodeError):
22
+ # Leave a malformed / unreadable config for the core to report.
23
+ return None
24
+
25
+ entries = (doc.get("dirsql") or {}).get("extension")
26
+ if not isinstance(entries, list):
27
+ return None
28
+ return entries, os.path.dirname(os.path.abspath(config_path))
@@ -0,0 +1,12 @@
1
+ """The loadable-file glob pattern(s) the running platform uses."""
2
+
3
+ import sys
4
+
5
+
6
+ def _platform_patterns():
7
+ """Loadable-file glob(s) for the current platform."""
8
+ if sys.platform == "darwin":
9
+ return ("*.dylib",)
10
+ if sys.platform == "win32":
11
+ return ("*.dll", "*.pyd")
12
+ return ("*.so",)
@@ -0,0 +1,39 @@
1
+ """SDK-side resolution of a TOML config's ``[[dirsql.extension]]`` entries.
2
+
3
+ The Rust core loads a config's extensions literally -- it has no
4
+ ``importlib``, so it cannot resolve a bare **package name**. When a TOML
5
+ config names an extension by package name, the SDK resolves every one of its
6
+ extensions here, hands the core the resolved literal paths, and suppresses
7
+ the core's own config-extension loading (``suppress_config_extensions``) so
8
+ the config's entries are not loaded a second time.
9
+
10
+ Shared by the ``DirSQL`` constructor (``config=`` path) and the CLI launcher
11
+ (which converts the resolved specs into ``--extension`` flags), both of which
12
+ reach it through :mod:`dirsql.resolve_configs_extension_specs`.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from .has_bare_name import _has_bare_name
18
+ from .load_extension_entries import _load_extension_entries
19
+ from .resolve_entries import _resolve_entries
20
+
21
+
22
+ def resolve_config_extension_specs(config_path):
23
+ """Resolve a TOML config's ``[[dirsql.extension]]`` entries to literal paths.
24
+
25
+ Returns a list of ``{"path", "entrypoint"}`` dicts -- every entry resolved
26
+ via :func:`resolve_extension_path` against the config file's parent
27
+ directory -- when at least one entry's ``path`` is a bare package name.
28
+ Returns ``None`` when the caller should not intervene: the config is
29
+ missing, malformed, declares no extensions, or uses only literal paths --
30
+ leaving the core's own loading (and error reporting) untouched. Raises if
31
+ a package name cannot be resolved.
32
+ """
33
+ loaded = _load_extension_entries(config_path)
34
+ if loaded is None:
35
+ return None
36
+ entries, base = loaded
37
+ if not _has_bare_name(entries):
38
+ return None
39
+ return _resolve_entries(entries, base)
@@ -0,0 +1,36 @@
1
+ """Resolution of several TOML configs' ``[[dirsql.extension]]`` entries, in order.
2
+
3
+ The plural counterpart to :func:`dirsql.resolve_config_extensions
4
+ .resolve_config_extension_specs`, used by the SDK constructor and the CLI
5
+ launcher when argv carries more than one ``--config``.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from .has_bare_name import _has_bare_name
11
+ from .load_extension_entries import _load_extension_entries
12
+ from .resolve_entries import _resolve_entries
13
+
14
+
15
+ def resolve_configs_extension_specs(config_paths):
16
+ """Resolve the ``[[dirsql.extension]]`` entries of several configs, in order.
17
+
18
+ The SDK intervenes for the whole set only when **some** config names an
19
+ extension by bare package name (the core can resolve neither package names
20
+ nor -- once globally suppressed -- the literal entries of the other
21
+ configs). When it intervenes it resolves **every** config's entries, each
22
+ against that config's own parent directory, concatenated in ``config_paths``
23
+ order; the caller suppresses the core's config-extension loading and passes
24
+ the resolved list. Returns ``None`` when no config uses a package name,
25
+ leaving every config's loading to the core.
26
+ """
27
+ loaded = [_load_extension_entries(p) for p in config_paths]
28
+ if not any(item is not None and _has_bare_name(item[0]) for item in loaded):
29
+ return None
30
+ specs = []
31
+ for item in loaded:
32
+ if item is None:
33
+ continue
34
+ entries, base = item
35
+ specs.extend(_resolve_entries(entries, base))
36
+ return specs
@@ -0,0 +1,20 @@
1
+ """Resolution of one config's ``[[dirsql.extension]]`` entries to literal paths."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .resolve_extension import resolve_extension_path
6
+
7
+
8
+ def _resolve_entries(entries, base):
9
+ specs = []
10
+ for e in entries:
11
+ entrypoint = e.get("entrypoint")
12
+ specs.append(
13
+ {
14
+ "path": resolve_extension_path(
15
+ e["path"], base=base, resolve_relative=True
16
+ ),
17
+ "entrypoint": entrypoint if isinstance(entrypoint, str) else None,
18
+ }
19
+ )
20
+ return specs
@@ -0,0 +1,38 @@
1
+ """Resolve an extension entry's ``path`` to a concrete loadable file.
2
+
3
+ Resolution is an ordered probe (file-first, then package), so only a bare
4
+ package name reaches the package machinery:
5
+
6
+ 1. **Path-looking** (contains a separator, or ends in ``.so`` / ``.dylib`` /
7
+ ``.dll`` / ``.pyd``) -- returned as a file path: made absolute against
8
+ ``base`` when ``resolve_relative`` is set (config-file entries), else
9
+ verbatim (programmatic entries).
10
+ 2. **Bare name** -- a same-named local file under ``base`` *shadows* the
11
+ package; otherwise the package dir is located via
12
+ :func:`importlib.util.find_spec` and the current platform's loadable is
13
+ globbed from inside it.
14
+ """
15
+
16
+ import os
17
+
18
+ from .is_bare_name import is_bare_name
19
+ from .resolve_package import _resolve_package
20
+
21
+
22
+ def resolve_extension_path(path, base, resolve_relative):
23
+ """Resolve an extension ``path`` to a concrete file.
24
+
25
+ ``base`` is the directory a relative path and the bare-name shadow probe
26
+ resolve against (a config file's parent dir, or the cwd for programmatic
27
+ entries). ``resolve_relative`` makes a relative path-looking value absolute
28
+ against ``base`` (config-file semantics); when false it is returned verbatim
29
+ (programmatic semantics).
30
+ """
31
+ if not is_bare_name(path):
32
+ if resolve_relative and not os.path.isabs(path):
33
+ return os.path.join(base, path)
34
+ return path
35
+ local = os.path.join(base, path)
36
+ if os.path.isfile(local):
37
+ return local
38
+ return _resolve_package(path)
@@ -0,0 +1,53 @@
1
+ """Location of an extension package's loadable file for this platform.
2
+
3
+ Zero matches and multiple matches are both hard errors -- the caller must
4
+ disambiguate with a literal path.
5
+ """
6
+
7
+ import glob as _glob
8
+ import importlib.util
9
+ import os
10
+
11
+ from .platform_patterns import _platform_patterns
12
+
13
+
14
+ def _resolve_package(name):
15
+ """Locate ``name``'s package dir and glob its platform loadable file."""
16
+ try:
17
+ spec = importlib.util.find_spec(name)
18
+ except (ImportError, ValueError) as exc:
19
+ raise ValueError(
20
+ f"could not resolve extension package {name!r}: {exc}"
21
+ ) from exc
22
+ if spec is None:
23
+ raise ValueError(f"could not resolve extension package {name!r}: not installed")
24
+
25
+ dirs = list(spec.submodule_search_locations or [])
26
+ if not dirs and spec.origin and spec.origin not in ("built-in", "frozen"):
27
+ dirs.append(os.path.dirname(spec.origin))
28
+ if not dirs:
29
+ raise ValueError(
30
+ f"could not resolve extension package {name!r}: no package directory"
31
+ )
32
+
33
+ patterns = _platform_patterns()
34
+ matches = set()
35
+ for d in dirs:
36
+ for pat in patterns:
37
+ matches.update(_glob.glob(os.path.join(d, "**", pat), recursive=True))
38
+ found = sorted(matches)
39
+
40
+ try:
41
+ (single,) = found
42
+ except ValueError:
43
+ pat_desc = " / ".join(patterns)
44
+ if not found:
45
+ raise ValueError(
46
+ f"no loadable extension file ({pat_desc}) found in package "
47
+ f"{name!r} (searched {', '.join(dirs)})"
48
+ ) from None
49
+ raise ValueError(
50
+ f"multiple loadable extension files found in package {name!r}: "
51
+ f"{', '.join(found)}; disambiguate with a literal path"
52
+ ) from None
53
+ return single
@@ -0,0 +1,21 @@
1
+ """The TOML parser this interpreter reads ``.dirsql.toml`` files with."""
2
+
3
+ import sys
4
+ from importlib import import_module
5
+
6
+
7
+ def _load_toml_module():
8
+ """Return the TOML parser module for the running interpreter.
9
+
10
+ ``tomllib`` is stdlib only on 3.11+; on 3.10 the ``tomli`` backport it was
11
+ derived from (a version-gated dependency) provides the same surface.
12
+ Imported by name so a unit test can exercise both arms on any
13
+ interpreter -- a literal ``import tomllib`` is unreachable on 3.10 no
14
+ matter what ``sys.version_info`` claims.
15
+ """
16
+ if sys.version_info >= (3, 11):
17
+ return import_module("tomllib")
18
+ return import_module("tomli")
19
+
20
+
21
+ _toml = _load_toml_module()
@@ -4,7 +4,7 @@ name = "dirsql-py-ext"
4
4
  # pypi/maturin handler can rewrite it via `write-version` before
5
5
  # `maturin build`. `pyproject.toml` declares `dynamic = ["version"]`
6
6
  # and maturin reads this field. Mirrors `packages/rust/Cargo.toml`.
7
- version = "0.4.35"
7
+ version = "0.4.37"
8
8
  # abi3 note: the `abi3-py310` pyo3 feature (below) builds ONE stable-ABI
9
9
  # `cp310-abi3` wheel per platform that loads on every CPython >= 3.10
10
10
  # (matching `pyproject.toml`'s `requires-python = ">=3.10"`), instead of
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - **The launcher's argv config-path scan moved to its own module.** `config_paths_from_argv` now lives in `dirsql/cli/config_paths_from_argv.py`; `with_resolved_extensions` imports it. Internal reorganisation with no change to the published API or CLI behavior, mirroring the TypeScript launcher. (#1042)
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - **The config-extension loader split into four modules.** `_load_toml_module` (with the `_toml` binding it produces) moved to `dirsql/toml_module.py`, `_load_extension_entries` to `dirsql/load_extension_entries.py` and `_has_bare_name` to `dirsql/has_bare_name.py`; `dirsql/resolve_config_extensions.py` keeps the intervene-or-not decision, `resolve_config_extension_specs`. Every function keeps its name and behavior — internal reorganisation with no change to the published API or CLI behavior. (#1079)
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - **The config-extension resolver split into three modules.** `_resolve_entries` moved to `dirsql/resolve_entries.py` and `resolve_configs_extension_specs` to `dirsql/resolve_configs_extension_specs.py`; `dirsql/resolve_config_extensions.py` keeps the TOML loading and the single-config `resolve_config_extension_specs`. Every function keeps its name and behavior — internal reorganisation with no change to the published API or CLI behavior. (#1056)
@@ -0,0 +1,3 @@
1
+ **Changed**
2
+
3
+ - **The extension-path resolver split into four modules.** `_platform_patterns` moved to `dirsql/platform_patterns.py`, `is_bare_name` (with `_LOADABLE_SUFFIXES`) to `dirsql/is_bare_name.py`, and `_resolve_package` to `dirsql/resolve_package.py`; `dirsql/resolve_extension.py` keeps the ordered probe, `resolve_extension_path`. Every function keeps its name and behavior — internal reorganisation with no change to the published API or CLI behavior. (#1066)
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "just test-e2e",
3
+ "ran_at": 1788571386,
4
+ "exit_code": 0,
5
+ "commit": "2b1dbcacb1960ec0e13c5fa06e58dfef012dbb45",
6
+ "branch": "claude/1056-py-ofpf9"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "just test-e2e",
3
+ "ran_at": 1788573322,
4
+ "exit_code": 0,
5
+ "commit": "4acf00655f8ebdce4297edca6b4d01b999ddfdeb",
6
+ "branch": "claude/1066-p1-resolve-extension"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "just test-e2e",
3
+ "ran_at": 1788573708,
4
+ "exit_code": 0,
5
+ "commit": "fb7bf9e800f9d682e3b8e4b83f3d69cc8642fe69",
6
+ "branch": "claude/1079-p2-resolve-config-extensions"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "just test-e2e",
3
+ "ran_at": 1788565282,
4
+ "exit_code": 0,
5
+ "commit": "9257c5204b6cf9b491cf5487aedbf026c5255338",
6
+ "branch": "claude/tackle-1042-py12"
7
+ }
@@ -10,7 +10,7 @@
10
10
  extra_scope = ["packages/rust/src", "packages/python/src"]
11
11
 
12
12
  [python]
13
- one_function_per_file = { max_lines = 16 }
13
+ one_function_per_file = { max_lines = 12 }
14
14
 
15
15
  # Same floor as the root file, which this lane no longer reads.
16
16
  [python.coverage]
@@ -6,7 +6,7 @@ description = "Ephemeral SQL index over a local directory"
6
6
  # version stays for the binding crates (publish = false). The literal
7
7
  # intentionally lags the published version: putitoutthere rewrites it to
8
8
  # the planned release version at build time and never commits it back.
9
- version = "0.4.35"
9
+ version = "0.4.37"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly
@@ -1,126 +0,0 @@
1
- """SDK-side resolution of a TOML config's ``[[dirsql.extension]]`` entries.
2
-
3
- The Rust core loads a config's extensions literally -- it has no
4
- ``importlib``, so it cannot resolve a bare **package name**. When a TOML
5
- config names an extension by package name, the SDK resolves every one of its
6
- extensions here, hands the core the resolved literal paths, and suppresses
7
- the core's own config-extension loading (``suppress_config_extensions``) so
8
- the config's entries are not loaded a second time.
9
-
10
- Shared by the ``DirSQL`` constructor (``config=`` path) and the CLI launcher
11
- (which converts the resolved specs into ``--extension`` flags).
12
- """
13
-
14
- from __future__ import annotations
15
-
16
- import os
17
- import sys
18
- from importlib import import_module
19
-
20
- from .resolve_extension import is_bare_name, resolve_extension_path
21
-
22
-
23
- def _load_toml_module():
24
- """Return the TOML parser module for the running interpreter.
25
-
26
- ``tomllib`` is stdlib only on 3.11+; on 3.10 the ``tomli`` backport it was
27
- derived from (a version-gated dependency) provides the same surface.
28
- Imported by name so a unit test can exercise both arms on any
29
- interpreter -- a literal ``import tomllib`` is unreachable on 3.10 no
30
- matter what ``sys.version_info`` claims.
31
- """
32
- if sys.version_info >= (3, 11):
33
- return import_module("tomllib")
34
- return import_module("tomli")
35
-
36
-
37
- _toml = _load_toml_module()
38
-
39
-
40
- def _load_extension_entries(config_path):
41
- """Return ``(entries, base_dir)`` for a config's ``[[dirsql.extension]]``.
42
-
43
- ``None`` when the config is missing, unreadable/malformed, or declares no
44
- extension array -- the caller should leave such configs to the core.
45
- """
46
- if not os.path.isfile(config_path):
47
- return None
48
- try:
49
- with open(config_path, "rb") as f:
50
- doc = _toml.load(f)
51
- except (OSError, _toml.TOMLDecodeError):
52
- # Leave a malformed / unreadable config for the core to report.
53
- return None
54
-
55
- entries = (doc.get("dirsql") or {}).get("extension")
56
- if not isinstance(entries, list):
57
- return None
58
- return entries, os.path.dirname(os.path.abspath(config_path))
59
-
60
-
61
- def _has_bare_name(entries):
62
- return any(
63
- isinstance(e, dict)
64
- and isinstance(e.get("path"), str)
65
- and is_bare_name(e["path"])
66
- for e in entries
67
- )
68
-
69
-
70
- def _resolve_entries(entries, base):
71
- specs = []
72
- for e in entries:
73
- entrypoint = e.get("entrypoint")
74
- specs.append(
75
- {
76
- "path": resolve_extension_path(
77
- e["path"], base=base, resolve_relative=True
78
- ),
79
- "entrypoint": entrypoint if isinstance(entrypoint, str) else None,
80
- }
81
- )
82
- return specs
83
-
84
-
85
- def resolve_config_extension_specs(config_path):
86
- """Resolve a TOML config's ``[[dirsql.extension]]`` entries to literal paths.
87
-
88
- Returns a list of ``{"path", "entrypoint"}`` dicts -- every entry resolved
89
- via :func:`resolve_extension_path` against the config file's parent
90
- directory -- when at least one entry's ``path`` is a bare package name.
91
- Returns ``None`` when the caller should not intervene: the config is
92
- missing, malformed, declares no extensions, or uses only literal paths --
93
- leaving the core's own loading (and error reporting) untouched. Raises if
94
- a package name cannot be resolved.
95
- """
96
- loaded = _load_extension_entries(config_path)
97
- if loaded is None:
98
- return None
99
- entries, base = loaded
100
- if not _has_bare_name(entries):
101
- return None
102
- return _resolve_entries(entries, base)
103
-
104
-
105
- def resolve_configs_extension_specs(config_paths):
106
- """Resolve the ``[[dirsql.extension]]`` entries of several configs, in order.
107
-
108
- The SDK intervenes for the whole set only when **some** config names an
109
- extension by bare package name (the core can resolve neither package names
110
- nor -- once globally suppressed -- the literal entries of the other
111
- configs). When it intervenes it resolves **every** config's entries, each
112
- against that config's own parent directory, concatenated in ``config_paths``
113
- order; the caller suppresses the core's config-extension loading and passes
114
- the resolved list. Returns ``None`` when no config uses a package name,
115
- leaving every config's loading to the core.
116
- """
117
- loaded = [_load_extension_entries(p) for p in config_paths]
118
- if not any(item is not None and _has_bare_name(item[0]) for item in loaded):
119
- return None
120
- specs = []
121
- for item in loaded:
122
- if item is None:
123
- continue
124
- entries, base = item
125
- specs.extend(_resolve_entries(entries, base))
126
- return specs