Skip to content

Migrate to pyproject.toml - #36

Merged
mrecachinas merged 17 commits into
masterfrom
migrate-to-pyproject-toml
Feb 16, 2026
Merged

Migrate to pyproject.toml#36
mrecachinas merged 17 commits into
masterfrom
migrate-to-pyproject-toml

Conversation

@mrecachinas

@mrecachinas mrecachinas commented Jan 24, 2026

Copy link
Copy Markdown
Owner

This pull request introduces several major improvements to the project, including a migration to a modern Python packaging standard, updates to the CI workflow for broader compatibility and maintainability, a switch to a more permissive license, and general code and test modernization. The most important changes are grouped by theme below.

Project packaging and build system modernization:

  • Added a pyproject.toml file to define build requirements, project metadata, and development dependencies, moving away from legacy setup.py-only configuration. The build now uses setuptools as the backend, and test/dev dependencies are clearly specified.
  • Updated setup.py to only handle the C extension build with platform-specific flags; all metadata and dependencies are now in pyproject.toml. Source files are now referenced from the src directory.
  • Updated MANIFEST.in to include pyproject.toml and migrate source and test directory structure.
  • Removed requirements-dev.txt and pytest.ini in favor of configuration in pyproject.toml. [1] [2]

Licensing:

  • Changed the project license from Beerware to MIT, updating the LICENSE file accordingly.

Continuous Integration and Distribution:

  • Updated .github/workflows/pythonpackage.yml to:
    • Use newer OS runners (Ubuntu 24.04, macOS-14, Windows-2022).
    • Expand the matrix to test and build for Python 3.9–3.13.
    • Switch to uv for dependency management and building on macOS.
    • Update wheel and sdist artifact naming and collection for clarity.
    • Require twine>=6.0.0 and show version before checks.
    • Simplify and modernize test and build commands, and update test requirements for cibuildwheel. [1] [2]

Testing improvements:

  • Refactored test/test_hexhamming.py to use consistent string and byte literals, improved parameterization, updated function and variable names for clarity, and improved assertion and error handling. [1] [2] [3] [4] [5] [6] [7] [8] [9]

Summary of most important changes:

1. Packaging and Build System:

  • Introduced pyproject.toml for modern, standardized project configuration, including build system, metadata, and dev dependencies.
  • Migrated source code to src/, updated setup.py to only handle extension build, and removed legacy files (requirements-dev.txt, pytest.ini). [1] [2] [3] [4]

2. Licensing:

  • Changed license from Beerware to MIT by replacing the LICENSE file.

3. CI/CD and Distribution:

  • Upgraded CI to use latest OS runners, added Python 3.11–3.13 to test/build matrix, switched to uv for dependency management, and improved artifact handling and naming. [1] [2]

4. Testing:

  • Refactored test code for style consistency, clarity, and maintainability, including better parameterization and error handling. [1] [2] [3] [4] [5] [6] [7] [8] [9]

- Add pyproject.toml with build configuration and metadata
- Simplify setup.py to only define C extension with platform flags
- Add uv.lock for reproducible dependency resolution
- Move dev dependencies to dependency-groups in pyproject.toml
- Move pytest config to pyproject.toml
- Remove requirements-dev.txt (now in pyproject.toml)
- Remove pytest.ini (now in pyproject.toml)
- Update MANIFEST.in for new file structure
- Reformat code with black
- Swap black for ruff in dev dependencies (faster, includes linting)
- Add ruff configuration to pyproject.toml
- Fix duplicate test function name caught by ruff linter
- Update Python versions: drop 3.6-3.8 (EOL), add 3.11-3.13
- Update runner images: ubuntu-24.04, macos-13/14, windows-2022
- Use native ARM runners for macOS arm64 builds
- Use uv for sdist job (setup-uv action)
- Replace requirements-dev.txt with direct pip install of test deps
- Use unique artifact names to avoid conflicts with v4 upload action
- Update artifact download to use pattern matching for multiple artifacts
CIBW_BEFORE_TEST now installs uv first, then uses uv to install
pytest and pytest-benchmark (faster dependency resolution).
Prevents pytest from adding project directory to sys.path, which
was causing it to find the hexhamming/ source directory instead
of the installed wheel.
The hexhamming/ directory containing C++ sources was being found
by Python as a package, shadowing the installed wheel during tests.
Use CIBW_TEST_REQUIRES instead of CIBW_BEFORE_TEST to properly
install test dependencies into the isolated test virtualenv.
Also remove --import-mode=importlib which is no longer needed.
Use {text = "MIT"} format instead of plain string to avoid PEP 639
metadata (license-expression, license-file) that older twine versions
don't recognize. Also add License classifier for better compatibility.
Twine 6.0+ supports the license-file and license-expression fields.
Also removed redundant license field since classifier is sufficient.
Setuptools auto-detects LICENSE and generates license-file metadata,
which requires packaging>=24.2 to validate. Disable this by setting
license-files = [] in [tool.setuptools]. The license is still declared
via the classifier.
@mrecachinas
mrecachinas marked this pull request as ready for review February 12, 2026 03:22
@github-actions

github-actions Bot commented Feb 12, 2026

Copy link
Copy Markdown

📊 Benchmark Comparison Results

Status Benchmark Base PR Delta
⚠️ bytes_arr_within[ 1024 elems,s=32,mid] 0.0100ms 0.0112ms 11.8% slower
➖ 23 benchmarks within noise (click to expand)
Benchmark Base PR Delta
bytes_arr_within[ 512 elems,s=16,at 0] 0.0002ms 0.0002ms 6.6% faster
bytes_arr_within[ 512 elems,s=16,end] 0.0018ms 0.0018ms 0.0% faster
bytes_arr_within[ 512 elems,s=16,mid] 0.0010ms 0.0010ms 0.4% slower
bytes_arr_within[ 1024 elems,s=32,at 0] 0.0002ms 0.0002ms 6.1% faster
bytes_arr_within[ 1024 elems,s=32,end] 0.0197ms 0.0213ms 8.4% slower
bytes_arr_within[16384 elems,s=64,at 0] 0.0002ms 0.0002ms 6.1% faster
bytes_arr_within[16384 elems,s=64,end] 0.0834ms 0.0872ms 4.5% slower
bytes_arr_within[16384 elems,s=64,mid] 0.0420ms 0.0433ms 2.9% slower
hex_within_dist 0.0002ms 0.0001ms 40.6% faster
hd_bytes[1000-diff] 0.0002ms 0.0002ms 2.6% faster
hd_bytes[1000-same] 0.0002ms 0.0002ms 1.2% slower
hd_bytes[1024-diff] 0.0001ms 0.0001ms 0.7% slower
hd_bytes[1024-same] 0.0001ms 0.0001ms 3.6% slower
hd_bytes[3-diff] 0.0001ms 0.0001ms 2.7% faster
hd_bytes[3-same] 0.0001ms 0.0001ms 1.7% slower
hd_bytes[64-diff] 0.0001ms 0.0001ms 1.5% slower
hd_string[1000-diff] 0.0003ms 0.0003ms 1.8% faster
hd_string[1000-same] 0.0003ms 0.0003ms 0.0% faster
hd_string[1024-diff] 0.0003ms 0.0003ms 2.4% faster
hd_string[1024-same] 0.0003ms 0.0003ms 2.7% faster
hd_string[3-diff] 0.0001ms 0.0001ms 1.5% faster
hd_string[3-same] 0.0001ms 0.0001ms 1.2% faster
hd_string[64-diff] 0.0001ms 0.0001ms 7.9% faster

Legend: ✅ Faster (>5%) · ⚠️ Slower (5-30%) · ❌ Regression (>30%) · 🆕 New · 🗑️ Removed

mrecachinas and others added 3 commits February 16, 2026 10:48
- Use SPDX license expression (license = 'MIT') instead of deprecated classifier
- Remove deprecated tool.setuptools.license-files in favor of auto-detection
- Bump setuptools requirement to >=77.0.0 for SPDX support
- Add Python 3.13 classifier
- Fix MANIFEST.in: include LICENSE, exclude *.pyc/*.pyo/*.so/__pycache__
- Add check-manifest config to ignore uv.lock
- Verified: twine check passes, check-manifest passes,
  wheel and sdist both install and work correctly

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
setuptools>=77 emits License-Expression (Metadata 2.4) which requires
twine>=6.1.0 (with packaging>=24.2) to validate. twine 6.0.x rejects
these fields as unrecognized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CI had twine 6.2.0 but packaging 24.0 — Metadata 2.4 (License-Expression)
requires packaging>=24.2. Explicitly pin it in all pip install lines.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mrecachinas
mrecachinas merged commit a3016bc into master Feb 16, 2026
13 checks passed
@mrecachinas
mrecachinas deleted the migrate-to-pyproject-toml branch February 16, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant