dirsql 0.4.109__tar.gz → 0.4.110__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 (431) hide show
  1. {dirsql-0.4.109 → dirsql-0.4.110}/Cargo.lock +2 -2
  2. {dirsql-0.4.109 → dirsql-0.4.110}/PKG-INFO +1 -1
  3. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/Cargo.toml +1 -1
  4. dirsql-0.4.110/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +7 -0
  5. dirsql-0.4.110/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +7 -0
  6. dirsql-0.4.110/packages/python/tests/e2e/bench_report.py +97 -0
  7. dirsql-0.4.110/packages/python/tests/e2e/bench_suite.py +115 -0
  8. dirsql-0.4.110/packages/python/tests/e2e/speed_of_light.py +417 -0
  9. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/Cargo.toml +1 -1
  10. dirsql-0.4.109/packages/python/tests/e2e/speed_of_light.py +0 -205
  11. {dirsql-0.4.109 → dirsql-0.4.110}/Cargo.toml +0 -0
  12. {dirsql-0.4.109 → dirsql-0.4.110}/README.md +0 -0
  13. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/__init__.py +0 -0
  14. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/_async.py +0 -0
  15. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/_dirsql.pyi +0 -0
  16. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/__init__.py +0 -0
  17. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/discover_plugins/__init__.py +0 -0
  18. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  19. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  20. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  21. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  22. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/main.py +0 -0
  23. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/cli/resolve_config_extensions.py +0 -0
  24. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/plan_entry_path.py +0 -0
  25. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/py.typed +0 -0
  26. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/read_config.py +0 -0
  27. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/resolve_configs_extension_specs.py +0 -0
  28. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/resolve_extension.py +0 -0
  29. {dirsql-0.4.109 → dirsql-0.4.110}/dirsql/resolve_package.py +0 -0
  30. {dirsql-0.4.109 → dirsql-0.4.110}/docs/.claude/CLAUDE.md +0 -0
  31. {dirsql-0.4.109 → dirsql-0.4.110}/docs/.vitepress/config.ts +0 -0
  32. {dirsql-0.4.109 → dirsql-0.4.110}/docs/.vitepress/theme/index.ts +0 -0
  33. {dirsql-0.4.109 → dirsql-0.4.110}/docs/.vitepress/theme/lang.ts +0 -0
  34. {dirsql-0.4.109 → dirsql-0.4.110}/docs/AGENTS.md +0 -0
  35. {dirsql-0.4.109 → dirsql-0.4.110}/docs/context/.gitattributes +0 -0
  36. {dirsql-0.4.109 → dirsql-0.4.110}/docs/context/recipes.md +0 -0
  37. {dirsql-0.4.109 → dirsql-0.4.110}/docs/context/troubleshooting.md +0 -0
  38. {dirsql-0.4.109 → dirsql-0.4.110}/docs/context/usage.md +0 -0
  39. {dirsql-0.4.109 → dirsql-0.4.110}/docs/explanation.md +0 -0
  40. {dirsql-0.4.109 → dirsql-0.4.110}/docs/getting-started.md +0 -0
  41. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/agent-skill.md +0 -0
  42. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/columns-from-paths.md +0 -0
  43. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/define-tables.md +0 -0
  44. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/embed.md +0 -0
  45. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/extract-from-contents.md +0 -0
  46. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/load-extension.md +0 -0
  47. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/parse-files-into-columns.md +0 -0
  48. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/persist.md +0 -0
  49. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/query-json.md +0 -0
  50. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/query-without-config.md +0 -0
  51. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/react-to-changes.md +0 -0
  52. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/search-by-meaning.md +0 -0
  53. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/search-indexes.md +0 -0
  54. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/skip-files.md +0 -0
  55. {dirsql-0.4.109 → dirsql-0.4.110}/docs/howto/write-a-plugin.md +0 -0
  56. {dirsql-0.4.109 → dirsql-0.4.110}/docs/index.md +0 -0
  57. {dirsql-0.4.109 → dirsql-0.4.110}/docs/package.json +0 -0
  58. {dirsql-0.4.109 → dirsql-0.4.110}/docs/plugins.md +0 -0
  59. {dirsql-0.4.109 → dirsql-0.4.110}/docs/pnpm-lock.yaml +0 -0
  60. {dirsql-0.4.109 → dirsql-0.4.110}/docs/pnpm-workspace.yaml +0 -0
  61. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/cli.md +0 -0
  62. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/columns.md +0 -0
  63. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/config.md +0 -0
  64. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/glob.md +0 -0
  65. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/hooks.md +0 -0
  66. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/http-api.md +0 -0
  67. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/path-tables.md +0 -0
  68. {dirsql-0.4.109 → dirsql-0.4.110}/docs/reference/sdk.md +0 -0
  69. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/CHANGELOG.md +0 -0
  70. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/MIGRATIONS.md +0 -0
  71. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/README.md +0 -0
  72. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  73. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  74. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  75. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  76. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  77. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  78. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  79. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  80. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  81. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  82. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  83. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  84. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  85. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  86. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  87. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  88. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  89. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  90. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  91. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  92. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  93. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  94. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  95. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  96. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
  97. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
  98. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
  99. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
  100. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  101. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  102. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
  103. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  104. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
  105. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  106. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  107. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
  108. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
  109. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
  110. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
  111. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
  112. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  113. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
  114. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
  115. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
  116. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
  117. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  118. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
  119. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
  120. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
  121. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
  122. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  123. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
  124. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  125. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
  126. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
  127. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
  128. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
  129. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
  130. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
  131. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
  132. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
  133. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  134. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
  135. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/changelog.d/README.md +0 -0
  136. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/conftest.py +0 -0
  137. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/.claude/CLAUDE.md +0 -0
  138. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/.vitepress/config.ts +0 -0
  139. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  140. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  141. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/AGENTS.md +0 -0
  142. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/context/.gitattributes +0 -0
  143. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/context/recipes.md +0 -0
  144. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/context/troubleshooting.md +0 -0
  145. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/context/usage.md +0 -0
  146. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/explanation.md +0 -0
  147. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/getting-started.md +0 -0
  148. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/agent-skill.md +0 -0
  149. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/columns-from-paths.md +0 -0
  150. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/define-tables.md +0 -0
  151. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/embed.md +0 -0
  152. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/extract-from-contents.md +0 -0
  153. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/load-extension.md +0 -0
  154. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  155. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/persist.md +0 -0
  156. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/query-json.md +0 -0
  157. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/query-without-config.md +0 -0
  158. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/react-to-changes.md +0 -0
  159. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/search-by-meaning.md +0 -0
  160. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/search-indexes.md +0 -0
  161. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/skip-files.md +0 -0
  162. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/howto/write-a-plugin.md +0 -0
  163. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/index.md +0 -0
  164. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/package.json +0 -0
  165. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/plugins.md +0 -0
  166. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/pnpm-lock.yaml +0 -0
  167. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/pnpm-workspace.yaml +0 -0
  168. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/cli.md +0 -0
  169. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/columns.md +0 -0
  170. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/config.md +0 -0
  171. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/glob.md +0 -0
  172. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/hooks.md +0 -0
  173. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/http-api.md +0 -0
  174. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/path-tables.md +0 -0
  175. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/docs/reference/sdk.md +0 -0
  176. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
  177. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
  178. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
  179. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
  180. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
  181. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
  182. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
  183. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
  184. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
  185. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
  186. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
  187. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
  188. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
  189. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
  190. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
  191. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
  192. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
  193. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
  194. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
  195. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
  196. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
  197. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
  198. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
  199. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
  200. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
  201. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
  202. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
  203. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
  204. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
  205. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
  206. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  207. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  208. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  209. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  210. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  211. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  212. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  213. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  214. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  215. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
  216. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
  217. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
  218. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
  219. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
  220. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
  221. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
  222. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
  223. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
  224. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
  225. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
  226. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
  227. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
  228. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
  229. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
  230. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
  231. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
  232. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
  233. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
  234. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
  235. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
  236. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
  237. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
  238. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
  239. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
  240. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
  241. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
  242. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
  243. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
  244. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
  245. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
  246. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
  247. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
  248. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
  249. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
  250. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
  251. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
  252. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
  253. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
  254. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
  255. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
  256. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
  257. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
  258. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
  259. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
  260. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
  261. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
  262. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
  263. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
  264. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
  265. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
  266. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
  267. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
  268. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
  269. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
  270. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
  271. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
  272. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
  273. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
  274. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
  275. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
  276. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
  277. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
  278. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
  279. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
  280. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
  281. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
  282. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
  283. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
  284. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
  285. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  286. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  287. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  288. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  289. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  290. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  291. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  292. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  293. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  294. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  295. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  296. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  297. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  298. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  299. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  300. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  301. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  302. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  303. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  304. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  305. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  306. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  307. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  308. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  309. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  310. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  311. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  312. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
  313. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  314. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
  315. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  316. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  317. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
  318. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
  319. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
  320. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
  321. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
  322. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  323. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
  324. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
  325. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
  326. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
  327. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  328. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
  329. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
  330. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
  331. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
  332. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  333. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
  334. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  335. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
  336. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
  337. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
  338. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
  339. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
  340. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
  341. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
  342. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
  343. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  344. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
  345. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/migrations.d/README.md +0 -0
  346. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/src/lib.rs +0 -0
  347. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/testing-conventions.toml +0 -0
  348. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/__init__.py +0 -0
  349. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/conftest.py +0 -0
  350. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/e2e/__init__.py +0 -0
  351. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  352. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  353. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/integration/__init__.py +0 -0
  354. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/integration/binding/__init__.py +0 -0
  355. {dirsql-0.4.109 → dirsql-0.4.110}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  356. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/CHANGELOG.md +0 -0
  357. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/MIGRATIONS.md +0 -0
  358. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/README.md +0 -0
  359. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/benches/db_bench.rs +0 -0
  360. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/benches/differ_bench.rs +0 -0
  361. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/benches/matcher_bench.rs +0 -0
  362. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/benches/scanner_bench.rs +0 -0
  363. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/context/.gitattributes +0 -0
  364. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/context/recipes.md +0 -0
  365. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/context/troubleshooting.md +0 -0
  366. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/context/usage.md +0 -0
  367. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/explanation.md +0 -0
  368. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/getting-started.md +0 -0
  369. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/agent-skill.md +0 -0
  370. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  371. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/define-tables.md +0 -0
  372. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/embed.md +0 -0
  373. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  374. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/load-extension.md +0 -0
  375. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  376. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/persist.md +0 -0
  377. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/query-json.md +0 -0
  378. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/query-without-config.md +0 -0
  379. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/react-to-changes.md +0 -0
  380. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  381. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/search-indexes.md +0 -0
  382. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/skip-files.md +0 -0
  383. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  384. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/index.md +0 -0
  385. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/plugins.md +0 -0
  386. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/cli.md +0 -0
  387. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/columns.md +0 -0
  388. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/config.md +0 -0
  389. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/glob.md +0 -0
  390. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/hooks.md +0 -0
  391. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/http-api.md +0 -0
  392. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/path-tables.md +0 -0
  393. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/docs/reference/sdk.md +0 -0
  394. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/bin/dirsql.rs +0 -0
  395. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/brace.rs +0 -0
  396. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/context.rs +0 -0
  397. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/execute.rs +0 -0
  398. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/init.rs +0 -0
  399. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/mod.rs +0 -0
  400. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/repl.rs +0 -0
  401. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/router.rs +0 -0
  402. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/run.rs +0 -0
  403. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/serialize.rs +0 -0
  404. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/server.rs +0 -0
  405. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/cli/table.rs +0 -0
  406. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/command.rs +0 -0
  407. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/config.rs +0 -0
  408. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/db.rs +0 -0
  409. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/default_config.toml +0 -0
  410. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/differ.rs +0 -0
  411. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/extension_resolution.rs +0 -0
  412. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/functions.rs +0 -0
  413. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/infer.rs +0 -0
  414. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/launcher.rs +0 -0
  415. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/lib.rs +0 -0
  416. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/listing.rs +0 -0
  417. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/matcher.rs +0 -0
  418. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/on_file.rs +0 -0
  419. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/parsed_vtab.rs +0 -0
  420. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/path_table.rs +0 -0
  421. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/persist.rs +0 -0
  422. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/posix_class.rs +0 -0
  423. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/progress.rs +0 -0
  424. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/row_event_flat.rs +0 -0
  425. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/scanner.rs +0 -0
  426. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/sql_literal.rs +0 -0
  427. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/tree_walk.rs +0 -0
  428. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/vtab.rs +0 -0
  429. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/vtab_scaffold.rs +0 -0
  430. {dirsql-0.4.109 → dirsql-0.4.110}/packages/rust/src/watcher.rs +0 -0
  431. {dirsql-0.4.109 → dirsql-0.4.110}/pyproject.toml +0 -0
@@ -573,7 +573,7 @@ dependencies = [
573
573
 
574
574
  [[package]]
575
575
  name = "dirsql"
576
- version = "0.4.109"
576
+ version = "0.4.110"
577
577
  dependencies = [
578
578
  "assert_cmd",
579
579
  "axum",
@@ -625,7 +625,7 @@ dependencies = [
625
625
 
626
626
  [[package]]
627
627
  name = "dirsql-py-ext"
628
- version = "0.4.109"
628
+ version = "0.4.110"
629
629
  dependencies = [
630
630
  "dirsql",
631
631
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.109
3
+ Version: 0.4.110
4
4
  Requires-Dist: bin-shim>=0.1
5
5
  Summary: Ephemeral SQL index over a local directory
6
6
  Keywords: sql,filesystem,directory,sqlite,index
@@ -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.109"
7
+ version = "0.4.110"
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,7 @@
1
+ {
2
+ "command": "just test-e2e",
3
+ "ran_at": 1791551036,
4
+ "exit_code": 0,
5
+ "commit": "30fee35315cbb6f971956415d71be398c0c9d46e",
6
+ "branch": "bot/1464-fastest-native-1008"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_recursive_test.py tests/e2e/stat_speed_test.py -x -q",
3
+ "ran_at": 1791558371,
4
+ "exit_code": 0,
5
+ "commit": "51dddeda464183ef6bd032221984298ce1437184",
6
+ "branch": "bot/1470-perf-suite-1009"
7
+ }
@@ -0,0 +1,97 @@
1
+ """Records, report and markdown for the performance suite (`just bench-suite`)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import statistics
7
+ from pathlib import Path
8
+
9
+ RECORDS = "cases.jsonl"
10
+
11
+
12
+ def ratio_stats(ratios):
13
+ low, high = min(ratios), max(ratios)
14
+ median = statistics.median(ratios)
15
+ return {"min": low, "median": median, "max": high, "spread": (high - low) / median}
16
+
17
+
18
+ def case_record(name, result, startup):
19
+ natives = {}
20
+ for native, seconds in result.native_seconds.items():
21
+ net = [s - startup.native for s in seconds]
22
+ natives[native] = {
23
+ "native_median_s": statistics.median(seconds),
24
+ "ratio": ratio_stats(
25
+ [(d - startup.dirsql) / n for d, n in zip(result.dirsql_seconds, net)]
26
+ ),
27
+ }
28
+ return {
29
+ "name": name,
30
+ "pairs": len(result.dirsql_seconds),
31
+ "fastest": result.fastest,
32
+ "ratio_vs_fastest": natives[result.fastest]["ratio"]["median"],
33
+ "dirsql_median_s": statistics.median(result.dirsql_seconds),
34
+ "startup": {"dirsql": startup.dirsql, "native": startup.native},
35
+ "natives": natives,
36
+ "skipped": list(result.skipped),
37
+ }
38
+
39
+
40
+ def build_report(records, meta):
41
+ return {**meta, "cases": sorted(records, key=lambda c: c["name"])}
42
+
43
+
44
+ def append_record(out, record):
45
+ with (Path(out) / RECORDS).open("a") as file:
46
+ file.write(json.dumps(record) + "\n")
47
+
48
+
49
+ def read_records(out):
50
+ lines = (Path(out) / RECORDS).read_text().splitlines()
51
+ return [json.loads(line) for line in lines]
52
+
53
+
54
+ def render_markdown(report):
55
+ machine = ", ".join(f"{k}: {v}" for k, v in report["machine"].items())
56
+ versions = ", ".join(f"{k}: {v}" for k, v in report["versions"].items())
57
+ lines = [
58
+ "# dirsql performance suite",
59
+ "",
60
+ f"- Commit: {report['commit']}",
61
+ f"- Date: {report['date']}",
62
+ f"- Machine: {machine}",
63
+ f"- Versions: {versions}",
64
+ (
65
+ f"- Method: {report['pairs']} paired runs per case, interleaved; ratios"
66
+ " are dirsql over the native after each side's startup, median across"
67
+ " pairs"
68
+ ),
69
+ "",
70
+ "| Case | Fastest native | dirsql / fastest | Spread | vs 1.0x |",
71
+ "|---|---|---|---|---|",
72
+ ]
73
+ for case in report["cases"]:
74
+ stats = case["natives"][case["fastest"]]["ratio"]
75
+ verdict = "over" if case["ratio_vs_fastest"] > 1.0 else "ok"
76
+ lines.append(
77
+ f"| {case['name']} | {case['fastest']} | {case['ratio_vs_fastest']:.2f}x"
78
+ f" | {stats['spread']:.0%} | {verdict} |"
79
+ )
80
+ for case in report["cases"]:
81
+ lines += [
82
+ "",
83
+ f"## {case['name']}",
84
+ "",
85
+ f"dirsql median {case['dirsql_median_s']:.3f}s",
86
+ "",
87
+ "| Native | Median s | dirsql / native | Min | Max | Spread |",
88
+ "|---|---|---|---|---|---|",
89
+ ]
90
+ for native, data in sorted(case["natives"].items()):
91
+ r = data["ratio"]
92
+ lines.append(
93
+ f"| {native} | {data['native_median_s']:.3f} | {r['median']:.2f}x"
94
+ f" | {r['min']:.2f}x | {r['max']:.2f}x | {r['spread']:.0%} |"
95
+ )
96
+ lines += [f"- {tool} (not installed)" for tool in case["skipped"]]
97
+ return "\n".join(lines) + "\n"
@@ -0,0 +1,115 @@
1
+ """Entry point for `just bench-suite`.
2
+
3
+ Runs every speed-of-light case with every native timed in each paired,
4
+ interleaved run, then writes `report.json` and `report.md` beside the raw
5
+ per-case records. The cases are the e2e tests themselves, so the suite and the
6
+ ratchet never disagree on what a case is.
7
+
8
+ python -m tests.e2e.bench_suite --pairs 100 --out /tmp/bench [-k expr]
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ import datetime
15
+ import json
16
+ import os
17
+ import platform
18
+ import shutil
19
+ import subprocess
20
+ import sys
21
+ from pathlib import Path
22
+
23
+ from .bench_report import build_report, read_records, render_markdown
24
+
25
+ HERE = Path(__file__).parent
26
+ TOOLS = (
27
+ ("bash", ["bash", "--version"]),
28
+ ("find", ["find", "--version"]),
29
+ ("fd", ["fd", "--version"]),
30
+ ("rg", ["rg", "--version"]),
31
+ ("xargs", ["xargs", "--version"]),
32
+ ("inotifywait", ["inotifywait", "--help"]),
33
+ )
34
+
35
+
36
+ def case_files(directory=HERE):
37
+ return sorted(
38
+ path
39
+ for path in directory.glob("*_test.py")
40
+ if "assert_speed_of_light" in path.read_text()
41
+ )
42
+
43
+
44
+ def first_line(argv):
45
+ if shutil.which(argv[0]) is None:
46
+ return None
47
+ proc = subprocess.run(argv, capture_output=True, text=True, check=False)
48
+ lines = (proc.stdout or proc.stderr).splitlines()
49
+ return lines[0].strip() if lines else None
50
+
51
+
52
+ def cpu_model():
53
+ try:
54
+ for line in Path("/proc/cpuinfo").read_text().splitlines():
55
+ if line.startswith("model name"):
56
+ return line.split(":", 1)[1].strip()
57
+ except OSError:
58
+ pass
59
+ return platform.processor() or "unknown"
60
+
61
+
62
+ def git_commit():
63
+ proc = subprocess.run(
64
+ ["git", "rev-parse", "HEAD"], capture_output=True, text=True, check=False
65
+ )
66
+ return proc.stdout.strip() or "unknown"
67
+
68
+
69
+ def metadata(pairs):
70
+ versions = {}
71
+ for name, argv in TOOLS:
72
+ versions[name] = first_line(argv)
73
+ return {
74
+ "commit": git_commit(),
75
+ "date": datetime.datetime.now(datetime.timezone.utc).strftime(
76
+ "%Y-%m-%dT%H:%M:%SZ"
77
+ ),
78
+ "machine": {
79
+ "platform": platform.platform(),
80
+ "cpu": cpu_model(),
81
+ "cpus": os.cpu_count(),
82
+ },
83
+ "versions": {k: v for k, v in versions.items() if v},
84
+ "pairs": pairs,
85
+ }
86
+
87
+
88
+ def main(argv=None):
89
+ parser = argparse.ArgumentParser()
90
+ parser.add_argument("--pairs", type=int, default=100)
91
+ parser.add_argument("--out", type=Path, required=True)
92
+ parser.add_argument("-k", default="")
93
+ args = parser.parse_args(argv)
94
+ args.out.mkdir(parents=True, exist_ok=True)
95
+ (args.out / "cases.jsonl").unlink(missing_ok=True)
96
+ env = {
97
+ **os.environ,
98
+ "DIRSQL_BENCH_PAIRS": str(args.pairs),
99
+ "DIRSQL_BENCH_OUT": str(args.out),
100
+ }
101
+ pytest = [sys.executable, "-m", "pytest", "-q", "-s", "-p", "no:cacheprovider"]
102
+ if args.k:
103
+ pytest += ["-k", args.k]
104
+ code = subprocess.run(
105
+ pytest + [str(p) for p in case_files()], env=env, check=False
106
+ ).returncode
107
+ report = build_report(read_records(args.out), metadata(args.pairs))
108
+ (args.out / "report.json").write_text(json.dumps(report, indent=2) + "\n")
109
+ (args.out / "report.md").write_text(render_markdown(report))
110
+ print(f"wrote {args.out}/report.json and {args.out}/report.md")
111
+ return code
112
+
113
+
114
+ if __name__ == "__main__":
115
+ sys.exit(main())
@@ -0,0 +1,417 @@
1
+ """Harness for the use-case speed-of-light tests.
2
+
3
+ Each test asks one question of a generated corpus through every plausible
4
+ native pipeline (find, fd, rg, xargs -P, a single parser process) and once
5
+ through the real `dirsql` launcher. Every native's rows must equal dirsql's.
6
+ dirsql's wall time, after subtracting the launcher's measured startup, must be
7
+ within ten percent of the case's bar native, `find` or the case's own first
8
+ native unless the case passes `bar=FASTEST`. The fastest native's ratio is
9
+ printed either way. The bar is a ratio, never a millisecond number, so it holds
10
+ on any machine. A native whose tool is not installed is printed as SKIPPED,
11
+ never dropped quietly.
12
+
13
+ A few screening pairs time every native to find the fastest; the measured
14
+ pairs then run only the fastest and the bar native. Pairs alternate (natives
15
+ first, then dirsql first, and so on) after one discarded warm-up pair, so
16
+ drift in machine speed hits every side alike. The verdict is the median of the
17
+ per-pair ratios. Startup is the median of `dirsql query 'SELECT 1'` runs with
18
+ the first dropped, and native's own is the median of `bash -c true` the same
19
+ way; each is subtracted from its side. A corpus too small to time is grown by
20
+ doubling until the native pipeline takes a second, unless the corpus ceiling
21
+ stops it sooner.
22
+ Output is captured as bytes and decoded after the clock stops.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import json
28
+ import os
29
+ import shutil
30
+ import statistics
31
+ import subprocess
32
+ import tempfile
33
+ import time
34
+ from collections.abc import Callable
35
+ from dataclasses import dataclass, field
36
+ from typing import NamedTuple
37
+
38
+ from .bench_report import append_record, case_record
39
+
40
+ ONE_SECOND = 1.0
41
+ TOLERANCE = 1.1
42
+ STARTUP_PROBES = 11
43
+ PAIRS = 15
44
+ SCREEN_PAIRS = 5
45
+ FASTEST = "fastest"
46
+ HOPELESS_STREAK = 3
47
+ NATIVE_ENV = {**os.environ, "LC_ALL": "C"}
48
+
49
+
50
+ class Startup(NamedTuple):
51
+ dirsql: float
52
+ native: float
53
+
54
+
55
+ class Native(NamedTuple):
56
+ """One native pipeline. `needs` lists the names its tool goes by, first
57
+ installed wins; `script` has `{bin}` where that name goes."""
58
+
59
+ name: str
60
+ needs: tuple
61
+ script: str
62
+
63
+
64
+ class Natives(NamedTuple):
65
+ """`bar` names the native dirsql is held to: the first one by default, or
66
+ `FASTEST`."""
67
+
68
+ runs: dict
69
+ skipped: list
70
+ bar: str = ""
71
+
72
+
73
+ class Series(NamedTuple):
74
+ rows: dict
75
+ dirsql_rows: object
76
+ native_seconds: dict
77
+ dirsql_seconds: list
78
+
79
+
80
+ @dataclass
81
+ class Paired:
82
+ native_rows: dict
83
+ dirsql_rows: object
84
+ native_seconds: dict
85
+ dirsql_seconds: list
86
+ skipped: list
87
+ screen_seconds: dict = field(default_factory=dict)
88
+ screen_dirsql: list = field(default_factory=list)
89
+ fastest: str = ""
90
+ bar: str = ""
91
+
92
+
93
+ def suite_pairs():
94
+ """The pair count when `just bench-suite` drives the run, else None."""
95
+ count = os.environ.get("DIRSQL_BENCH_PAIRS")
96
+ return int(count) if count and os.environ.get("DIRSQL_BENCH_OUT") else None
97
+
98
+
99
+ def suite_only(*specs):
100
+ """Natives the performance suite times that the e2e ratchet does not."""
101
+ return list(specs) if suite_pairs() else []
102
+
103
+
104
+ def cli() -> str:
105
+ dirsql = shutil.which("dirsql")
106
+ assert dirsql is not None, (
107
+ "`dirsql` console script not on PATH -- run `uv run maturin develop`"
108
+ )
109
+ return dirsql
110
+
111
+
112
+ def timed(argv, cwd, timeout, env=None):
113
+ started = time.perf_counter()
114
+ proc = subprocess.run(
115
+ argv,
116
+ cwd=str(cwd),
117
+ stdin=subprocess.DEVNULL,
118
+ capture_output=True,
119
+ timeout=timeout,
120
+ env=env,
121
+ check=False,
122
+ )
123
+ seconds = time.perf_counter() - started
124
+ proc.stdout = proc.stdout.decode()
125
+ proc.stderr = proc.stderr.decode()
126
+ return proc, seconds
127
+
128
+
129
+ def timed_native(argv, cwd, timeout=600):
130
+ return timed(argv, cwd, timeout, env=NATIVE_ENV)
131
+
132
+
133
+ def sorted_lines(proc):
134
+ return sorted(proc.stdout.splitlines())
135
+
136
+
137
+ def resolve_natives(specs, which=shutil.which):
138
+ runnable, skipped = [], []
139
+ for spec in specs:
140
+ binary = next((n for n in spec.needs if which(n)), None)
141
+ if binary is None:
142
+ skipped.append(spec.name)
143
+ else:
144
+ runnable.append((spec.name, spec.script.replace("{bin}", binary)))
145
+ assert runnable, f"no native installed: {[s.name for s in specs]}"
146
+ return runnable, skipped
147
+
148
+
149
+ def shell_natives(root, specs, parse=sorted_lines, shell="bash", bar="") -> Natives:
150
+ def runner(script):
151
+ def run():
152
+ proc, seconds = timed_native([shell, "-c", script], root)
153
+ assert proc.returncode == 0, proc.stderr
154
+ return parse(proc), seconds
155
+
156
+ return run
157
+
158
+ runnable, skipped = resolve_natives(specs)
159
+ return Natives({name: runner(script) for name, script in runnable}, skipped, bar)
160
+
161
+
162
+ AGG_AWK = (
163
+ '{ n[$1]++; s[$1] += $2 } END { for (k in n) print k "\\t" n[k] "\\t" s[k] }\n'
164
+ )
165
+ MERGE_AWK = (
166
+ '{ n[$1] += $2; s[$1] += $3 } END { for (k in n) print k "\\t" n[k] "\\t" s[k] }\n'
167
+ )
168
+
169
+
170
+ def fd(args):
171
+ return Native("fd", ("fd", "fdfind"), "{bin} --no-ignore --type f " + args)
172
+
173
+
174
+ def rg(args):
175
+ return Native("rg", ("rg",), "{bin} --files --no-ignore " + args)
176
+
177
+
178
+ def globstar(pattern):
179
+ trim = "cut -c3-" if pattern.startswith("./") else "cat"
180
+ return Native(
181
+ "bash-globstar",
182
+ ("bash",),
183
+ '{bin} -O globstar -O nullglob -c \'printf "%s\\n" ' + pattern + f"' | {trim}",
184
+ )
185
+
186
+
187
+ def baseline(natives: Natives) -> Callable:
188
+ return next(iter(natives.runs.values()))
189
+
190
+
191
+ def median_after_first(samples):
192
+ return statistics.median(samples[1:])
193
+
194
+
195
+ def probe_seconds(argv, cwd, env=None) -> float:
196
+ samples = []
197
+ for _ in range(STARTUP_PROBES):
198
+ proc, seconds = timed(argv, cwd, timeout=60, env=env)
199
+ assert proc.returncode == 0, proc.stderr
200
+ samples.append(seconds)
201
+ return median_after_first(samples)
202
+
203
+
204
+ def startup_seconds(argv=None, cwd=None) -> Startup:
205
+ argv = [cli(), "query", "SELECT 1"] if argv is None else argv
206
+ with tempfile.TemporaryDirectory() as empty:
207
+ dirsql = probe_seconds(argv, cwd or empty)
208
+ native = probe_seconds(["bash", "-c", "true"], empty, NATIVE_ENV)
209
+ return Startup(dirsql, native)
210
+
211
+
212
+ def dirsql_rows(proc, columns):
213
+ assert proc.returncode == 0, (
214
+ f"dirsql failed: stdout={proc.stdout!r} stderr={proc.stderr!r}"
215
+ )
216
+ return [tuple(row[column] for column in columns) for row in json.loads(proc.stdout)]
217
+
218
+
219
+ def grow_until_native_takes_a_second(build, native, start, ceiling):
220
+ """Grow the corpus by doubling until `native` runs for a second.
221
+
222
+ `build(lo, hi)` adds items `lo` through `hi - 1` to the corpus already
223
+ holding `lo` items, so each doubling writes only the new half.
224
+ """
225
+ built, size = 0, start
226
+ while True:
227
+ build(built, size)
228
+ os.sync()
229
+ built = size
230
+ _, seconds = native()
231
+ if seconds >= ONE_SECOND or size >= ceiling:
232
+ return size
233
+ size *= 2
234
+
235
+
236
+ def dirsql_timeout(native_seconds: float) -> float:
237
+ return max(60.0, 30 * native_seconds)
238
+
239
+
240
+ def pair_ratios(native_seconds, dirsql_seconds, startup):
241
+ ratios = []
242
+ for native, dirsql in zip(native_seconds, dirsql_seconds):
243
+ net = native - startup.native
244
+ assert net > 0, (
245
+ f"native {native:.3f}s is under its startup {startup.native:.3f}s"
246
+ )
247
+ ratios.append((dirsql - startup.dirsql) / net)
248
+ return ratios
249
+
250
+
251
+ def is_hopeless(native, dirsql, startup):
252
+ return dirsql - startup.dirsql > 10 * TOLERANCE * (native - startup.native)
253
+
254
+
255
+ def run_or_fail(run, name):
256
+ try:
257
+ return run()
258
+ except subprocess.TimeoutExpired as expired:
259
+ raise AssertionError(
260
+ f"{name} did not finish within {expired.timeout:.0f}s"
261
+ ) from None
262
+
263
+
264
+ def paired(natives, dirsql, startup, pairs=PAIRS, screen=SCREEN_PAIRS):
265
+ """Screen every native, then time dirsql against the bar and the fastest.
266
+
267
+ The first pair is a discarded warm-up that also sets dirsql's timeout.
268
+ `screen` alternating pairs run every native to find the fastest by median
269
+ time; `pairs` alternating pairs then run only the fastest and the bar
270
+ native (the same one unless the bar is pinned elsewhere). A run that
271
+ raises `TimeoutExpired` fails the test at once. Three hopeless pairs in a
272
+ row, judged against the pair's fastest native, end the measured series
273
+ early: noise does not account for an order of magnitude, so more pairs
274
+ cannot bring the median under the bar.
275
+ """
276
+ runs = natives.runs
277
+ rows = {}
278
+ warm = []
279
+ for name, run in runs.items():
280
+ rows[name], seconds = run_or_fail(run, name)
281
+ warm.append(seconds)
282
+ timeout = dirsql_timeout(max(warm))
283
+
284
+ def run_dirsql():
285
+ return run_or_fail(lambda: dirsql(timeout), "dirsql")
286
+
287
+ run_dirsql()
288
+ everyone = suite_pairs()
289
+ if everyone:
290
+ result = run_pairs(runs, run_dirsql, everyone)
291
+ fastest = fastest_by_median(result.native_seconds)
292
+ return Paired(
293
+ {**rows, **result.rows},
294
+ result.dirsql_rows,
295
+ result.native_seconds,
296
+ result.dirsql_seconds,
297
+ natives.skipped,
298
+ fastest=fastest,
299
+ bar=fastest,
300
+ )
301
+ screened = run_pairs(runs, run_dirsql, screen)
302
+ rows.update(screened.rows)
303
+ fastest = fastest_by_median(screened.native_seconds)
304
+ bar = fastest if natives.bar == FASTEST else natives.bar or next(iter(runs))
305
+ measured = {name: runs[name] for name in dict.fromkeys([fastest, bar])}
306
+ result = run_pairs(measured, run_dirsql, pairs, startup)
307
+ rows.update(result.rows)
308
+ return Paired(
309
+ rows,
310
+ result.dirsql_rows,
311
+ result.native_seconds,
312
+ result.dirsql_seconds,
313
+ natives.skipped,
314
+ screened.native_seconds,
315
+ screened.dirsql_seconds,
316
+ fastest,
317
+ bar,
318
+ )
319
+
320
+
321
+ def run_pairs(runs, run_dirsql, count, startup=None):
322
+ """Alternate every run in `runs` with dirsql, runs first on even pairs."""
323
+ rows = {}
324
+ dirsql_rows_ = None
325
+ native_times = {name: [] for name in runs}
326
+ dirsql_times, streak = [], 0
327
+ for index in range(count):
328
+ order = list(runs)
329
+ if index % 2:
330
+ order.reverse()
331
+ this_pair = {}
332
+ if index % 2 == 0:
333
+ for name in order:
334
+ rows[name], this_pair[name] = run_or_fail(runs[name], name)
335
+ dirsql_rows_, dirsql_seconds = run_dirsql()
336
+ else:
337
+ dirsql_rows_, dirsql_seconds = run_dirsql()
338
+ for name in order:
339
+ rows[name], this_pair[name] = run_or_fail(runs[name], name)
340
+ for name, seconds in this_pair.items():
341
+ native_times[name].append(seconds)
342
+ dirsql_times.append(dirsql_seconds)
343
+ if startup is None:
344
+ continue
345
+ hopeless = is_hopeless(min(this_pair.values()), dirsql_seconds, startup)
346
+ streak = streak + 1 if hopeless else 0
347
+ if streak == HOPELESS_STREAK:
348
+ break
349
+ return Series(rows, dirsql_rows_, native_times, dirsql_times)
350
+
351
+
352
+ def summarize(ratios):
353
+ low, high = min(ratios), max(ratios)
354
+ median = statistics.median(ratios)
355
+ return low, median, high, (high - low) / median
356
+
357
+
358
+ def fastest_by_median(native_seconds):
359
+ return min(native_seconds, key=lambda name: statistics.median(native_seconds[name]))
360
+
361
+
362
+ def agreed_rows(result):
363
+ names = list(result.native_rows)
364
+ first = names[0]
365
+ for name in names[1:]:
366
+ assert result.native_rows[name] == result.native_rows[first], (
367
+ f"{name} disagrees with {first}"
368
+ )
369
+ return result.native_rows[first]
370
+
371
+
372
+ def ratio_line(label, native, native_seconds, dirsql_seconds, startup):
373
+ ratios = pair_ratios(native_seconds, dirsql_seconds, startup)
374
+ low, median, high, spread = summarize(ratios)
375
+ line = (
376
+ f"{label} vs {native}: {len(ratios)} pairs, ratio min {low:.3f}"
377
+ f" median {median:.3f} max {high:.3f} spread {spread:.0%}, native"
378
+ f" median {statistics.median(native_seconds):.3f}s"
379
+ )
380
+ return median, line
381
+
382
+
383
+ def assert_speed_of_light(name, result, startup):
384
+ """Print every native's screening time and ratio, then hold dirsql to the bar.
385
+
386
+ The bar is `result.bar`; the fastest native's ratio is printed beside it
387
+ and not asserted unless the bar is that native. Under `just bench-suite`
388
+ the case is recorded and nothing is asserted: the suite reports.
389
+ """
390
+ if suite_pairs():
391
+ append_record(
392
+ os.environ["DIRSQL_BENCH_OUT"], case_record(name, result, startup)
393
+ )
394
+ return
395
+ lines = []
396
+ for native, seconds in result.screen_seconds.items():
397
+ _, line = ratio_line(
398
+ f"{name} screen", native, seconds, result.screen_dirsql, startup
399
+ )
400
+ lines.append(line + (" [fastest]" if native == result.fastest else ""))
401
+ lines.extend(f"{name}: SKIPPED {tool} (not installed)" for tool in result.skipped)
402
+ verdicts = {}
403
+ for role, native in (("bar", result.bar), ("fastest", result.fastest)):
404
+ verdicts[role] = ratio_line(
405
+ name, native, result.native_seconds[native], result.dirsql_seconds, startup
406
+ )
407
+ lines.append(f"{role} {verdicts[role][1]}")
408
+ lines.append(
409
+ f"{name}: startup dirsql {startup.dirsql:.3f}s native {startup.native:.3f}s,"
410
+ f" load {os.getloadavg()[0]:.1f}"
411
+ )
412
+ for line in lines:
413
+ print(f"SPEED {line}")
414
+ median, line = verdicts["bar"]
415
+ assert median <= TOLERANCE, (
416
+ f"bar native {result.bar}: {line}; median is over {TOLERANCE}x"
417
+ )
@@ -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.109"
9
+ version = "0.4.110"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly