8. Contributing to bitmath

This section describes the guidelines for contributing to bitmath.

8.1. Code of Conduct

All persons submitting code or otherwise interacting with the bitmath project on GitHub must accept and abide by the terms of the Code of Conduct.

8.2. Issue Reporting

If you encounter an issue with the bitmath library, please use the provided template.

8.3. Project Architecture

If you are about to make a non-trivial change, read the ARCHITECTURE.md document in the repository root first. It is the map of how bitmath is put together: the runtime library, the build and release pipeline, the CI gates, and the trust boundaries.

The contract is that ARCHITECTURE.md is reviewed at every minor release and updated alongside any change to a public API, the build pipeline, or a trust boundary. If you are touching one of those things, your pull request should include the corresponding update.

8.4. Code Style and Formatting

Two static analysis tools run on every pull request as part of the GitHub Actions CI workflow, and locally via make ci:

  • pycodestyle — checks PEP 8 code style, with E501 (line too long) ignored. Runs across all matrix cells.

  • pylint — full static analysis: naming conventions, refactoring hints, design metrics, and correctness checks. The project targets 10.00/10. Runs on Ubuntu / Python 3.12 only (linting is not platform-sensitive).

A PR cannot be merged until both pass. If you want to save time you can run make ci locally to check before submitting and waiting on the GitHub runners to report back.

8.5. Commit Messages

Please write intelligent commit messages.

For example:

Short summary (50 chars or less)

More detailed explanatory text, if necessary. Wrap it to about 72
characters or so.

Write your commit message in the imperative: "Fix bug" and not
"Fixed bug" or "Fixes bug."

- Bullet points are okay, too

8.6. Pull Requests

When you open a pull request, GitHub Actions automatically runs the full test suite across all supported Python versions. The repository is configured to block merges until all checks pass — you don’t need to trigger anything manually.

If a check fails, GitHub will report the failure directly on the pull request. Review the output, push a fix, and the checks will re-run automatically.

The bitmath project welcomes all contributors. If you’re unable to fix a failing check yourself, leave a comment on the pull request explaining the situation and we’ll help.

8.7. Supported Python Versions

bitmath supports Python versions shipping with the current and previous major RHEL release available via EPEL. This means the minimum supported version tracks the oldest Python still included in a supported EPEL target:

  • RHEL 10 / EPEL 10 — Python 3.12

  • RHEL 9 / EPEL 9 — Python 3.9, 3.10, 3.11

The CI matrix tests all versions in this range. When a RHEL major release reaches end-of-life and is dropped from EPEL, the corresponding Python versions may be dropped from the support matrix in the next bitmath release.

If anybody wants to take over Debian/Ubuntu patching, we can add notes for which distributions are covered.

8.8. Testing Policy

The bitmath testing policy is short: every major change to the library MUST be accompanied by tests in the same pull request.

A “major change” for the purposes of this policy means any of:

  • a new public function, method, class, or property

  • a change to the behavior of an existing public API

  • a bug fix whose root cause is reproducible by a test (which is almost all of them)

  • a change to the internal arithmetic, parsing, or normalization logic

A “non-major change” that does not require new tests:

  • documentation changes

  • comment-only changes

  • CI workflow tweaks that do not affect the build matrix

  • changes to packaging metadata that do not change runtime behavior

All bitmath code includes unit tests to verify expected functionality. New tests should:

  • live in tests/ as a test_*.py file

  • have a unique test case name across the whole suite (tests/test_unique_testcase_names.sh enforces this)

  • be written using unittest (the existing style) unless there is a specific reason to reach for pytest-native features

If you are unsure how to write a test for a particular change, open the pull request anyway and ask in the description. I will help you scope an appropriate test.

8.8.1. Components

The bitmath test suite depends on the following tools:

  • GitHub Actions — Runs the full test suite automatically on every pull request across all supported Python versions.

  • unittest — Python’s standard unit testing framework. All bitmath tests are written using this framework.

  • pytest — Test runner used to execute the unittest-based test suite, collect results, and report coverage.

  • 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: naming, refactoring hints, design metrics, and correctness. The project targets a score of 10.00/10.

  • virtualenv — Creates an isolated Python environment. The make ci target manages this automatically.

  • Makefile — Orchestrates all build and test tasks. See Makefile Targets below.

8.8.2. Makefile Targets

All development tasks are driven through make. The targets most relevant to contributors are:

Note

These targets are how you test your changes locally and clean up afterwards before opening a pull request.

make ci

The primary target. Creates a Python virtualenv, installs all dependencies from requirements.txt, runs the unique test name check, executes the full pytest suite with coverage, and runs pycodestyle and pylint. Run this before opening a pull request. This is the same check GitHub Actions runs.

make clean

Removes the virtualenv, compiled *.pyc files, __pycache__ directories, and build artifacts. Run make clean; make ci for a guaranteed fresh test run.

make docs

Builds the HTML documentation locally using Sphinx. Output is written to docsite/build/html/. Run make viewdocs to open the result automatically in your default browser, or open docsite/build/html/index.html directly.

8.8.3. Running the Tests

The simplest way to run the full test suite locally is:

$ make ci

For a guaranteed clean run (recommended before opening a PR):

$ make clean; make ci

The output will look something like this (dependency installation output omitted for brevity):

#############################################
# Running Unique TestCase checker
#############################################
./tests/test_unique_testcase_names.sh

#############################################
# Creating a virtualenv
#############################################
... (dependency installation) ...

#############################################
# Running Unit Tests
#############################################
============================= test session starts ==============================
tests/test_arithmetic.py::TestArithmetic::test_add_bitmath_to_bitmath PASSED [  0%]
tests/test_arithmetic.py::TestArithmetic::test_sub_bitmath_from_bitmath PASSED [  0%]
... (hundreds more) ...

================================ tests coverage ================================
Name    Stmts   Miss  Cover   Missing
-------------------------------------
TOTAL     623      0   100%

======================== NNN passed in Xs ========================

The exact test count grows as new tests are added.

The definitive pass/fail verdict comes from the GitHub Actions workflow on your pull request, which runs the suite across all supported Python versions. A clean local make ci is a strong signal, but the PR checks are the final authority.