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.
- fleche-0.22.0/.github/workflows/claude_ci_details.yaml → fleche-0.22.2/.github/workflows/ci-failure-summary.yml +2 -2
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/claude.yaml +3 -3
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/perf-triage.yml +1 -1
- fleche-0.22.2/.github/workflows/reflow-agent-docs.yml +57 -0
- fleche-0.22.2/.github/workflows/reflow_agent_docs.py +160 -0
- fleche-0.22.2/.release-please-manifest.json +3 -0
- fleche-0.22.2/AGENTS.md +33 -0
- {fleche-0.22.0 → fleche-0.22.2}/CHANGELOG.md +15 -0
- {fleche-0.22.0/src/fleche.egg-info → fleche-0.22.2}/PKG-INFO +7 -9
- {fleche-0.22.0 → fleche-0.22.2}/README.md +3 -5
- fleche-0.22.2/agents/DEVELOPING.md +1028 -0
- fleche-0.22.2/agents/USAGE.md +172 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/profile_digest_types.py +18 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/dev/call_lifecycle.rst +51 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/dev/custom_digests.rst +20 -0
- fleche-0.22.2/docs/dev/extending_destructurer.rst +119 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/dev/function_profile.rst +9 -1
- {fleche-0.22.0 → fleche-0.22.2}/docs/dev/ssh_cache.rst +18 -8
- {fleche-0.22.0 → fleche-0.22.2}/docs/digests/digest_equivalence.rst +116 -1
- {fleche-0.22.0 → fleche-0.22.2}/docs/digests/digests_as_args.rst +12 -6
- {fleche-0.22.0 → fleche-0.22.2}/docs/digests/entry_points.rst +3 -6
- {fleche-0.22.0 → fleche-0.22.2}/docs/index.rst +0 -1
- {fleche-0.22.0 → fleche-0.22.2}/docs/installation.rst +11 -9
- {fleche-0.22.0 → fleche-0.22.2}/docs/parallel_execution.rst +13 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/storage/cache_stack.rst +4 -4
- {fleche-0.22.0 → fleche-0.22.2}/docs/storage/configuration.rst +97 -30
- {fleche-0.22.0 → fleche-0.22.2}/docs/usage/helpers.rst +18 -20
- {fleche-0.22.0 → fleche-0.22.2}/docs/usage/lazy_call.rst +5 -2
- {fleche-0.22.0 → fleche-0.22.2}/docs/usage/tldr.rst +7 -9
- {fleche-0.22.0 → fleche-0.22.2}/pyproject.toml +3 -3
- fleche-0.22.2/src/fleche/_pandas.py +110 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/_version.py +3 -3
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/caches.py +6 -2
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/call.py +29 -1
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/config.py +6 -4
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/digest.py +168 -36
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/state.py +2 -2
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/destructuring.py +2 -1
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/file.py +1 -1
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/sql.py +5 -2
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/wrapper.py +10 -0
- {fleche-0.22.0 → fleche-0.22.2/src/fleche.egg-info}/PKG-INFO +7 -9
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/SOURCES.txt +7 -2
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/requires.txt +3 -3
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/scm_file_list.json +8 -3
- fleche-0.22.2/src/fleche.egg-info/scm_version.json +8 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/fixtures.py +73 -27
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_hash_code_integration.py +23 -0
- fleche-0.22.2/tests/regression/test_issue_1004.py +68 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/strategies.py +14 -3
- fleche-0.22.2/tests/unit/call/test_code_digest.py +182 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_attrs.py +0 -12
- fleche-0.22.2/tests/unit/digest/test_attrs_optional_dep.py +56 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_digest.py +689 -44
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_decorator_attributes.py +22 -1
- fleche-0.22.2/tests/unit/fleche/test_hash_code.py +82 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_destructuring_storage.py +4 -0
- fleche-0.22.2/tests/unit/storage/test_sql_evict.py +110 -0
- fleche-0.22.2/tests/unit/storage/test_sql_pragmas.py +221 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_pickle.py +20 -12
- fleche-0.22.0/.release-please-manifest.json +0 -3
- fleche-0.22.0/AGENTS.md +0 -29
- fleche-0.22.0/agents/DEVELOPING.md +0 -430
- fleche-0.22.0/agents/USAGE.md +0 -214
- fleche-0.22.0/docs/dev/extending_destructurer.rst +0 -70
- fleche-0.22.0/src/fleche.egg-info/scm_version.json +0 -8
- fleche-0.22.0/tests/unit/call/test_code_digest.py +0 -101
- fleche-0.22.0/tests/unit/fleche/test_hash_code.py +0 -41
- fleche-0.22.0/tests/unit/storage/test_sql_pragmas.py +0 -121
- fleche-0.22.0/x.db +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.claude/CLAUDE.md +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.claude/settings.json +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/dependabot.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/benchmarks-main.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/benchmarks.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/pypi-publish.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/release-please.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/rendernb.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/test-minimum-deps.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/tests.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/ty.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.github/workflows/updatebenchmarks.yml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.gitignore +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/.readthedocs.yaml +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/LICENSE +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/benchmark_digest.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/benchmark_integration.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/benchmark_storage.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/compare_results.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/results.csv +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/run_benchmarks.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/benchmarks/utils.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/_static/custom.css +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/conf.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/dev/sql_test_backends.rst +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/dev/storage_hierarchy.rst +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/cache_sequence.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/dedup_forest.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/gen_diagrams.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/gen_sequence.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/remaining_depth.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/special_cases.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_hierarchy.dot +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_hierarchy.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_mro.dot +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_mro.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/figures/storage_sequence.svg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/CacheStack.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/Caches.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/ConcurrentExecution.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/Destructuring.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/ExtraMethods.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/FiveMinuteTour.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/GettingStarted.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/SecureStorage.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/StorageBackends.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/notebooks/TransferWorkflow.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/storage/destructuring.rst +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/storage/security.rst +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/docs/usage/query.rst +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/CacheStack.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/Caches.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/ConcurrentExecution.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/Destructuring.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/ExtraMethods.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/FiveMinuteTour.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/GettingStarted.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/SecureStorage.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/StorageBackends.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/notebooks/TransferWorkflow.ipynb +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/release-please-config.json +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/setup.cfg +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/__main__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/_attrs.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/executor.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/metadata.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/query.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/remote.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/security.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/bagofholding_file.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/base.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/memory.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/pickle_file.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/thread_safe.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche/storage/void.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/dependency_links.txt +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/src/fleche.egg-info/top_level.txt +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/conftest.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_integration.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_methods.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_notebooks.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_parallel_execution.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_remote.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/integration/test_wrapper_query_integration.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_builtin_signature.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_217.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_297.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_319.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_352.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_451.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_452.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_485.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_578.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_592.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_issue_691.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_sql_concurrent_save.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_sql_non_sqlite_backends.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_sql_table_uniqueness.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/regression/test_wrap_executor_cloudpickle_lock.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/smoke/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/smoke/test_optional_deps.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_cache.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_cache_pool.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_cache_stack.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_expand_shrink.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_filter.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_gc.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_lazy_call.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_operation_context_cache.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_readonly_cache.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_redigest.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_refreshing_cache.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/caches/test_size_limited.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_dehydrate.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_matches.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_partial_binding.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/call/test_prepared_call.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_cache_from_config.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_cache_to_config.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_config.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/config/test_storage_to_config.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_digest_methods.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/digest/test_entry_points.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_bound_wrapper.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_dataclass_input.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_digest_args.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_fleche.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_futures.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_ignore_digest.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_process_args.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_processpool.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_query_iterator.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_rerun.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_signature_binding.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_type_hints.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/fleche/test_workdir.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/metadata/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/metadata/test_metadata.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/__init__.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_bagofholding_file.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_destructuring_dataclasses.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_file_storage.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_mixins.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_operation_context.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_optional_deps.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_overwrite.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_pickle_file.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_secure_storage.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_short_digest.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_sql_digest_types.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_sql_query.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_sql_url_coercion.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_storage.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_thread_safe.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_transform.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/storage/test_void.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_cache_sticky.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_executor.py +0 -0
- {fleche-0.22.0 → fleche-0.22.2}/tests/unit/test_main.py +0 -0
- {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
|
|
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
|
|
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
|
|
37
|
+
# back to opus. (A glued '@claude[model]' would not trigger the action.)
|
|
38
38
|
body="${COMMENT_BODY}${REVIEW_BODY}"
|
|
39
|
-
model=
|
|
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
|
|
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())
|
fleche-0.22.2/AGENTS.md
ADDED
|
@@ -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.
|
|
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
|
|
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
|
|
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.
|
|
46
|
+
Requires-Dist: ty==0.0.89; extra == "ty"
|
|
47
47
|
Dynamic: license-file
|
|
48
48
|
|
|
49
49
|
# fleche
|
|
50
50
|
|
|
51
51
|
[](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
|
|
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**:
|
|
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
|
[](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
|
|
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**:
|
|
234
|
+
- **Documentation**: https://fleche.readthedocs.io
|
|
237
235
|
- **Tests**: See `tests/` for usage examples
|
|
238
236
|
- **Benchmarks**: See `benchmarks/` for performance metrics
|