Skip to content

Modernize package: uv, pyproject.toml, pytest, Python 3.10-3.13 - #4

Merged
ulikoehler merged 10 commits into
ulikoehler:masterfrom
mpasternak:modernize-package
May 4, 2026
Merged

Modernize package: uv, pyproject.toml, pytest, Python 3.10-3.13#4
ulikoehler merged 10 commits into
ulikoehler:masterfrom
mpasternak:modernize-package

Conversation

@mpasternak

Copy link
Copy Markdown
Collaborator

Summary

Full modernization of the pyoai package tooling. Stacked on top of PR #3 (datetime.utcnow fix).

  • Packaging: setup.py + setup.cfg + MANIFEST.in + buildout.cfgpyproject.toml + uv
  • Python support: dropped EOL 2.7 / 3.5–3.9, now targets 3.10, 3.11, 3.12, 3.13
  • CI: GitHub Actions matrix rewritten to use uv; informational-only ruff lint job
  • Test runner: tox + python -m unittestpytest (58/58 passing on 3.13)
  • Version management: fixed mismatch (setup.py said 2.5.2pre, stale bumpversion said 2.5.0) → single source in pyproject.toml via bumpver
  • Pre-commit: added ruff (E, F, W) + hygiene hooks; runs staged-only, no mass reformat of existing code
  • Removed six dependency: package is Python 3-only
  • Python 3.12+ compatibility fixes required for tests to run at all:
    • pkg_resourcesimportlib.metadata
    • removed unittest.makeSuite / test_suite() dead code (zope-testrunner era)
    • assertEqualsassertEqual, assert_assertTrue
    • lxml evaluator.evaluate (removed attribute) → callable evaluator
    • relative imports: from fakeclientfrom .fakeclient
  • Deleted legacy files: .hgignore, .hgtags, buildout.cfg, Makefile, INSTALL.txt
  • README: updated badges, fixed Python 2 print record, added pip/uv install instructions
  • HISTORY.txt: documented all 2.5.2 changes

Test plan

  • uv sync --all-extras succeeds
  • uv run pytest — 58 passed locally on Python 3.13
  • CI matrix green on 3.10, 3.11, 3.12, 3.13
  • Verify install from wheel (uv build && uv pip install dist/*.whl)

Notes

  • uv.lock is gitignored (library convention — users resolve their own versions).
  • Ruff lint has ~230 pre-existing style warnings in source. Intentionally not auto-fixed to keep the diff reviewable; the CI lint job is non-blocking. Can be addressed in a separate cleanup PR.
  • The first 2 commits are from PR Replace deprecated datetime.utcnow() with timezone-aware equivalent #3 (datetime.utcnow fix); if that lands first this PR will shrink accordingly.

🤖 Generated with Claude Code

mpasternak and others added 10 commits April 19, 2026 20:43
`datetime.datetime.utcnow()` is deprecated since Python 3.12 and
scheduled for removal in a future version:

    DeprecationWarning: datetime.datetime.utcnow() is deprecated and
    scheduled for removal in a future version. Use timezone-aware
    objects to represent datetimes in UTC:
    datetime.datetime.now(datetime.UTC).

`datetime_to_datestamp()` in `oaipmh/datestamp.py` asserts that the
input has `tzinfo is None`, so we convert the timezone-aware UTC
value back to naive with `.replace(tzinfo=None)` before passing it
in. The resulting `responseDate` string in the OAI-PMH response is
unchanged.

This is the only `datetime.utcnow()` call in the codebase; after
this change, pyoai no longer emits `DeprecationWarning` for it on
Python 3.12+.
Replace deprecated datetime.utcnow() with timezone-aware equivalent
- Generated pyproject.toml with metadata migrated from setup.py/setup.cfg
- Python requirement raised to >=3.10 (dropping EOL 2.7/3.5-3.9)
- Initialized uv; uv.lock added to .gitignore (library)
- Removed obsolete packaging files: setup.py, setup.cfg, MANIFEST.in
- Updated .gitignore with modern Python patterns

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Normalized version 2.5.2pre -> 2.5.2 (PEP 440 compliant)
- Added [tool.bumpver] config to pyproject.toml
- Single source of truth: pyproject.toml only

Previously the version was inconsistent: setup.py had 2.5.2pre while
setup.cfg bumpversion pointed to 2.5.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Added .pre-commit-config.yaml with ruff lint + format
- Configured ruff with basic flake8-equivalent rules (E, F, W)
- Hooks run only on staged files — existing code not reformatted
- Added hygiene hooks: trailing-whitespace, end-of-file-fixer,
  check-yaml, check-added-large-files, detect-private-key

Install with: pre-commit install

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Python matrix: 3.10, 3.11, 3.12, 3.13 (was 2.7, 3.6-3.8)
- Use uv for Python install + dependency resolution
- Replace tox invocation with direct pytest
- Upgraded action versions: checkout@v4, setup-uv@v5
- Added informational-only ruff lint job (non-blocking)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Configured [tool.pytest.ini_options] in pyproject.toml
- python_classes = ["*TestCase"] to avoid collecting non-test TestError
- Removed tox.ini and src/oaipmh/tests/runtests.sh

Python 3.12+ compatibility fixes (required for test matrix):
- pkg_resources (removed from stdlib setuptools) -> importlib.metadata
- unittest.makeSuite / test_suite() -> removed (dead code for zope.testrunner)
- unittest.assertEquals (removed alias) -> assertEqual
- unittest.assert_ (removed alias) -> assertTrue
- lxml evaluator.evaluate (removed attribute) -> evaluator is callable directly
- Relative imports: `from fakeclient` -> `from .fakeclient`
- Dropped Python 2 compat shims (StringIO fallbacks, urllib2 fallback, six.PY2/PY3)

All 58 tests pass on Python 3.13.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- Replaced six.text_type with str
- Removed six.PY3 check (always True)
- Removed six from [project] dependencies

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Deleted:
- .hgignore, .hgtags (Mercurial remnants, repo is on git)
- buildout.cfg (zc.buildout config; replaced by uv)
- Makefile (referenced `python setup.py sdist upload`; had bogus path
  from another project; superseded by uv)
- INSTALL.txt (outdated: mentioned Python 2.3, `python setup.py install`,
  and codespeak lxml URL)

README.rst:
- Fixed Python 2 `print record` -> `print(record)`
- Updated CI badge to new workflow URL (mpasternak/pyoai)
- Added Python version support badge (3.10-3.13)
- Added modern installation instructions (pip, uv)
- Added development quickstart (uv sync, uv run pytest)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@mpasternak

Copy link
Copy Markdown
Collaborator Author

@ulikoehler let me know what you think about this, I'd bump version and release.

I just realised I can merge this PR but I won't, I'm waiting for your opinion on it.

Do we know if Infrae guys are alive/around?

@ulikoehler

Copy link
Copy Markdown
Owner

Hi @mpasternak , thanks for doing this modernization. Looks good to me , merging now ;-)

@ulikoehler
ulikoehler merged commit 3696c6c into ulikoehler:master May 4, 2026
5 checks passed
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.

2 participants