Skip to content

Adopt the ruff/pyright/pytest toolchain and gate CI - #44

Merged
jhansche merged 5 commits into
jhansche:mainfrom
parrot-tailor:split/pr2-toolchain
Jul 19, 2026
Merged

Adopt the ruff/pyright/pytest toolchain and gate CI#44
jhansche merged 5 commits into
jhansche:mainfrom
parrot-tailor:split/pr2-toolchain

Conversation

@parrot-tailor

Copy link
Copy Markdown
Contributor

Split of #40, part 2 of 3. Per your review there, separating pure repo/tooling from linting/functional and test.

Commits

The diff is on the large side because of the ruff formatting and type fixes, but this PR is scoped better than #40 was 😄. You might want to look at 50420dc, 795551c, bb180de, and 0732ac6 separately first (that's the actual work, formatting was either automatically fixed by ruff, or hand-fixed in the case of lines that exceeded Black's 88 chars)

  1. 50420dc Adopt the ruff/pyright/pytest toolchain — adds a Makefile, the ruff/pyright/pytest/coverage config, and the markdownlint config. Brings the dev extras in pyproject.toml up to the latest versions, resolving the failures in Bump the pip group with 5 updates #43. Now make test runs the full format/lint/type check/test workflow.
  2. 97291e5 Resolve all ruff and pyright findings; adopt Google-style docstrings — set max line length is to 88 (the ruff/Black default), switch to absolute imports, use Google-style docstrings, improve type annotations, and rewrite asserts in non-test code as explicit raises. Ships a PEP 561 py.typed marker so downstream consumers can use our types.
  3. 795551c Guard the postcard argument against an unbound local — reanalyze_postcard/sighting_from_postcard branched on str/FeedNode, leaving postcard_id unbound (UnboundLocalError) for any other input; adds an else that raises a clear TypeError, plus a test.
  4. bb180de Restructure the README and document the dev workflow — clearer structure, adds status shields (version, license, build status, etc.)
  5. 0732ac6 Gate CI and publish test results across Python 3.10–3.14 — replace the pytest-only workflow with make deps + make test. Uploads coverage reports as artifacts for individual CI runs. Extends the matrix to include Python 3.13 and 3.14.

Testing

Ran make test on Python 3.10.20 (lowest supported runtime) — ruff, ruff format --check, markdownlint (0 issues), pyright (0 errors, 0 warnings), pytest (12 passed). Also ran tests locally against 3.12 and 3.14, but of course CI is the final arbiter for the matrix.

Add the Makefile, the ruff/pyright/pytest/coverage config, and the
markdownlint config; bring the dev extra up to the tools they run; and
ignore the junit.xml that the pytest config emits.
Bring the tree to a clean gate (make test: ruff, ruff format,
markdownlint, pyright, pytest) without changing valid-input behavior:

- Format to line-length 88 and sort imports; convert package-relative
  imports to absolute (TID252, ban-relative-imports = all). Symbol
  imports are kept (not module-qualified).
- Rewrite docstrings to Google style: Args/Returns/Raises on functions
  with parameters, attribute-style one-liners on properties; convert the
  old reStructuredText :param blocks.
- Add type annotations; refine loose return types (e.g. str | None,
  datetime | None), fix UserDict[str, any] (the builtin) to typing.Any,
  and correct GraphqlError.error_code to str | None.
- Remove asserts from source (they are reserved for tests): precondition
  asserts become explicit raises, and the two assert-await-refresh cases
  become plain await calls so the request is not tied to an assertion.
- Keep the N818 noqa on CompositeException (public name, no rename).
- Ship the PEP 561 py.typed marker in the wheel (package-data) so
  downstream consumers can use the annotations.
- Reflow README prose to satisfy markdownlint.

make test passes on 3.10.20.
reanalyze_postcard and sighting_from_postcard branched on str / FeedNode
with no else, leaving postcard_id unbound (UnboundLocalError) for any
other input type. Add an else that raises a clear TypeError. Valid str /
FeedNode inputs behave identically. Add a guard test.
Give the README a clear structure and fix its broken examples:

- Add the project description and status shields (PyPI version, build,
  maintenance, GitHub release, license).
- Split the content into Installation, Usage, Translations,
  Development and Releasing sections.
- Fix the Translations example: import BirdBuddy from birdbuddy.client
  (the package root only exports LOGGER/VERBOSE) and instantiate it with
  credentials instead of referencing the bare class.
- Document the development workflow: pyenv, make deps and the make
  targets (each self-activates the venv), plus pip install -e '.[dev]'.
- Document the PyPI release process: bump the version, then make build
  (python -m build -> sdist + wheel) and make publish (twine check +
  upload), including how twine reads its credentials.
Run the full gate in CI instead of pytest alone: set up Python and Node
(markdownlint and pyright are Node-based), install the toolchain with make
deps, then make test (ruff, ruff format --check, markdownlint, pyright,
pytest). Upload the junit and coverage reports as artifacts and publish
the pytest results as a PR check with dorny/test-reporter. Extend the
matrix to Python 3.13 and 3.14.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the repo’s Python toolchain and CI gate by adopting ruff + pyright + pytest/coverage, adding Makefile-driven workflows, and applying formatting/type/docstring updates across the codebase (including a PEP 561 py.typed marker).

Changes:

  • Add/standardize the ruff/pyright/pytest/coverage/markdownlint configuration and a Makefile-driven make deps / make test workflow.
  • Gate CI with the Makefile across a broader Python matrix and publish JUnit/coverage artifacts.
  • Apply type-annotation/docstring/formatting updates and add a regression test for invalid postcard input types.

Reviewed changes

Copilot reviewed 27 out of 29 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/test_sighting_create.py Adds docstrings and a new test covering invalid reanalyze_postcard input types.
tests/test_issue_40.py Adds docstrings and minor formatting tweaks for strategy regression tests.
tests/test_exceptions.py Tightens imports and clarifies regression test docstring wording.
tests/conftest.py Adds fixture docstrings, typing, and refactors fixture construction/patching.
tests/__init__.py Minor docstring punctuation update.
README.md Restructures README; documents installation/dev/release workflow and shields.
pyrightconfig.json Adds pyright configuration (tests execution environment, excludes).
pyproject.toml Updates dev deps; adds ruff/pytest/coverage configuration; ships py.typed.
Makefile Introduces Makefile targets for deps/format/test/schema/build/publish/clean.
dump_schema.py Adds module docstring; uses pathlib for writing schema.json.
birdbuddy/user.py Docstring and minor style updates.
birdbuddy/sightings.py Broad typing/docstring/format updates across sightings models.
birdbuddy/queries/me.py Docstring punctuation update.
birdbuddy/queries/feeder.py Docstring punctuation update.
birdbuddy/queries/debug.py Adds module docstring for schema introspection query.
birdbuddy/queries/birds.py Docstring punctuation update.
birdbuddy/queries/auth.py Docstring punctuation update.
birdbuddy/queries/__init__.py Switches to absolute imports and defines __all__.
birdbuddy/py.typed Adds PEP 561 marker to publish type information.
birdbuddy/media.py Adds typing/docstrings and adjusts media-expiry helper implementation.
birdbuddy/feeder.py Adds typing/docstrings and converts to absolute imports.
birdbuddy/feed.py Adds typing/docstrings and changes edges/nodes to iterators.
birdbuddy/exceptions.py Expands docstrings and clarifies public API compatibility notes.
birdbuddy/client.py Adds typing/docstrings, improves input validation, and updates request handling.
birdbuddy/birds.py Docstring punctuation update.
birdbuddy/__init__.py Docstring punctuation update.
.markdownlint.yaml Adds markdownlint configuration.
.gitignore Ignores junit.xml.
.github/workflows/python-package.yml Gates CI via make deps + make test, expands Python matrix, uploads/publishes results.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread birdbuddy/media.py
Comment thread birdbuddy/client.py
Comment thread birdbuddy/feed.py
Comment thread birdbuddy/feed.py
@jhansche
jhansche merged commit d2e8159 into jhansche:main Jul 19, 2026
5 checks passed
@jhansche

Copy link
Copy Markdown
Owner

Agreed: copilot flagged existing issues, not introduced in this PR 👍

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.

3 participants