From c1db3a4ebc7df17e9838314998574685c6097ca7 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Sun, 24 May 2026 16:59:55 -0500 Subject: [PATCH 1/6] Write bitmath-2.1.0 release notes in NEWS.rst Flips Unreleased to Released (2026-05-24), expands the intro to mention the supply-chain work, adds a Hypothesis property-testing bullet under Project Infrastructure, and adds two new sections: - Security and Supply Chain: OpenSSF Best Practices badge, OSPS Baseline L1/L2/L3 status, OSSF Scorecard, SHA-pinned actions, Dependabot, hardened workflow token permissions, pip-audit SCA, CycloneDX SBOM attached to releases. - Project Documentation and Governance: MAINTAINERS.md, ARCHITECTURE.md, SECURITY_ASSESSMENT.md, SECURITY_POLICIES.md, VERIFICATION.md, SECURITY.md CVD response timeframes, and the https-everywhere doc-URL sweep. Each filename header links to the file on master. --- NEWS.rst | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 183 insertions(+), 8 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index a4d0d68..35abb96 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -10,11 +10,16 @@ NEWS bitmath-2.1.0 ************* -*Unreleased* +*Released: May 24, 2026* bitmath 2.1.0 is a focused follow-up to the 2.0.0 modernization. It finishes the last of the Python 2 cleanup, tightens the project's -quality tooling, and retires one piece of legacy API surface. +quality tooling, retires one piece of legacy API surface, and works +through OpenSSF's full menu of supply-chain checks (Scorecard, Best +Practices, and the OSPS Baseline) to put a credible security posture +on the record. The public API is essentially unchanged from 2.0; the +two breaking changes below are narrow ones that affect internal-type +inspection and one deprecated helper. Breaking Changes @@ -45,9 +50,8 @@ Library Improvements ==================== **pathlib support** - :func:`bitmath.getsize` and :func:`bitmath.listdir` now accept - :class:`pathlib.Path` objects, not just strings, for their path - and ``search_base`` arguments. + :func:`bitmath.getsize` now accepts :class:`pathlib.Path` objects, + not just strings, for its ``path`` argument. Project Infrastructure @@ -60,9 +64,13 @@ Project Infrastructure does not cover. **Security scanning with bandit** - bandit runs as part of ``make ci`` and as a dedicated GitHub - Actions workflow that fires on every push, every pull request, and - on a weekly schedule, scanning both ``bitmath/`` and ``tests/``. + Bandit is a static analyzer from PyCQA that scans Python source + for common security smells (hardcoded secrets, ``eval``, + ``subprocess`` calls with ``shell=True``, insecure ``yaml`` and + ``pickle`` deserialization, weak crypto primitives). It runs as + part of ``make ci`` and as a dedicated GitHub Actions workflow + that fires on every push, every pull request, and on a weekly + schedule, scanning both ``bitmath/`` and ``tests/``. **100% test coverage** The remaining coverage gaps were closed, including the @@ -70,6 +78,16 @@ Project Infrastructure bringing the suite to 100% measured coverage on every supported platform. +**Property-based testing with Hypothesis** + Four ``@given`` properties cover :func:`bitmath.parse_string` + roundtrips, lossless unit conversion across every ``(src, dst)`` + pair in :data:`bitmath.ALL_UNIT_TYPES`, and the contract that + :func:`bitmath.parse_string` raises only :exc:`ValueError` on bad + input. The roundtrip property already turned up a real parser bug + around scientific-notation float formatting, which is filed as a + follow-up. See `PR #144 + `_. + **SPDX license headers** Every source and test file now carries ``SPDX-License-Identifier`` and ``SPDX-FileCopyrightText`` headers. @@ -78,6 +96,163 @@ Project Infrastructure The package version is read dynamically from the ``VERSION`` file by hatchling, so bumping that one file propagates everywhere. +**Signed releases (landing with 2.1.0)** + The 2.1.0 release closes out the open OSSF Scorecard + Signed-Releases finding ("Determines if the project + cryptographically signs release artifacts," currently flagged + at high severity). Scorecard should reflect the improvement on + its next weekly run after the release lands. + + +Security and Supply Chain +========================= + +.. |scorecard| image:: https://api.securityscorecards.dev/projects/github.com/timlnx/bitmath/badge + :target: https://securityscorecards.dev/viewer/?uri=github.com/timlnx/bitmath + :alt: OSSF Scorecard +.. |bestpractices| image:: https://www.bestpractices.dev/projects/12749/badge + :target: https://www.bestpractices.dev/en/projects/12749 + :alt: OpenSSF Best Practices +.. |baseline| image:: https://www.bestpractices.dev/projects/12749/baseline + :target: https://www.bestpractices.dev/projects/12749 + :alt: OpenSSF Baseline + +|scorecard| |bestpractices| |baseline| + +Most of the work in this release happened here. OpenSSF's +supply-chain story has matured enough to be worth pursuing in earnest +even on a small library like bitmath, and the project now carries +the badges and the automation to back them up. + +**OpenSSF Best Practices passing badge** + bitmath earned the `OpenSSF Best Practices passing badge + `_. The full + self-assessment is on the linked profile; the badge appears on the + README and the docsite landing page alongside the OSSF Scorecard + and OSPS Baseline badges. + +**OSPS Baseline Levels 1 and 2 (Level 3 mostly)** + `OSPS Baseline `_ Level 1: 23 Met, + 2 Not Applicable, 0 Unmet. Level 2: 19 Met, 0 Unmet. Level 3: 18 + Met, 2 Not Applicable, 1 Unmet. The single Unmet at Level 3 is + OSPS-QA-07.01 (non-author code review), which is structurally + blocked by this being a single-maintainer project. Closing it + would require either onboarding a second maintainer or changing + the project governance model, neither of which is happening in + 2.1.0. The control responses backing each Met assessment live in + the docsite under :ref:`Project Architecture + ` and the policy documents listed below. + +**OSSF Scorecard** + ``.github/workflows/scorecard.yml`` runs on every push to + ``master``, on branch-protection-rule changes, and on a weekly + cron. Current score and history are published at + https://securityscorecards.dev/viewer/?uri=github.com/timlnx/bitmath. + +**GitHub Actions pinned to commit SHAs** + Every GitHub Actions reference in ``.github/workflows/`` is now + pinned to a full-length commit SHA with the version as a trailing + ``# vX.Y.Z`` comment. Floating tags (the old ``@v4``) and + floating branch refs (the now-removed + ``MishaKav/pytest-coverage-comment@main`` third-party step) are + gone. Dependabot keeps the SHAs fresh. + +**Dependabot** + ``.github/dependabot.yml`` watches the ``github-actions`` and + ``pip`` ecosystems on a weekly cadence. Minor and patch bumps are + grouped per ecosystem to keep PR noise bounded; major bumps land + as standalone PRs so breaking-change review stays honest. + +**Hardened workflow token permissions** + Every workflow declares an explicit ``permissions: read-all`` at + the top level, with ``write`` scopes applied only to the jobs that + need them (``security-events: write`` for SARIF upload, + ``id-token: write`` for PyPI OIDC Trusted Publishing, and so on). + The default-write ``GITHUB_TOKEN`` posture is no longer inherited + anywhere. + +**SCA via pip-audit** + ``.github/workflows/sca.yml`` runs `pip-audit + `_ on every push, every pull + request, and on a weekly cron. bitmath has no runtime + dependencies, so this scans the test-only deps in + ``requirements.txt``. Findings are resolved on the release-blocking + timetable specified in ``SECURITY_POLICIES.md``. + +**CycloneDX SBOM attached to every release** + The publish workflow now installs the built wheel into an isolated + venv, snapshots it with `cyclonedx-py + `_, and attaches + the resulting ``bitmath-.cdx.json`` to the GitHub release + alongside the wheel and sdist. Downstream consumers who SBOM-scan + everything they ingest can now pull bitmath's SBOM from the + release page directly instead of generating their own. + + +Project Documentation and Governance +==================================== + +The documentation set picked up five new top-level files this +release. These exist to answer standing security, governance, and +verification questions for downstream consumers without requiring a +real-time email exchange, and several of them are direct deliverables +for OSPS Baseline controls. + +`MAINTAINERS.md `_ + New top-level file naming the sole current maintainer, the + sensitive-resource access that comes with the role (PyPI account, + GitHub admin, GPG key, ReadTheDocs admin), maintainer + responsibilities, and a standing open call for a Debian/Ubuntu + co-maintainer (see `issue #117 + `_ if you're + interested). + +`ARCHITECTURE.md `_ + New top-level design document covering runtime architecture, the + build and release pipeline (including the Packit downstream RPM + flow into Fedora and EPEL), CI gates, trust boundaries, and the + documentation pipeline. Lives at the repo root so the OpenSSF + scanner finds it by filename, and so anyone exploring the repo for + the first time can get the design picture before reading code. + +`SECURITY_ASSESSMENT.md `_ + Standing threat model describing the attack surfaces (supply + chain, PyPI account, source repository, build chain, distribution + chain), the mitigations in place for each, and the automated + security tooling stack with what each tool catches. + +`SECURITY_POLICIES.md `_ + The SAST and SCA remediation thresholds and release-blocking + criteria in one place. Bandit and pip-audit findings, severity + ladder, the rule for what blocks a release versus what gets a + follow-up, and the timetable for acting on each. + +`VERIFICATION.md `_ + Downstream-consumer guide for verifying a bitmath release end to + end: integrity via the SHA-256 sums published alongside the GitHub + release, authenticity via `PEP 740 + `_ attestations and + `pypi-attestations + `_, and + provenance via the CycloneDX SBOM. If your organization's policy + requires verifying every dependency before installation, this is + the playbook. + +`SECURITY.md `_ tightened up + Coordinated Vulnerability Disclosure now states explicit response + timeframes (72 hours to acknowledge a report, 7 days to triage), + and the document picked up new Scope of Support, Duration of + Support, and Secrets and Credentials Policy sections. + +**HTTPS for all project doc URLs** + Every ``http://`` reference to project-owned documentation + (``bitmath.readthedocs.io``, the docsite, README badge targets, + NEWS historical links, CONTRIBUTING) has been switched to + ``https://`` to clear the bestpractices.dev ``sites_https`` check. + ReadTheDocs was already serving TLS; only the scheme needed + flipping. See `PR #146 + `_. + .. _bitmath-2.0.0: From 3a3564ad971a9f29084a3d978d9165215e59eac8 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Sun, 24 May 2026 16:59:59 -0500 Subject: [PATCH 2/6] Use dict form for source_suffix in Sphinx config Sphinx now auto-converts the string form ('.rst') to the dict form ({'.rst': 'restructuredtext'}) at build time and logs a notice every run. Declaring the dict form directly keeps make docs output quiet and matches current Sphinx documentation. --- docsite/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docsite/source/conf.py b/docsite/source/conf.py index a55bb0b..470ea6d 100644 --- a/docsite/source/conf.py +++ b/docsite/source/conf.py @@ -42,7 +42,7 @@ templates_path = ['_templates'] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = {'.rst': 'restructuredtext'} # The encoding of source files. #source_encoding = 'utf-8-sig' From ecb2bbd954908552a50f294cb0554e9fbd376c1e Mon Sep 17 00:00:00 2001 From: Tim Case Date: Sun, 24 May 2026 18:01:02 -0500 Subject: [PATCH 3/6] Fix broken and insecure URLs across docsite and NEWS Sweep of dead and http-scheme links surfaced by a curl-based audit of all URLs in the docsite and NEWS.rst. Broken (4xx) replaced with working targets: - classes.rst: BIPM SI brochure chapter3 path is gone; point at the brochure landing page. - real_life_examples.rst: Apple's 2001 iPod press release is gone; point at a Wayback Machine snapshot so the citation survives. - NEWS.rst: Fedora admin.fedoraproject.org pkgdb is long deprecated; point at src.fedoraproject.org/rpms/python-bitmath. http -> https upgrades on working hosts: - appendices/on_units.rst: tldp.org - appendices/who_uses.rst: travelcrm.org.ua - simple_examples.rst: miniwebtool.com (canonical drops www) NEWS.rst revert: the Coveralls account never moved with the GitHub rename, so the badge URL must stay at coveralls.io/github/tbielawa, not timlnx. Earlier sweep was over-aggressive. --- NEWS.rst | 4 ++-- docsite/source/appendices/on_units.rst | 2 +- docsite/source/appendices/who_uses.rst | 2 +- docsite/source/classes.rst | 2 +- docsite/source/real_life_examples.rst | 2 +- docsite/source/simple_examples.rst | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 35abb96..a96e968 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -814,7 +814,7 @@ Major Updates * bitmath is now included in the `Extra Packages for Enterprise Linux `_ EPEL6 and EPEL7 repositories (`pkg info - `_) + `_) * merged 6 `pull requests `_ from 3 `contributors @@ -867,7 +867,7 @@ Project than the previous major release (`1.0.4-1 `__) * Test suite now runs on EPEL6 and EPEL7 * `Code coverage - `_ is stable + `_ is stable around 95-100% diff --git a/docsite/source/appendices/on_units.rst b/docsite/source/appendices/on_units.rst index cd0865c..de1bf75 100644 --- a/docsite/source/appendices/on_units.rst +++ b/docsite/source/appendices/on_units.rst @@ -47,7 +47,7 @@ values. Why two unit systems? Why take the time to point this difference out? Why should you care? `The Linux Documentation Project -`_ comments on that: +`_ comments on that: Before these binary prefixes were introduced, it was fairly common to use k=1000 and K=1024, just like b=bit, B=byte. Unfortunately, diff --git a/docsite/source/appendices/who_uses.rst b/docsite/source/appendices/who_uses.rst index 9c01bfa..8f72f5e 100644 --- a/docsite/source/appendices/who_uses.rst +++ b/docsite/source/appendices/who_uses.rst @@ -22,7 +22,7 @@ identify: `_ flocker driver -* `TravelCRM `_ - Free CRM for travel +* `TravelCRM `_ - Free CRM for travel companies - `Bitbucket `_ * `direscraw diff --git a/docsite/source/classes.rst b/docsite/source/classes.rst index 1389652..168a664 100644 --- a/docsite/source/classes.rst +++ b/docsite/source/classes.rst @@ -26,7 +26,7 @@ defined by increasing powers of 2. Classes without the **'i'** character are **SI** type classes. Though not formally defined by any standards organization, they follow the `International System of Units (SI) -`_ +`_ pattern (commonly used to abbreviate base 10 values). You may hear these referred to as the "Decimal" or "SI" prefixes. diff --git a/docsite/source/real_life_examples.rst b/docsite/source/real_life_examples.rst index 3b39641..3384dba 100644 --- a/docsite/source/real_life_examples.rst +++ b/docsite/source/real_life_examples.rst @@ -37,7 +37,7 @@ Calculating how many files fit on a device ****************************************** In 2001 Apple® announced the iPod™. Their `headline statement -`_ +`_ boasting: "... iPod stores up to 1,000 CD-quality songs on its super-thin 5 GB hard drive, ..." diff --git a/docsite/source/simple_examples.rst b/docsite/source/simple_examples.rst index b030488..9c792c4 100644 --- a/docsite/source/simple_examples.rst +++ b/docsite/source/simple_examples.rst @@ -98,7 +98,7 @@ Bitwise Operations .. seealso:: - `Bitwise Calculator `_ + `Bitwise Calculator `_ A free online calculator for checking your math Bitwise operations are also supported. Bitwise operations work From 376521ee9fcd96faf99983048d867d32dcca4f76 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Sun, 24 May 2026 18:09:31 -0500 Subject: [PATCH 4/6] Refresh canonical URLs across docsite and NEWS Round two of the URL audit: items that currently auto-redirect but where the canonical target has moved. GitHub account rename (tbielawa -> timlnx): - index.rst.in: link to the tests/ directory. - NEWS.rst: historical PR links for #105 and #107. Note: NEWS.rst:870 Coveralls badge stays at tbielawa on purpose. The Coveralls account did not migrate with the GitHub rename and that URL is where the coverage data actually lives. Fedora wiki -> docs.fedoraproject.org/en-US/epel/: - NEWS.rst (two occurrences) for the EPEL reference. pypi.python.org -> pypi.org: - NEWS.rst: bitmath project page. - index.rst.in: hurry.filesize reference for prefix-selection prior art. mkaz.blog Python String Format Cookbook moved to a new path under the working-with-python tree: - instances.rst seealso link. TravelCRM (appendices/who_uses.rst): Bitbucket source repo is gone (Bitbucket dropped Mercurial in 2020) and the project itself appears abandoned. Removed both links and the dangling Bitbucket clause; kept the bare-text mention as a historical entry. --- NEWS.rst | 10 +++++----- docsite/source/appendices/who_uses.rst | 3 +-- docsite/source/index.rst | 4 ++-- docsite/source/index.rst.in | 4 ++-- docsite/source/instances.rst | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index a96e968..f2fa1ac 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -507,12 +507,12 @@ Changes * Fixed packaging: ``bitmath.integrations`` subpackage was missing from the ``packages`` list in ``setup.py.in``, causing the argparse, click, and progressbar integrations to be absent from installed distributions. - Reported in `PR #107 `_. + Reported in `PR #107 `_. * Modernized mock imports in the test suite: ``tests/test_progressbar.py`` and ``tests/test_query_device_capacity.py`` now prefer ``unittest.mock`` (stdlib, Python 3.3+) and fall back to the third-party ``mock`` package. - Based on `PR #105 `_. + Based on `PR #105 `_. .. _bitmath-1.3.3-1: @@ -683,7 +683,7 @@ Project Look for separate python3.x and python2.x packages coming soon to `Fedora `_ and `EPEL -`_. This is happening because of +`_. This is happening because of the `initiative `_ to update the base Python implementation on Fedora to Python 3.x @@ -812,7 +812,7 @@ Major Updates `_ * bitmath is now Python 3.x compatible * bitmath is now included in the `Extra Packages for Enterprise Linux - `_ EPEL6 and EPEL7 repositories + `_ EPEL6 and EPEL7 repositories (`pkg info `_) * merged 6 `pull requests @@ -885,7 +885,7 @@ Project Available via: -* `PyPi `_ +* `PyPi `_ * Fedora 19 * Fedora 20 diff --git a/docsite/source/appendices/who_uses.rst b/docsite/source/appendices/who_uses.rst index 8f72f5e..ae217ab 100644 --- a/docsite/source/appendices/who_uses.rst +++ b/docsite/source/appendices/who_uses.rst @@ -22,8 +22,7 @@ identify: `_ flocker driver -* `TravelCRM `_ - Free CRM for travel - companies - `Bitbucket `_ +* TravelCRM - Free CRM for travel companies * `direscraw `_ by diff --git a/docsite/source/index.rst b/docsite/source/index.rst index 7033319..a2c95c6 100644 --- a/docsite/source/index.rst +++ b/docsite/source/index.rst @@ -56,7 +56,7 @@ focusing on file size unit conversion, functionality now includes: * Converting between **SI** and **NIST** prefix units (``kB`` to ``GiB``) * Converting between units of the same type (SI to SI, or NIST to NIST) * Full NIST unit coverage including **ZiB**, **YiB**, **Zib**, and **Yib** -* Automatic human-readable prefix selection (like in `hurry.filesize `_) +* Automatic human-readable prefix selection (like in `hurry.filesize `_) * Basic arithmetic operations (subtracting 42KiB from 50GiB) * Capacity math with floor division, modulo, and ``divmod`` (``GiB(1) // MiB(300)``, ``GiB(1) % MiB(300)``) * Rich comparison operations (``1024 Bytes == 1KiB``) @@ -87,7 +87,7 @@ most of the time what you're really seeing are the base-2 sizes/rates. `_. And did we mention there are nearly 300 unit tests? `Check them out for -yourself `_. +yourself `_. * :ref:`Examples ` after the TOC. diff --git a/docsite/source/index.rst.in b/docsite/source/index.rst.in index fdd1fe9..7c9ff35 100644 --- a/docsite/source/index.rst.in +++ b/docsite/source/index.rst.in @@ -56,7 +56,7 @@ focusing on file size unit conversion, functionality now includes: * Converting between **SI** and **NIST** prefix units (``kB`` to ``GiB``) * Converting between units of the same type (SI to SI, or NIST to NIST) * Full NIST unit coverage including **ZiB**, **YiB**, **Zib**, and **Yib** -* Automatic human-readable prefix selection (like in `hurry.filesize `_) +* Automatic human-readable prefix selection (like in `hurry.filesize `_) * Basic arithmetic operations (subtracting 42KiB from 50GiB) * Capacity math with floor division, modulo, and ``divmod`` (``GiB(1) // MiB(300)``, ``GiB(1) % MiB(300)``) * Rich comparison operations (``1024 Bytes == 1KiB``) @@ -87,7 +87,7 @@ most of the time what you're really seeing are the base-2 sizes/rates. `_. And did we mention there are nearly 300 unit tests? `Check them out for -yourself `_. +yourself `_. * :ref:`Examples ` after the TOC. diff --git a/docsite/source/instances.rst b/docsite/source/instances.rst index 6123ec3..47f3656 100644 --- a/docsite/source/instances.rst +++ b/docsite/source/instances.rst @@ -574,5 +574,5 @@ given). .. seealso:: - `Python String Format Cookbook `_ + `Python String Format Cookbook `_ `Marcus Kazmierczak’s `_ *excellent* introduction to string formatting From 95b6423c2dc0da20d3901b2f5c09321f4bca0e01 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Sun, 24 May 2026 18:22:08 -0500 Subject: [PATCH 5/6] Wire up Sphinx linkcheck via make linkcheck Adds a `make linkcheck` target that dispatches to Sphinx's built-in linkcheck builder. Scans every external URL in the docsite plus NEWS.rst (included via `.. include::`) and writes a structured report to docsite/build/linkcheck/output.txt. Configured in docsite/source/conf.py: - 8 parallel workers (default is 5) - 15-second timeout per URL - 2 retries on transient failures - Anchor checking enabled (catches dead #L line refs etc.) - Ignore patterns for known-quirky endpoints: - api.securityscorecards.dev (serves SVG, 405 on HEAD, 302 on GET) - web.archive.org pinned snapshots (occasional 5xx during indexing) Not wired into `make ci` on purpose. Link rot happens independently of code changes, so the right home for this is a weekly GH Actions cron, not every PR build. To run locally: `make linkcheck`. --- Makefile | 6 ++++++ docsite/source/conf.py | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Makefile b/Makefile index 698f730..077e9c3 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,12 @@ docs-venv: docs: docs-venv $(MANPAGES) docsite/source/index.rst . $(DOCSVENV)/bin/activate && cd docsite && make html +# Scan every external URL in the docsite (plus NEWS.rst via include) and +# report broken links. Output lands in docsite/build/linkcheck/output.txt. +# Configured via linkcheck_* settings in docsite/source/conf.py. +linkcheck: docs-venv docsite/source/index.rst + . $(DOCSVENV)/bin/activate && cd docsite && make linkcheck + # Add examples to the RTD docs by taking it from the README docsite/source/index.rst: docsite/source/index.rst.in README.rst VERSION @echo "#############################################" diff --git a/docsite/source/conf.py b/docsite/source/conf.py index 470ea6d..cc0e9db 100644 --- a/docsite/source/conf.py +++ b/docsite/source/conf.py @@ -259,3 +259,24 @@ # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' + + +# -- Options for linkcheck builder --------------------------------------------- + +# Run `make linkcheck` to scan every external URL in the docsite plus NEWS.rst +# (included via `.. include::`) and report broken links to +# docsite/build/linkcheck/output.txt. + +linkcheck_workers = 8 +linkcheck_timeout = 15 +linkcheck_retries = 2 +linkcheck_anchors = True + +linkcheck_ignore = [ + # The OSSF Scorecard badge endpoint serves an SVG and returns 405 to HEAD, + # 302 to GET. The badge renders fine in the wild; skip the probe. + r'^https://api\.securityscorecards\.dev/.*', + # Wayback Machine snapshots are intentionally pinned to a specific archive + # date. They occasionally return 5xx during indexing; treat as out-of-band. + r'^https://web\.archive\.org/web/\d+/.*', +] From 65d86c542b25aaf41ee63926428c29ac86731303 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Sun, 24 May 2026 18:48:44 -0500 Subject: [PATCH 6/6] Apply linkcheck findings: kill redirects, drop stale anchors Round three of the URL audit, this time driven by `make linkcheck` output rather than manual curling. linkcheck caught several things the earlier passes missed. Stale anchors dropped: - NEWS.rst: Makefile#L177 link from a 2014 entry; the virtualenv: target sits at L186 now and pinning by line number to a 10+ year old file location is fragile. Drop the anchor; keep the file link. URL refreshes that were currently 30x-redirecting: - NEWS.rst: pypi-attestations repo moved from trailofbits to the pypi org (this URL came in with my 2.1.0 NEWS write-up). - on_units.rst: tldp.org dropped the www subdomain canonically. - who_uses.rst: codedellemc -> thecodeteam for the ScaleIO flocker driver. - related_projects.rst: pypi.python.org -> pypi.org for the hurry.filesize prior art reference (last pypi.python.org URL in the tree). readthedocs trailing-path normalization (so the URL stops bouncing through a redirect to its own /en/{latest,stable}/ canonical): - contributing.rst: pytest-cov, pylint - integration_examples.rst, module.rst: progressbar2 Badge host: readthedocs.org/projects/bitmath/badge -> the new app.readthedocs.org host the project redirects to. docsite/source/conf.py: cap linkcheck_rate_limit_timeout at 10s so a single rate-limited host (GitHub, gnu.org) does not stall an interactive `make linkcheck` run for minutes at a time. Default is 60+ seconds because Sphinx honors Retry-After headers; 10s is more useful for local iteration. --- NEWS.rst | 4 ++-- docsite/source/appendices/on_units.rst | 2 +- docsite/source/appendices/related_projects.rst | 2 +- docsite/source/appendices/who_uses.rst | 2 +- docsite/source/conf.py | 3 +++ docsite/source/contributing.rst | 4 ++-- docsite/source/index.rst | 2 +- docsite/source/index.rst.in | 2 +- docsite/source/integration_examples.rst | 2 +- docsite/source/module.rst | 2 +- 10 files changed, 14 insertions(+), 11 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index f2fa1ac..e34df08 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -233,7 +233,7 @@ for OSPS Baseline controls. release, authenticity via `PEP 740 `_ attestations and `pypi-attestations - `_, and + `_, and provenance via the CycloneDX SBOM. If your organization's policy requires verifying every dependency before installation, this is the playbook. @@ -861,7 +861,7 @@ Project **Tests** * Test suite is now implemented using `Python virtualenv's - `_ + `_ for consistency across across platforms * Test suite now contains 150 unit tests. This is **110** more tests than the previous major release (`1.0.4-1 `__) diff --git a/docsite/source/appendices/on_units.rst b/docsite/source/appendices/on_units.rst index de1bf75..2c74a44 100644 --- a/docsite/source/appendices/on_units.rst +++ b/docsite/source/appendices/on_units.rst @@ -47,7 +47,7 @@ values. Why two unit systems? Why take the time to point this difference out? Why should you care? `The Linux Documentation Project -`_ comments on that: +`_ comments on that: Before these binary prefixes were introduced, it was fairly common to use k=1000 and K=1024, just like b=bit, B=byte. Unfortunately, diff --git a/docsite/source/appendices/related_projects.rst b/docsite/source/appendices/related_projects.rst index e88a007..3a9ba93 100644 --- a/docsite/source/appendices/related_projects.rst +++ b/docsite/source/appendices/related_projects.rst @@ -51,7 +51,7 @@ calculations `, then you will find hurry.filesize lacking. This project has not updated since 2009, so I would not expect to see updates any time soon. -* `PyPi Homepage & Download `_ +* `PyPi Homepage & Download `_ SymPy - Units diff --git a/docsite/source/appendices/who_uses.rst b/docsite/source/appendices/who_uses.rst index ae217ab..a6250d7 100644 --- a/docsite/source/appendices/who_uses.rst +++ b/docsite/source/appendices/who_uses.rst @@ -15,7 +15,7 @@ identify: flocker storage driver * EMC's `scaleio - `_ + `_ flocker storage driver * Dell Storage's `storage center block device diff --git a/docsite/source/conf.py b/docsite/source/conf.py index cc0e9db..bb54718 100644 --- a/docsite/source/conf.py +++ b/docsite/source/conf.py @@ -271,6 +271,9 @@ linkcheck_timeout = 15 linkcheck_retries = 2 linkcheck_anchors = True +# Don't hang the entire run waiting on a rate-limited host (GitHub, gnu.org). +# Default is 60+ seconds (honors Retry-After). Bail after 10s instead. +linkcheck_rate_limit_timeout = 10.0 linkcheck_ignore = [ # The OSSF Scorecard badge endpoint serves an SVG and returns 405 to HEAD, diff --git a/docsite/source/contributing.rst b/docsite/source/contributing.rst index defa480..ef9fa92 100644 --- a/docsite/source/contributing.rst +++ b/docsite/source/contributing.rst @@ -193,14 +193,14 @@ The bitmath test suite depends on the following tools: to execute the unittest-based test suite, collect results, and report coverage. -* `pytest-cov `_ — Coverage plugin +* `pytest-cov `_ — Coverage plugin for pytest. The project aims for high coverage; reasonable exceptions can always be discussed in the pull request. * `pycodestyle `_ — Checks Python code style (PEP 8). -* `pylint `_ — Full static analysis: +* `pylint `_ — Full static analysis: naming, refactoring hints, design metrics, and correctness. The project targets a score of 10.00/10. diff --git a/docsite/source/index.rst b/docsite/source/index.rst index a2c95c6..9397427 100644 --- a/docsite/source/index.rst +++ b/docsite/source/index.rst @@ -21,7 +21,7 @@ .. image:: https://img.shields.io/pypi/pyversions/bitmath?style=flat-square :alt: PyPI - Python Version -.. image:: https://readthedocs.org/projects/bitmath/badge/?version=latest +.. image:: https://app.readthedocs.org/projects/bitmath/badge/?version=latest :target: https://bitmath.readthedocs.io/ .. image:: https://github.com/timlnx/bitmath/actions/workflows/bandit.yml/badge.svg :target: https://github.com/timlnx/bitmath/actions/workflows/bandit.yml diff --git a/docsite/source/index.rst.in b/docsite/source/index.rst.in index 7c9ff35..083d4ef 100644 --- a/docsite/source/index.rst.in +++ b/docsite/source/index.rst.in @@ -21,7 +21,7 @@ .. image:: https://img.shields.io/pypi/pyversions/bitmath?style=flat-square :alt: PyPI - Python Version -.. image:: https://readthedocs.org/projects/bitmath/badge/?version=latest +.. image:: https://app.readthedocs.org/projects/bitmath/badge/?version=latest :target: https://bitmath.readthedocs.io/ .. image:: https://github.com/timlnx/bitmath/actions/workflows/bandit.yml/badge.svg :target: https://github.com/timlnx/bitmath/actions/workflows/bandit.yml diff --git a/docsite/source/integration_examples.rst b/docsite/source/integration_examples.rst index 8caf1ba..4f33c98 100644 --- a/docsite/source/integration_examples.rst +++ b/docsite/source/integration_examples.rst @@ -224,7 +224,7 @@ Example run: progressbar2 ************ -`progressbar2 `_ is a flexible +`progressbar2 `_ is a flexible terminal progress-bar library. The example below defines a custom widget that displays a data-transfer speed (bytes per second) in a human-readable bitmath unit, and demonstrates it with a simulated file diff --git a/docsite/source/module.rst b/docsite/source/module.rst index 611d7c8..f96b1d0 100644 --- a/docsite/source/module.rst +++ b/docsite/source/module.rst @@ -961,5 +961,5 @@ behavior. Self-contained, copy-paste examples for integrating :mod:`bitmath` with :mod:`argparse`, `click `_, and -`progressbar2 `_ are collected in +`progressbar2 `_ are collected in the :ref:`Integration Examples ` chapter.