counted-float 1.1.1__tar.gz → 1.1.3__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 (96) hide show
  1. {counted_float-1.1.1 → counted_float-1.1.3}/.gitignore +4 -3
  2. {counted_float-1.1.1 → counted_float-1.1.3}/PKG-INFO +34 -10
  3. {counted_float-1.1.1 → counted_float-1.1.3}/pyproject.toml +65 -11
  4. counted_float-1.1.1/README.md +0 -701
  5. {counted_float-1.1.1 → counted_float-1.1.3}/LICENSE +0 -0
  6. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/__init__.py +0 -0
  7. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/__init__.py +0 -0
  8. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/_cli.py +0 -0
  9. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/__init__.py +0 -0
  10. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/counted_float/__init__.py +0 -0
  11. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/counted_float/_counted_float_benchmark.py +0 -0
  12. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/flops/__init__.py +0 -0
  13. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/flops/_array_generator.py +0 -0
  14. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/flops/_flops_benchmark_suite.py +0 -0
  15. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/flops/_flops_micro_benchmark.py +0 -0
  16. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/micro/__init__.py +0 -0
  17. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/benchmarking/micro/_micro_benchmark.py +0 -0
  18. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/compatibility/__init__.py +0 -0
  19. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/compatibility/_numba.py +0 -0
  20. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/__init__.py +0 -0
  21. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/_builtin_data.py +0 -0
  22. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/_context_managers.py +0 -0
  23. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/_counted_float.py +0 -0
  24. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/_global_counter.py +0 -0
  25. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/_math_patching.py +0 -0
  26. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/config/__init__.py +0 -0
  27. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/config/_config.py +0 -0
  28. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/counting/config/_defaults.py +0 -0
  29. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/__init__.py +0 -0
  30. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_base.py +0 -0
  31. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_flop_counts.py +0 -0
  32. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_flop_type.py +0 -0
  33. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_flop_weights.py +0 -0
  34. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_flops_benchmark_meta_data.py +0 -0
  35. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_flops_benchmark_result.py +0 -0
  36. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_flops_benchmark_type.py +0 -0
  37. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_instruction_latencies.py +0 -0
  38. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/models/_micro_benchmark_result.py +0 -0
  39. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/__init__.py +0 -0
  40. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_cpu_freq.py +0 -0
  41. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_formatting.py +0 -0
  42. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_geo_mean.py +0 -0
  43. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_latency.py +0 -0
  44. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_missing_data.py +0 -0
  45. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_rounding.py +0 -0
  46. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/_core/utils/_timer.py +0 -0
  47. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/benchmarking/__init__.py +0 -0
  48. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/config/__init__.py +0 -0
  49. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/benchmarks/apple_m1_github_actions.json +0 -0
  50. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/benchmarks/apple_m3_max_mbp16.json +0 -0
  51. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/benchmarks/apple_m3_mba15.json +0 -0
  52. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/benchmarks/aws_graviton_2_neoverse_n1_ec2_m6g_xlarge.json +0 -0
  53. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/benchmarks/aws_graviton_3_neoverse_v1_ec2_m7g_xlarge.json +0 -0
  54. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/specs/arm_cortex_a76.json +0 -0
  55. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/specs/arm_cortex_x1.json +0 -0
  56. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/specs/arm_neoverse_n1.json +0 -0
  57. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v8_x/specs/arm_neoverse_v1.json +0 -0
  58. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_0/benchmarks/aws_graviton_4_neoverse_v2_ec2_m8g_xlarge.json +0 -0
  59. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_0/benchmarks/azure_cobalt_100_neoverse_n2_github_actions.json +0 -0
  60. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_0/specs/arm_cortex_x2.json +0 -0
  61. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_0/specs/arm_cortex_x3.json +0 -0
  62. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_0/specs/arm_neoverse_n2.json +0 -0
  63. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_0/specs/arm_neoverse_v2.json +0 -0
  64. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_2/benchmarks/apple_m4_pro_mbp16.json +0 -0
  65. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_2/specs/arm_cortex_x4.json +0 -0
  66. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_2/specs/arm_cortex_x925.json +0 -0
  67. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/arm/v9_2/specs/arm_neoverse_v3.json +0 -0
  68. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2017_zen1/benchmarks/amd_ryzen_1700x.json +0 -0
  69. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2017_zen1/other/analysis_uops_info_zen1+.json +0 -0
  70. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2020_zen3/benchmark/amd_epyc_7763_linux_github.json +0 -0
  71. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2020_zen3/benchmark/amd_epyc_7763_windows_github.json +0 -0
  72. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2020_zen3/other/analysis_agner_fog_r7_5800x.json +0 -0
  73. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2020_zen3/other/analysis_uops_info_zen3.json +0 -0
  74. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2022_zen4/benchmark/amd_epyc_9r14_ec2_m7a_xlarge.json +0 -0
  75. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2022_zen4/other/analysis_agner_fog_r9_7900x.json +0 -0
  76. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2022_zen4/other/analysis_uops_info_zen4.json +0 -0
  77. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2022_zen4/other/specs_amd.json +0 -0
  78. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2024_zen5/benchmark/amd_epyc_9r45_ec2_m8a_xlarge.json +0 -0
  79. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2024_zen5/other/analysis_agner_fog_r7_9800x3d.json +0 -0
  80. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/amd/2024_zen5/other/specs_amd.json +0 -0
  81. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmarks/intel_i7_8550U_windows.json +0 -0
  82. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/benchmarks/intel_i7_8700B_macos_github_actions.json +0 -0
  83. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/other/analysis_agner_fog_coffee_lake.json +0 -0
  84. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2017_coffee_lake_gen_8/other/analysis_uops_info_coffee_lake.json +0 -0
  85. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/benchmarks/intel_xeon_8375c_ice_lake_ec2_m6i_xlarge.json +0 -0
  86. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/other/analysis_agner_fog_ice_lake.json +0 -0
  87. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/other/analysis_uops_info_ice_lake.json +0 -0
  88. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2019_sunny_cove_gen_10/other/analysis_uops_info_tiger_lake.json +0 -0
  89. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2021_golden_cove_gen_12/benchmarks/intel_xeon_8488c_sapphire_rapids_ec2_m7i_xlarge.json +0 -0
  90. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2021_golden_cove_gen_12/other/analysis_uops_info_alder_lake_p.json +0 -0
  91. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2021_golden_cove_gen_12/other/specs_intel.json +0 -0
  92. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/benchmarks/intel_xeon_8559c_emerald_rapids_ec2_i7i_xlarge.json +0 -0
  93. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2022_raptor_cove_gen_13_14/other/specs_intel.json +0 -0
  94. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/benchmarks/intel_xeon_6975p_granite_rapids_ec2_m8i_xlarge.json +0 -0
  95. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/data/x86/intel/2023_redwood_cove_ultra_1/other/specs_intel.json +0 -0
  96. {counted_float-1.1.1 → counted_float-1.1.3}/counted_float/py.typed +0 -0
@@ -3,17 +3,18 @@ dist
3
3
  *.tar.gz
4
4
  *.whl
5
5
 
6
- # no need to track uv.lock for a Python package (where deps are not pinned)
7
- uv.lock
8
-
9
6
  # Python cache files
10
7
  __pycache__
11
8
  *.pyc
12
9
 
13
10
  # Coverage reports
14
11
  .coverage
12
+ .coverage.*
15
13
  htmlcov
16
14
 
15
+ # CI metrics artifact (generated by the coverage job, never committed)
16
+ metrics.json
17
+
17
18
  # Jupyter Notebook checkpoints
18
19
  .ipynb_checkpoints
19
20
 
@@ -1,28 +1,52 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: counted-float
3
- Version: 1.1.1
3
+ Version: 1.1.3
4
4
  Summary: Count floating-point operations in Python code & benchmark relative flop costs.
5
5
  Project-URL: Source, https://github.com/bertpl/counted-float
6
6
  Project-URL: ChangeLog, https://github.com/bertpl/counted-float/blob/main/CHANGELOG.md
7
7
  Project-URL: Issues, https://github.com/bertpl/counted-float/issues
8
8
  Project-URL: Roadmap, https://github.com/bertpl/counted-float/milestones
9
9
  License-File: LICENSE
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Scientific/Engineering
10
20
  Requires-Python: >=3.11
11
- Requires-Dist: numpy>=1.20
12
- Requires-Dist: psutil>=5.0
21
+ Requires-Dist: numpy>=1.23.2; python_version < '3.12'
22
+ Requires-Dist: numpy>=1.26.0; python_version == '3.12'
23
+ Requires-Dist: numpy>=2.1.0; python_version == '3.13'
24
+ Requires-Dist: numpy>=2.3.2; python_version >= '3.14'
25
+ Requires-Dist: psutil>=5.9.4; python_version < '3.13'
26
+ Requires-Dist: psutil>=7.1.2; python_version >= '3.13'
13
27
  Requires-Dist: py-cpuinfo>=9.0.0
14
- Requires-Dist: pydantic>=2.0.0
28
+ Requires-Dist: pydantic>=2.12; python_version >= '3.14'
29
+ Requires-Dist: pydantic>=2.6; python_version < '3.13'
30
+ Requires-Dist: pydantic>=2.9; python_version == '3.13'
15
31
  Requires-Dist: rich>=13.0.0
16
32
  Provides-Extra: cli
17
33
  Requires-Dist: click>=8.0.0; extra == 'cli'
18
34
  Provides-Extra: numba
19
- Requires-Dist: numba>=0.50; extra == 'numba'
35
+ Requires-Dist: numba>=0.57; (python_version < '3.12') and extra == 'numba'
36
+ Requires-Dist: numba>=0.59; (python_version == '3.12') and extra == 'numba'
37
+ Requires-Dist: numba>=0.61; (python_version == '3.13') and extra == 'numba'
38
+ Requires-Dist: numba>=0.63; (python_version >= '3.14') and extra == 'numba'
20
39
  Description-Content-Type: text/markdown
21
40
 
22
- ![shields.io-python-versions](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)
23
- ![genbadge-test-count](https://bertpl.github.io/counted-float/version_artifacts/release/v1.1.1/badge-test-count.svg)
24
- ![genbadge-test-coverage](https://bertpl.github.io/counted-float/version_artifacts/release/v1.1.1/badge-coverage.svg)
25
- ![counted_float logo](https://bertpl.github.io/counted-float/version_artifacts/release/v1.1.1/splash.webp)
41
+ [![CI](https://img.shields.io/github/actions/workflow/status/bertpl/counted-float/push_to_main.yml?branch=main&label=CI)](https://github.com/bertpl/counted-float/actions/workflows/push_to_main.yml)
42
+ [![Coverage](https://img.shields.io/badge/coverage-99.30%25-brightgreen)](https://github.com/bertpl/counted-float/actions/workflows/push_to_main.yml)
43
+ [![Tests](https://img.shields.io/badge/tests-708-blue)](https://github.com/bertpl/counted-float/actions/workflows/push_to_main.yml)
44
+ [![PyPI](https://img.shields.io/pypi/v/counted-float.svg)](https://pypi.org/project/counted-float/)
45
+ [![Python](https://img.shields.io/pypi/pyversions/counted-float.svg)](https://pypi.org/project/counted-float/)
46
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](https://github.com/bertpl/counted-float/blob/main/LICENSE)
47
+ [![code style: ruff](https://img.shields.io/badge/code%20style-ruff-261230)](https://github.com/astral-sh/ruff)
48
+
49
+ ![counted_float logo](https://raw.githubusercontent.com/bertpl/counted-float/v1.1.3/images/splash/splash.webp)
26
50
 
27
51
  # counted-float
28
52
 
@@ -192,7 +216,7 @@ counts.total_count() # 2
192
216
  The `counted_float` package contains a set of default, built-in FLOP weights, based on both empirical measurements
193
217
  and theoretical estimates of the relative cost of different floating point operations.
194
218
 
195
- See [fpu_data_sources.md](https://github.com/bertpl/counted-float/tree/develop/docs/analysis_methodology.md) for
219
+ See [analysis_methodology.md](https://github.com/bertpl/counted-float/blob/v1.1.3/docs/analysis_methodology.md) for
196
220
  rationale behind choice of data sources and methodology.
197
221
 
198
222
  ```
@@ -1,16 +1,41 @@
1
1
  [project]
2
2
  name = "counted-float"
3
- version = "1.1.1"
3
+ version = "1.1.3"
4
4
  description = "Count floating-point operations in Python code & benchmark relative flop costs."
5
- readme = "README.md"
5
+ # readme is dynamic: hatch-fancy-pypi-readme builds the PyPI long-description from
6
+ # README.md, rewriting relative links to tag-pinned absolute URLs (config below).
7
+ dynamic = ["readme"]
6
8
  requires-python = ">=3.11"
7
9
  dependencies = [
8
- "pydantic>=2.0.0",
9
- "numpy>=1.20",
10
- "psutil>=5.0",
10
+ # Per-Python floors: each compiled dep's floor is the earliest version shipping a
11
+ # wheel for that CPython, so `lowest-direct` installs (not source-builds) everywhere.
12
+ "numpy>=1.23.2; python_version < '3.12'",
13
+ "numpy>=1.26.0; python_version == '3.12'",
14
+ "numpy>=2.1.0; python_version == '3.13'",
15
+ "numpy>=2.3.2; python_version >= '3.14'",
16
+ # pydantic floor is a code requirement (auto model-rebuild of cross-module forward
17
+ # refs, from 2.6), raised further where a newer CPython needs a newer pydantic-core wheel.
18
+ "pydantic>=2.6; python_version < '3.13'",
19
+ "pydantic>=2.9; python_version == '3.13'",
20
+ "pydantic>=2.12; python_version >= '3.14'",
21
+ "psutil>=5.9.4; python_version < '3.13'",
22
+ "psutil>=7.1.2; python_version >= '3.13'",
11
23
  "rich>=13.0.0",
12
24
  "py-cpuinfo>=9.0.0",
13
25
  ]
26
+ classifiers = [
27
+ "Development Status :: 5 - Production/Stable",
28
+ "Intended Audience :: Developers",
29
+ "Intended Audience :: Science/Research",
30
+ "License :: OSI Approved :: Apache Software License",
31
+ "Operating System :: OS Independent",
32
+ # Python versions kept in sync with .python-versions (release.py enforces this)
33
+ "Programming Language :: Python :: 3.11",
34
+ "Programming Language :: Python :: 3.12",
35
+ "Programming Language :: Python :: 3.13",
36
+ "Programming Language :: Python :: 3.14",
37
+ "Topic :: Scientific/Engineering",
38
+ ]
14
39
 
15
40
  [project.scripts]
16
41
  counted_float = "counted_float._core._cli:cli"
@@ -23,7 +48,12 @@ Roadmap = "https://github.com/bertpl/counted-float/milestones"
23
48
 
24
49
  [project.optional-dependencies]
25
50
  numba = [
26
- "numba>=0.50",
51
+ # per-Python floors: earliest numba with a wheel for that CPython (also fixes the
52
+ # indirect llvmlite build failure — old numba>=0.50 dragged in unbuildable llvmlite 0.33)
53
+ "numba>=0.57; python_version < '3.12'",
54
+ "numba>=0.59; python_version == '3.12'",
55
+ "numba>=0.61; python_version == '3.13'",
56
+ "numba>=0.63; python_version >= '3.14'",
27
57
  ]
28
58
  cli = [
29
59
  "click>=8.0.0",
@@ -36,16 +66,32 @@ dev = [
36
66
  "pytest>=8.0",
37
67
  "pytest-cov>=6.0",
38
68
  "pytest-xdist>=3.5.0",
39
- # ruff & ty are pinned exactly: uv.lock is untracked, so these pins are what
40
- # keep pre-commit, `make lint`, and CI on the same tool versions.
41
- "ruff==0.15.11",
42
- "ty==0.0.56",
69
+ # exact tool versions are pinned by the tracked uv.lock (used by pre-commit,
70
+ # `make lint`, and CI); these ranges just set the floor.
71
+ "ruff>=0.15.11",
72
+ "ty>=0.0.56",
43
73
  ]
44
74
 
45
75
  [build-system]
46
- requires = ["hatchling"]
76
+ requires = ["hatchling", "hatch-fancy-pypi-readme"]
47
77
  build-backend = "hatchling.build"
48
78
 
79
+ [tool.hatch.metadata.hooks.fancy-pypi-readme]
80
+ content-type = "text/markdown"
81
+
82
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
83
+ path = "README.md"
84
+
85
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
86
+ # image embeds (splash, ...): relative -> tag-pinned raw URL for PyPI
87
+ pattern = '\]\((images/[^)]+)\)'
88
+ replacement = '](https://raw.githubusercontent.com/bertpl/counted-float/v$HFPR_VERSION/\1)'
89
+
90
+ [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
91
+ # docs/*.md references: relative -> tag-pinned blob URL for PyPI
92
+ pattern = '\]\((docs/[^)]+)\)'
93
+ replacement = '](https://github.com/bertpl/counted-float/blob/v$HFPR_VERSION/\1)'
94
+
49
95
  [tool.hatch.build.targets.sdist]
50
96
  # configs below also make sure the .whl file contains the data files, because wheels are built from the sdist
51
97
  packages = ["counted_float"]
@@ -107,6 +153,9 @@ runtime-evaluated-base-classes = ["pydantic.BaseModel", "counted_float._core.mod
107
153
  "__init__.py" = ["F401"] # re-export modules: naked imports, no `as` alias
108
154
  # module-level mutable patching state (original-function snapshots + context refcount) is the design
109
155
  "counted_float/_core/counting/_math_patching.py" = ["PLW0603"]
156
+ # maintainer tooling, not the shipped library: not a package (INP001), subprocess is fine (S)
157
+ "scripts/**" = ["INP001", "S"]
158
+ ".github/scripts/**" = ["INP001", "S"]
110
159
 
111
160
  [tool.ty.src]
112
161
  include = ["counted_float"]
@@ -119,8 +168,13 @@ unused-ignore-comment = "ignore"
119
168
 
120
169
  [tool.coverage.run]
121
170
  source = ["counted_float"]
171
+ relative_files = true # so per-combo matrix data files combine without a [paths] map
172
+ # no `parallel`: pytest-cov combines its own xdist workers into one file per run;
173
+ # each run/combo is named via COVERAGE_FILE, then combined across combos.
122
174
 
123
175
  [tool.coverage.report]
176
+ precision = 2
177
+ fail_under = 95 # cumulative gate, enforced on the combined matrix data
124
178
  exclude_also = [
125
179
  "@abstractmethod",
126
180
  "@abc.abstractmethod",