fleche 0.22.0__tar.gz → 0.22.2__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 (241) hide show
  1. fleche-0.22.0/.github/workflows/claude_ci_details.yaml → fleche-0.22.2/.github/workflows/ci-failure-summary.yml +2 -2
  2. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/claude.yaml +3 -3
  3. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/perf-triage.yml +1 -1
  4. fleche-0.22.2/.github/workflows/reflow-agent-docs.yml +57 -0
  5. fleche-0.22.2/.github/workflows/reflow_agent_docs.py +160 -0
  6. fleche-0.22.2/.release-please-manifest.json +3 -0
  7. fleche-0.22.2/AGENTS.md +33 -0
  8. {fleche-0.22.0 → fleche-0.22.2}/CHANGELOG.md +15 -0
  9. {fleche-0.22.0/src/fleche.egg-info → fleche-0.22.2}/PKG-INFO +7 -9
  10. {fleche-0.22.0 → fleche-0.22.2}/README.md +3 -5
  11. fleche-0.22.2/agents/DEVELOPING.md +1028 -0
  12. fleche-0.22.2/agents/USAGE.md +172 -0
  13. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/profile_digest_types.py +18 -0
  14. {fleche-0.22.0 → fleche-0.22.2}/docs/dev/call_lifecycle.rst +51 -0
  15. {fleche-0.22.0 → fleche-0.22.2}/docs/dev/custom_digests.rst +20 -0
  16. fleche-0.22.2/docs/dev/extending_destructurer.rst +119 -0
  17. {fleche-0.22.0 → fleche-0.22.2}/docs/dev/function_profile.rst +9 -1
  18. {fleche-0.22.0 → fleche-0.22.2}/docs/dev/ssh_cache.rst +18 -8
  19. {fleche-0.22.0 → fleche-0.22.2}/docs/digests/digest_equivalence.rst +116 -1
  20. {fleche-0.22.0 → fleche-0.22.2}/docs/digests/digests_as_args.rst +12 -6
  21. {fleche-0.22.0 → fleche-0.22.2}/docs/digests/entry_points.rst +3 -6
  22. {fleche-0.22.0 → fleche-0.22.2}/docs/index.rst +0 -1
  23. {fleche-0.22.0 → fleche-0.22.2}/docs/installation.rst +11 -9
  24. {fleche-0.22.0 → fleche-0.22.2}/docs/parallel_execution.rst +13 -0
  25. {fleche-0.22.0 → fleche-0.22.2}/docs/storage/cache_stack.rst +4 -4
  26. {fleche-0.22.0 → fleche-0.22.2}/docs/storage/configuration.rst +97 -30
  27. {fleche-0.22.0 → fleche-0.22.2}/docs/usage/helpers.rst +18 -20
  28. {fleche-0.22.0 → fleche-0.22.2}/docs/usage/lazy_call.rst +5 -2
  29. {fleche-0.22.0 → fleche-0.22.2}/docs/usage/tldr.rst +7 -9
  30. {fleche-0.22.0 → fleche-0.22.2}/pyproject.toml +3 -3
  31. fleche-0.22.2/src/fleche/_pandas.py +110 -0
  32. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/_version.py +3 -3
  33. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/caches.py +6 -2
  34. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/call.py +29 -1
  35. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/config.py +6 -4
  36. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/digest.py +168 -36
  37. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/state.py +2 -2
  38. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/destructuring.py +2 -1
  39. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/file.py +1 -1
  40. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/sql.py +5 -2
  41. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/wrapper.py +10 -0
  42. {fleche-0.22.0 → fleche-0.22.2/src/fleche.egg-info}/PKG-INFO +7 -9
  43. {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/SOURCES.txt +7 -2
  44. {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/requires.txt +3 -3
  45. {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/scm_file_list.json +8 -3
  46. fleche-0.22.2/src/fleche.egg-info/scm_version.json +8 -0
  47. {fleche-0.22.0 → fleche-0.22.2}/tests/fixtures.py +73 -27
  48. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_hash_code_integration.py +23 -0
  49. fleche-0.22.2/tests/regression/test_issue_1004.py +68 -0
  50. {fleche-0.22.0 → fleche-0.22.2}/tests/strategies.py +14 -3
  51. fleche-0.22.2/tests/unit/call/test_code_digest.py +182 -0
  52. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_attrs.py +0 -12
  53. fleche-0.22.2/tests/unit/digest/test_attrs_optional_dep.py +56 -0
  54. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_digest.py +689 -44
  55. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_decorator_attributes.py +22 -1
  56. fleche-0.22.2/tests/unit/fleche/test_hash_code.py +82 -0
  57. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_destructuring_storage.py +4 -0
  58. fleche-0.22.2/tests/unit/storage/test_sql_evict.py +110 -0
  59. fleche-0.22.2/tests/unit/storage/test_sql_pragmas.py +221 -0
  60. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_pickle.py +20 -12
  61. fleche-0.22.0/.release-please-manifest.json +0 -3
  62. fleche-0.22.0/AGENTS.md +0 -29
  63. fleche-0.22.0/agents/DEVELOPING.md +0 -430
  64. fleche-0.22.0/agents/USAGE.md +0 -214
  65. fleche-0.22.0/docs/dev/extending_destructurer.rst +0 -70
  66. fleche-0.22.0/src/fleche.egg-info/scm_version.json +0 -8
  67. fleche-0.22.0/tests/unit/call/test_code_digest.py +0 -101
  68. fleche-0.22.0/tests/unit/fleche/test_hash_code.py +0 -41
  69. fleche-0.22.0/tests/unit/storage/test_sql_pragmas.py +0 -121
  70. fleche-0.22.0/x.db +0 -0
  71. {fleche-0.22.0 → fleche-0.22.2}/.claude/CLAUDE.md +0 -0
  72. {fleche-0.22.0 → fleche-0.22.2}/.claude/settings.json +0 -0
  73. {fleche-0.22.0 → fleche-0.22.2}/.github/dependabot.yml +0 -0
  74. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/benchmarks-main.yml +0 -0
  75. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/benchmarks.yml +0 -0
  76. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/pypi-publish.yml +0 -0
  77. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/release-please.yml +0 -0
  78. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/rendernb.yml +0 -0
  79. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/test-minimum-deps.yml +0 -0
  80. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/tests.yml +0 -0
  81. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/ty.yml +0 -0
  82. {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/updatebenchmarks.yml +0 -0
  83. {fleche-0.22.0 → fleche-0.22.2}/.gitignore +0 -0
  84. {fleche-0.22.0 → fleche-0.22.2}/.readthedocs.yaml +0 -0
  85. {fleche-0.22.0 → fleche-0.22.2}/LICENSE +0 -0
  86. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/benchmark_digest.py +0 -0
  87. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/benchmark_integration.py +0 -0
  88. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/benchmark_storage.py +0 -0
  89. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/compare_results.py +0 -0
  90. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/results.csv +0 -0
  91. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/run_benchmarks.py +0 -0
  92. {fleche-0.22.0 → fleche-0.22.2}/benchmarks/utils.py +0 -0
  93. {fleche-0.22.0 → fleche-0.22.2}/docs/_static/custom.css +0 -0
  94. {fleche-0.22.0 → fleche-0.22.2}/docs/conf.py +0 -0
  95. {fleche-0.22.0 → fleche-0.22.2}/docs/dev/sql_test_backends.rst +0 -0
  96. {fleche-0.22.0 → fleche-0.22.2}/docs/dev/storage_hierarchy.rst +0 -0
  97. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/cache_sequence.svg +0 -0
  98. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/dedup_forest.svg +0 -0
  99. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/gen_diagrams.py +0 -0
  100. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/gen_sequence.py +0 -0
  101. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/remaining_depth.svg +0 -0
  102. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/special_cases.svg +0 -0
  103. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_hierarchy.dot +0 -0
  104. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_hierarchy.svg +0 -0
  105. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_mro.dot +0 -0
  106. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_mro.svg +0 -0
  107. {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_sequence.svg +0 -0
  108. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/CacheStack.ipynb +0 -0
  109. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/Caches.ipynb +0 -0
  110. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/ConcurrentExecution.ipynb +0 -0
  111. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/Destructuring.ipynb +0 -0
  112. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/ExtraMethods.ipynb +0 -0
  113. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/FiveMinuteTour.ipynb +0 -0
  114. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/GettingStarted.ipynb +0 -0
  115. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/SecureStorage.ipynb +0 -0
  116. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/StorageBackends.ipynb +0 -0
  117. {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/TransferWorkflow.ipynb +0 -0
  118. {fleche-0.22.0 → fleche-0.22.2}/docs/storage/destructuring.rst +0 -0
  119. {fleche-0.22.0 → fleche-0.22.2}/docs/storage/security.rst +0 -0
  120. {fleche-0.22.0 → fleche-0.22.2}/docs/usage/query.rst +0 -0
  121. {fleche-0.22.0 → fleche-0.22.2}/notebooks/CacheStack.ipynb +0 -0
  122. {fleche-0.22.0 → fleche-0.22.2}/notebooks/Caches.ipynb +0 -0
  123. {fleche-0.22.0 → fleche-0.22.2}/notebooks/ConcurrentExecution.ipynb +0 -0
  124. {fleche-0.22.0 → fleche-0.22.2}/notebooks/Destructuring.ipynb +0 -0
  125. {fleche-0.22.0 → fleche-0.22.2}/notebooks/ExtraMethods.ipynb +0 -0
  126. {fleche-0.22.0 → fleche-0.22.2}/notebooks/FiveMinuteTour.ipynb +0 -0
  127. {fleche-0.22.0 → fleche-0.22.2}/notebooks/GettingStarted.ipynb +0 -0
  128. {fleche-0.22.0 → fleche-0.22.2}/notebooks/SecureStorage.ipynb +0 -0
  129. {fleche-0.22.0 → fleche-0.22.2}/notebooks/StorageBackends.ipynb +0 -0
  130. {fleche-0.22.0 → fleche-0.22.2}/notebooks/TransferWorkflow.ipynb +0 -0
  131. {fleche-0.22.0 → fleche-0.22.2}/release-please-config.json +0 -0
  132. {fleche-0.22.0 → fleche-0.22.2}/setup.cfg +0 -0
  133. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/__init__.py +0 -0
  134. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/__main__.py +0 -0
  135. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/_attrs.py +0 -0
  136. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/executor.py +0 -0
  137. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/metadata.py +0 -0
  138. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/query.py +0 -0
  139. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/remote.py +0 -0
  140. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/security.py +0 -0
  141. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/__init__.py +0 -0
  142. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/bagofholding_file.py +0 -0
  143. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/base.py +0 -0
  144. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/memory.py +0 -0
  145. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/pickle_file.py +0 -0
  146. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/thread_safe.py +0 -0
  147. {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/void.py +0 -0
  148. {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/dependency_links.txt +0 -0
  149. {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/top_level.txt +0 -0
  150. {fleche-0.22.0 → fleche-0.22.2}/tests/__init__.py +0 -0
  151. {fleche-0.22.0 → fleche-0.22.2}/tests/conftest.py +0 -0
  152. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/__init__.py +0 -0
  153. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_integration.py +0 -0
  154. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_methods.py +0 -0
  155. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_notebooks.py +0 -0
  156. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_parallel_execution.py +0 -0
  157. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_remote.py +0 -0
  158. {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_wrapper_query_integration.py +0 -0
  159. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/__init__.py +0 -0
  160. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_builtin_signature.py +0 -0
  161. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_217.py +0 -0
  162. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_297.py +0 -0
  163. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_319.py +0 -0
  164. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_352.py +0 -0
  165. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_451.py +0 -0
  166. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_452.py +0 -0
  167. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_485.py +0 -0
  168. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_578.py +0 -0
  169. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_592.py +0 -0
  170. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_691.py +0 -0
  171. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_sql_concurrent_save.py +0 -0
  172. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_sql_non_sqlite_backends.py +0 -0
  173. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_sql_table_uniqueness.py +0 -0
  174. {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_wrap_executor_cloudpickle_lock.py +0 -0
  175. {fleche-0.22.0 → fleche-0.22.2}/tests/smoke/__init__.py +0 -0
  176. {fleche-0.22.0 → fleche-0.22.2}/tests/smoke/test_optional_deps.py +0 -0
  177. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/__init__.py +0 -0
  178. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/__init__.py +0 -0
  179. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_cache.py +0 -0
  180. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_cache_pool.py +0 -0
  181. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_cache_stack.py +0 -0
  182. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_expand_shrink.py +0 -0
  183. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_filter.py +0 -0
  184. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_gc.py +0 -0
  185. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_lazy_call.py +0 -0
  186. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_operation_context_cache.py +0 -0
  187. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_readonly_cache.py +0 -0
  188. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_redigest.py +0 -0
  189. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_refreshing_cache.py +0 -0
  190. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_size_limited.py +0 -0
  191. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/__init__.py +0 -0
  192. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_dehydrate.py +0 -0
  193. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_matches.py +0 -0
  194. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_partial_binding.py +0 -0
  195. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_prepared_call.py +0 -0
  196. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/__init__.py +0 -0
  197. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_cache_from_config.py +0 -0
  198. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_cache_to_config.py +0 -0
  199. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_config.py +0 -0
  200. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_storage_to_config.py +0 -0
  201. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/__init__.py +0 -0
  202. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_digest_methods.py +0 -0
  203. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_entry_points.py +0 -0
  204. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/__init__.py +0 -0
  205. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_bound_wrapper.py +0 -0
  206. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_dataclass_input.py +0 -0
  207. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_digest_args.py +0 -0
  208. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_fleche.py +0 -0
  209. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_futures.py +0 -0
  210. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_ignore_digest.py +0 -0
  211. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_process_args.py +0 -0
  212. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_processpool.py +0 -0
  213. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_query_iterator.py +0 -0
  214. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_rerun.py +0 -0
  215. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_signature_binding.py +0 -0
  216. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_type_hints.py +0 -0
  217. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_workdir.py +0 -0
  218. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/metadata/__init__.py +0 -0
  219. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/metadata/test_metadata.py +0 -0
  220. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/__init__.py +0 -0
  221. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_bagofholding_file.py +0 -0
  222. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_destructuring_dataclasses.py +0 -0
  223. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_file_storage.py +0 -0
  224. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_mixins.py +0 -0
  225. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_operation_context.py +0 -0
  226. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_optional_deps.py +0 -0
  227. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_overwrite.py +0 -0
  228. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_pickle_file.py +0 -0
  229. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_secure_storage.py +0 -0
  230. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_short_digest.py +0 -0
  231. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_sql_digest_types.py +0 -0
  232. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_sql_query.py +0 -0
  233. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_sql_url_coercion.py +0 -0
  234. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_storage.py +0 -0
  235. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_thread_safe.py +0 -0
  236. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_transform.py +0 -0
  237. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_void.py +0 -0
  238. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_cache_sticky.py +0 -0
  239. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_executor.py +0 -0
  240. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_main.py +0 -0
  241. {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_remote.py +0 -0
@@ -25,7 +25,7 @@ jobs:
25
25
  with:
26
26
  claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
27
27
  claude_args: |
28
- --model claude-haiku-4-5
28
+ --model haiku
29
29
  --allowedTools "Bash(gh run view:*),Bash(gh run download:*),Bash(gh api:*),Bash(gh pr comment:*),Bash(gh pr list:*),Bash(gh issue create:*),Bash(cat:*),Bash(head:*),Bash(tail:*),Bash(grep:*),Bash(wc:*),Bash(ls:*)"
30
30
  prompt: |
31
31
  A CI run just failed. Investigate and post a concise summary.
@@ -53,6 +53,6 @@ jobs:
53
53
  - If still no PR, open an issue titled "CI failure on ${{ github.event.workflow_run.head_branch }} @ <short-sha>" with the summary as the body
54
54
  5. Prepend this header to whatever you post:
55
55
  `🤖 **CI failure summary** for [\`<short-sha>\`](${{ github.event.workflow_run.html_url }}) on \`${{ github.event.workflow_run.head_branch }}\``
56
- and append: `\n\n---\n_Generated by Claude Haiku 4.5._`
56
+ and append: `\n\n---\n_Generated by Claude Haiku._`
57
57
 
58
58
  Write the body to a temp file first (e.g. `/tmp/summary.md`) and use `--body-file` so markdown formatting survives intact.
@@ -34,9 +34,9 @@ jobs:
34
34
  # followed by whitespace, punctuation, or end-of-line, so a model is
35
35
  # selected with a space -- '@claude [haiku|sonnet|opus]'. This step only
36
36
  # maps that alias onto a --model arg; bare or unrecognised mentions fall
37
- # back to sonnet. (A glued '@claude[model]' would not trigger the action.)
37
+ # back to opus. (A glued '@claude[model]' would not trigger the action.)
38
38
  body="${COMMENT_BODY}${REVIEW_BODY}"
39
- model=sonnet
39
+ model=opus
40
40
  if [[ "$body" =~ @claude[[:space:]]*\[([a-zA-Z]+)\] ]]; then
41
41
  choice="${BASH_REMATCH[1],,}"
42
42
  case "$choice" in
@@ -53,6 +53,6 @@ jobs:
53
53
  - uses: anthropics/claude-code-action@v1
54
54
  with:
55
55
  claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
56
- claude_args: '--model ${{ steps.model.outputs.model }} --effort high --allowedTools WebFetch Bash(pip:*) Bash(python:*) Bash(pytest:*) Bash(git:*) Bash(gh pr:*)'
56
+ claude_args: '--model ${{ steps.model.outputs.model }} --effort high --allowedTools WebFetch Bash(pip:*) Bash(python:*) Bash(pytest:*) Bash(ty:*) Bash(uv:*) Bash(jupyter:*) Bash(git:*) Bash(gh pr:*) Bash(gh run:*)'
57
57
  additional_permissions: |
58
58
  actions: read
@@ -41,7 +41,7 @@ jobs:
41
41
  with:
42
42
  claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
43
43
  claude_args: |
44
- --model claude-haiku-4-5
44
+ --model haiku
45
45
  --allowedTools "Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr edit:*),Bash(gh label list:*),Bash(gh label create:*)"
46
46
  prompt: |
47
47
  You are triaging a pull request to decide whether it is
@@ -0,0 +1,57 @@
1
+ name: reflow agent docs
2
+
3
+ # Keeps AGENTS.md and agents/*.md at one sentence per line (see the
4
+ # Conventions section of agents/DEVELOPING.md). On a same-repo PR the reflowed
5
+ # files are committed back to the branch; a fork PR cannot be pushed to, so
6
+ # there the job fails and asks the author to run the script.
7
+
8
+ on:
9
+ pull_request:
10
+ types: [opened, synchronize, reopened]
11
+ paths:
12
+ - 'AGENTS.md'
13
+ - 'agents/*.md'
14
+ - '.github/workflows/reflow_agent_docs.py'
15
+ - '.github/workflows/reflow-agent-docs.yml'
16
+
17
+ concurrency:
18
+ group: reflow-agent-docs-${{ github.head_ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ reflow:
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ contents: write
26
+ env:
27
+ SAME_REPO: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
28
+ HEAD_REF: ${{ github.event.pull_request.head.ref }}
29
+ steps:
30
+ - uses: actions/checkout@v6
31
+ with:
32
+ ref: ${{ github.event.pull_request.head.ref }}
33
+ repository: ${{ github.event.pull_request.head.repo.full_name }}
34
+ - uses: actions/setup-python@v6
35
+ with:
36
+ python-version: "3.12"
37
+ - name: Reflow (fork PR, check only)
38
+ if: env.SAME_REPO != 'true'
39
+ run: |
40
+ python .github/workflows/reflow_agent_docs.py --check || {
41
+ echo "::error::Agent docs need reflowing; run 'python .github/workflows/reflow_agent_docs.py' and push."
42
+ exit 1
43
+ }
44
+ - name: Reflow
45
+ if: env.SAME_REPO == 'true'
46
+ run: python .github/workflows/reflow_agent_docs.py
47
+ - name: Commit and push
48
+ if: env.SAME_REPO == 'true'
49
+ run: |
50
+ if git diff --quiet; then
51
+ echo "Agent docs already one sentence per line."
52
+ exit 0
53
+ fi
54
+ git -c user.name="github-actions[bot]" \
55
+ -c user.email="41898282+github-actions[bot]@users.noreply.github.com" \
56
+ commit -am "docs(agents): reflow to one sentence per line"
57
+ git push origin "HEAD:refs/heads/$HEAD_REF"
@@ -0,0 +1,160 @@
1
+ """Reflow the agent guides to one sentence per line (semantic line breaks).
2
+
3
+ Usage (from anywhere in the repo):
4
+
5
+ python .github/workflows/reflow_agent_docs.py # rewrite AGENTS.md and agents/*.md in place
6
+ python .github/workflows/reflow_agent_docs.py --check # list files that need reflowing; exit 1 if any
7
+ python .github/workflows/reflow_agent_docs.py FILE... # only these files
8
+
9
+ CI runs it on every PR touching those files (reflow-agent-docs.yml) and
10
+ commits the result back to the PR branch.
11
+
12
+ Every sentence and every ``;``-separated clause starts its own line, and long
13
+ ```a`, `b`, `c``` enumerations break before each item.
14
+ Code fences, tables, headings and HTML are left alone.
15
+ The rewrite is whitespace-only: it refuses to write a file whose word sequence
16
+ would change, and running it twice is a no-op.
17
+ """
18
+
19
+ import argparse
20
+ import re
21
+ import sys
22
+ from pathlib import Path
23
+
24
+ ROOT = Path(__file__).resolve().parents[2]
25
+ ABBREVIATIONS = ("e.g.", "i.e.", "vs.", "etc.", "cf.", "approx.", "resp.")
26
+ LIST_ITEM = re.compile(r"^(\s*)([-*+]|\d+\.)\s+")
27
+ ENUM_LIMIT = 200 # only split ``, `item`` enumerations on lines longer than this
28
+ UNTOUCHED = ("#", "|", "<", "---")
29
+
30
+
31
+ def _skip_code_span(text: str, i: int) -> int:
32
+ """Return the index just past the code span opening at ``text[i]``."""
33
+ j = i
34
+ while j < len(text) and text[j] == "`":
35
+ j += 1
36
+ close = text.find(text[i:j], j)
37
+ return close + (j - i) if close != -1 else j
38
+
39
+
40
+ def split_sentences(text: str) -> list[str]:
41
+ """Split after ``.``/``;``/``?``/``!`` followed by a space, outside code spans."""
42
+ parts, start, i = [], 0, 0
43
+ while i < len(text):
44
+ c = text[i]
45
+ if c == "`":
46
+ i = _skip_code_span(text, i)
47
+ continue
48
+ if c in ".;?!" and text[i + 1 : i + 2] == " " and text[i + 1 :].strip():
49
+ head = text[start : i + 1]
50
+ word = head.split()[-1] if head.strip() else ""
51
+ abbreviation = word.lower().endswith(ABBREVIATIONS)
52
+ # "1. " or a lone initial like "A. "
53
+ ordinal = c == "." and len(word) <= 2
54
+ if not (abbreviation or ordinal):
55
+ parts.append(head.strip())
56
+ start = i + 1
57
+ i += 1
58
+ if text[start:].strip():
59
+ parts.append(text[start:].strip())
60
+ return parts
61
+
62
+
63
+ def split_enumeration(text: str) -> list[str]:
64
+ """Break a long line before each top-level ``, `item`` entry."""
65
+ if len(text) <= ENUM_LIMIT:
66
+ return [text]
67
+ parts, start, depth, i = [], 0, 0, 0
68
+ while i < len(text):
69
+ c = text[i]
70
+ if c == "`":
71
+ i = _skip_code_span(text, i)
72
+ continue
73
+ if c in "([{":
74
+ depth += 1
75
+ elif c in ")]}":
76
+ depth = max(0, depth - 1)
77
+ elif c == "," and depth == 0 and text.startswith(" `", i + 1):
78
+ parts.append(text[start : i + 1].strip())
79
+ start = i + 1
80
+ i += 1
81
+ parts.append(text[start:].strip())
82
+ return parts
83
+
84
+
85
+ def _emit(prefix: str, indent: str, text: str) -> list[str]:
86
+ parts = [e for s in split_sentences(text) for e in split_enumeration(s)]
87
+ return [prefix + parts[0]] + [indent + p for p in parts[1:]]
88
+
89
+
90
+ def _is_continuation(line: str, also_stop: tuple[str, ...] = ()) -> bool:
91
+ s = line.lstrip()
92
+ return bool(s) and not LIST_ITEM.match(line) and not s.startswith(("```", "|", "#") + also_stop)
93
+
94
+
95
+ def reflow(src: str) -> str:
96
+ lines = src.split("\n")
97
+ out: list[str] = []
98
+ i, in_fence = 0, False
99
+ while i < len(lines):
100
+ line = lines[i]
101
+ s = line.lstrip()
102
+ if s.startswith("```"):
103
+ in_fence = not in_fence
104
+ if in_fence or s.startswith("```") or not s or s.startswith(UNTOUCHED):
105
+ out.append(line)
106
+ i += 1
107
+ elif s.startswith(">"):
108
+ buf = []
109
+ while i < len(lines) and lines[i].lstrip().startswith(">"):
110
+ buf.append(lines[i].lstrip()[1:].strip())
111
+ i += 1
112
+ out += _emit("> ", "> ", " ".join(buf))
113
+ elif m := LIST_ITEM.match(line):
114
+ prefix = m.group(0)
115
+ buf = [line[len(prefix) :].strip()]
116
+ i += 1
117
+ while i < len(lines) and _is_continuation(lines[i]):
118
+ buf.append(lines[i].strip())
119
+ i += 1
120
+ out += _emit(prefix, " " * len(prefix), " ".join(buf))
121
+ else:
122
+ lead = line[: len(line) - len(s)]
123
+ buf = []
124
+ while i < len(lines) and _is_continuation(lines[i], also_stop=(">",)):
125
+ buf.append(lines[i].strip())
126
+ i += 1
127
+ out += _emit(lead, lead, " ".join(buf))
128
+ return "\n".join(out)
129
+
130
+
131
+ def _words(text: str) -> list[str]:
132
+ return [w for w in text.split() if w != ">"]
133
+
134
+
135
+ def main(argv: list[str] | None = None) -> int:
136
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
137
+ parser.add_argument("files", nargs="*", type=Path, help="default: AGENTS.md and agents/*.md")
138
+ parser.add_argument("--check", action="store_true", help="report files that need reflowing; don't write")
139
+ args = parser.parse_args(argv)
140
+
141
+ files = args.files or [ROOT / "AGENTS.md", *sorted((ROOT / "agents").glob("*.md"))]
142
+ dirty = []
143
+ for path in files:
144
+ old = path.read_text()
145
+ new = reflow(old)
146
+ if _words(old) != _words(new):
147
+ print(f"{path}: reflow would change words, not just line breaks — skipped", file=sys.stderr)
148
+ return 2
149
+ if new != old:
150
+ dirty.append(path)
151
+ if not args.check:
152
+ path.write_text(new)
153
+ for path in dirty:
154
+ shown = path.relative_to(ROOT) if path.is_relative_to(ROOT) else path
155
+ print(f"{'needs reflow' if args.check else 'reflowed'}: {shown}")
156
+ return 1 if args.check and dirty else 0
157
+
158
+
159
+ if __name__ == "__main__":
160
+ sys.exit(main())
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.22.2"
3
+ }
@@ -0,0 +1,33 @@
1
+ # AGENTS.md
2
+
3
+ Cross-tool entry point for AI coding agents (Codex, Cursor, Aider, Claude, ...).
4
+
5
+ **Fleche** is a persistent function cache for Python (`@fleche()`) — like `lru_cache` but it survives restarts, with SHA256 content-based keys and pluggable storage backends (memory, pickle-family, HDF5, SQL, SSH).
6
+
7
+ This file is deliberately short.
8
+ Pick the guide that matches what you're doing:
9
+
10
+ | Task | Guide |
11
+ |---|---|
12
+ | Writing code that *calls* fleche — decorating functions, configuring a cache via `fleche.toml`, choosing a storage backend, querying stored calls | **[agents/USAGE.md](agents/USAGE.md)** |
13
+ | Changing fleche's *own* source — commands, tests, module map, architecture internals, open design themes on the issue tracker, commit conventions | **[agents/DEVELOPING.md](agents/DEVELOPING.md)** |
14
+
15
+ When editing this file or `agents/*.md`, write **one sentence per line** (and one `;`-clause per line);
16
+ never hard-wrap or join lines.
17
+ `python .github/workflows/reflow_agent_docs.py` applies this for you.
18
+ Many PRs edit these guides at once, and line-per-sentence keeps their diffs small and mergeable.
19
+ See [agents/DEVELOPING.md](agents/DEVELOPING.md#conventions).
20
+
21
+ Full human-facing docs (Sphinx) live in `docs/`;
22
+ runnable examples live in `notebooks/`.
23
+
24
+ ## In a hurry
25
+
26
+ ```bash
27
+ pip install -e ".[tests]" # install with test deps
28
+ pytest tests/ # run tests
29
+ ty check src/ # type check
30
+ ```
31
+
32
+ Python `>=3.11,<3.15`.
33
+ Conventional Commits are required on every commit message (`feat:`/`fix:`/`docs:`/`test:`/`chore:`/`refactor:`) — see [agents/DEVELOPING.md](agents/DEVELOPING.md#commit-messages) for why and how.
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.2](https://github.com/pmrv/fleche/compare/0.22.1...0.22.2) (2026-10-23)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **digest:** digest object and structured numpy arrays by value ([#1010](https://github.com/pmrv/fleche/issues/1010)) ([35fae96](https://github.com/pmrv/fleche/commit/35fae964b3b1c7bc7ff2301fd830baad6c360538))
9
+ * **digest:** hash pandas object columns pandas cannot hash faithfully ([#1006](https://github.com/pmrv/fleche/issues/1006)) ([c0eed1b](https://github.com/pmrv/fleche/commit/c0eed1bd75c1f5ff0c19d8ddb13baa1158653a13))
10
+
11
+ ## [0.22.1](https://github.com/pmrv/fleche/compare/0.22.0...0.22.1) (2026-09-03)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **digest:** fold captured variables and argument defaults into function digests ([#909](https://github.com/pmrv/fleche/issues/909)) ([cb9ed6c](https://github.com/pmrv/fleche/commit/cb9ed6c3e7c0f1a246b007cd023a28b8b72a52a9))
17
+
3
18
  ## [0.22.0](https://github.com/pmrv/fleche/compare/0.21.2...0.22.0) (2026-08-28)
4
19
 
5
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleche
3
- Version: 0.22.0
3
+ Version: 0.22.2
4
4
  Summary: Hierachical, persistant caches in python
5
5
  Author-email: Marvin Poul <pmrv@posteo.de>
6
6
  License-Expression: BSD-3-Clause
@@ -26,7 +26,7 @@ Requires-Dist: dill>=0.3; extra == "dill"
26
26
  Provides-Extra: sqlalchemy
27
27
  Requires-Dist: sqlalchemy>=2; extra == "sqlalchemy"
28
28
  Provides-Extra: bagofholding
29
- Requires-Dist: bagofholding==0.1.12; extra == "bagofholding"
29
+ Requires-Dist: bagofholding<0.1.17,>=0.1.12; extra == "bagofholding"
30
30
  Provides-Extra: ssh
31
31
  Requires-Dist: cloudpickle>=2; extra == "ssh"
32
32
  Provides-Extra: tests
@@ -35,7 +35,7 @@ Requires-Dist: hypothesis>=6.100; extra == "tests"
35
35
  Requires-Dist: cloudpickle>=2; extra == "tests"
36
36
  Requires-Dist: dill>=0.3; extra == "tests"
37
37
  Requires-Dist: sqlalchemy>=2; extra == "tests"
38
- Requires-Dist: bagofholding==0.1.12; extra == "tests"
38
+ Requires-Dist: bagofholding<0.1.17,>=0.1.12; extra == "tests"
39
39
  Requires-Dist: nbconvert>=6.5; extra == "tests"
40
40
  Requires-Dist: ipykernel>=6.26; extra == "tests"
41
41
  Requires-Dist: tabulate>=0.8; extra == "tests"
@@ -43,16 +43,14 @@ Requires-Dist: attrs>=21.3; extra == "tests"
43
43
  Provides-Extra: executorlib
44
44
  Requires-Dist: executorlib; extra == "executorlib"
45
45
  Provides-Extra: ty
46
- Requires-Dist: ty==0.0.74; extra == "ty"
46
+ Requires-Dist: ty==0.0.89; extra == "ty"
47
47
  Dynamic: license-file
48
48
 
49
49
  # fleche
50
50
 
51
51
  [![docs](https://app.readthedocs.org/projects/fleche/badge/?version=latest)](https://fleche.readthedocs.io/en/latest/?badge=latest)
52
52
 
53
-
54
-
55
-
53
+ Requires Python 3.11–3.14.
56
54
 
57
55
  A persistent caching solution for arbitrary Python functions - like `lru_cache` on steroids.
58
56
 
@@ -162,7 +160,7 @@ if compute.contains(5):
162
160
  else:
163
161
  result = compute(5)
164
162
 
165
- # Get Call object with metadata
163
+ # Get the Call object used for lookup (no result/metadata yet — see .query() for stored metadata)
166
164
  call = compute.call(5)
167
165
  ```
168
166
 
@@ -281,6 +279,6 @@ BSD-3-Clause License - see LICENSE file for details.
281
279
 
282
280
  ## Resources
283
281
 
284
- - **Documentation**: See `docs/` directory
282
+ - **Documentation**: https://fleche.readthedocs.io
285
283
  - **Tests**: See `tests/` for usage examples
286
284
  - **Benchmarks**: See `benchmarks/` for performance metrics
@@ -2,9 +2,7 @@
2
2
 
3
3
  [![docs](https://app.readthedocs.org/projects/fleche/badge/?version=latest)](https://fleche.readthedocs.io/en/latest/?badge=latest)
4
4
 
5
-
6
-
7
-
5
+ Requires Python 3.11–3.14.
8
6
 
9
7
  A persistent caching solution for arbitrary Python functions - like `lru_cache` on steroids.
10
8
 
@@ -114,7 +112,7 @@ if compute.contains(5):
114
112
  else:
115
113
  result = compute(5)
116
114
 
117
- # Get Call object with metadata
115
+ # Get the Call object used for lookup (no result/metadata yet — see .query() for stored metadata)
118
116
  call = compute.call(5)
119
117
  ```
120
118
 
@@ -233,6 +231,6 @@ BSD-3-Clause License - see LICENSE file for details.
233
231
 
234
232
  ## Resources
235
233
 
236
- - **Documentation**: See `docs/` directory
234
+ - **Documentation**: https://fleche.readthedocs.io
237
235
  - **Tests**: See `tests/` for usage examples
238
236
  - **Benchmarks**: See `benchmarks/` for performance metrics