Thank you for considering contributing to reader!
Please report issues via GitHub Issues.
When doing so:
- Write a short, descriptive title.
- Describe what you expected to happen.
- Include a minimal reproducible example if possible. This helps identify the root cause and confirm the issue is not with your own code.
- Describe what actually happened. Include the full traceback if there was an exception, and any other relevant output.
- List the Python and reader versions you are using. If possible, check if the issue is already fixed in the latest PyPI release or in the latest :ref:`pre-release code <install-pre-release>`.
Please use Github Discussions for support or general questions.
Please use GitHub Issues to discuss non-trivial changes:
- If there is no open issue, open one before working on a pull request.
- You can work on any help wanted issue that does not have an open PR or an assigned maintainer (no need to ask).
- For other open issues, please ask first, there may be background that didn't end up in the issue yet; also see :ref:`roadmap` and :ref:`design notes`.
- For trivial changes (e.g. typos), you can open a PR directly.
When working on a pull request:
- Consider whether the change is necessary.
- Make minimal, focused changes.
- Follow existing coding style and patterns.
- Write tests that exercise the change.
- Update relevant documentation and docstrings.
- Follow the :ref:`ai` policy.
Before submitting the PR, make sure that :ref:`tests <tests>`, :ref:`coverage <test-coverage>`, :ref:`type checking <type-checking>`, and :ref:`linters <linters>` pass.
run.sh
The :gh:`run.sh <run.sh>` script in the repository root wraps standard Python development tools in commands that serve as executable documentation (i.e. a summary of the guide below).
Where applicable, a matching ./run.sh command for each section is shown;
you are welcome to use that or invoke the tool directly,
whichever is more convenient.
The -dev version of a command
reruns it whenever files change,
usually using entr.
Make sure you have a GitHub account.
Download and install the latest version of git.
Configure git with your username and email.
$ git config --global user.name 'your name' $ git config --global user.email 'your email'
Fork reader to your GitHub account by clicking the Fork button.
Clone your fork locally, replacing
your-usernamein the command below with your actual username.$ git clone https://github.com/your-username/reader $ cd reader
Create a virtualenv. Use the latest version of Python.
Linux/macOS
$ python3 -m venv .venv $ . .venv/bin/activate
Windows
> py -3 -m venv .venv > .venv\Scripts\activate
run.sh
./run.sh install- Install development dependencies and pre-commit hooks.
Install reader in editable mode, with all :ref:`extras <optional dependencies>` and development dependencies:
$ pip install -e '.[all]' --group devInstall pre-commit hooks, so that :ref:`linters <linters>` run automatically before each commit:
$ pre-commit install --install-hooksCreate a branch to identify the issue you will work on.
Branch off of the master branch.
$ git fetch origin
$ git checkout -b your-branch-name origin/masterUsing your favorite editor, make your changes, committing as you go.
Include tests that cover any code changes you make. Make sure the test fails without your patch. Run the tests and type checking as described below.
Update any relevant documentation pages and docstrings; see :ref:`documentation` for details. Adding a changelog entry is optional, a maintainer will write one if you're not sure how to.
run.sh
./run.sh test- Run tests.
./run.sh test-dev- Run tests when files change.
Run the tests with pytest (including slow tests):
$ pytest --runslowrun.sh
./run.sh coverage- Run test coverage and generate reports.
Generating a report of lines that do not have test coverage can indicate what code needs to be tested. Use coverage to run pytest, generate an HTML report, and check required coverage:
$ coverage run -m pytest --runslow
$ coverage html
$ ./run.sh coverage-reportOpen htmlcov/index.html in your browser to explore the report.
The core library must have 100% test coverage. Experimental plugins, the command-line interface, and the web application do not have coverage requirements.
run.sh
./run.sh typing- Run type checking.
./run.sh typing-dev- Run type checking when files change.
Run type checking with mypy:
$ mypyThe core library must pass strict type checking. Plugins, the command-line interface, and the web application do not have type checking requirements.
pre-commit will run Black, Flake8 etc. automatically before each commit.
run.sh
./run.sh docs- Build the docs.
./run.sh docs-dev- Build the docs when files change.
Build the documentation using Sphinx:
$ sphinx-build -E -W docs docs/_build/htmlOpen docs/_build/html/index.html in your browser to view the built documentation.
run.sh
./run.sh test-all- Run tests on all supported Python versions.
Run tests on all supported Python versions with tox:
$ tox run-parallelThis includes coverage, type checking, and documentation, making it the closest to a full CI run possible locally.
Push your commits to your fork on GitHub and create a pull request.
Link to the issue being addressed with Fixes #123.
in the pull request description.
$ git push --set-upstream origin your-branch-nameContributions must not include content generated by large language models to any significant extent, including but not limited to code, documentation, pull requests, issues, and comments.
I am open to revisiting this later, once the problems surrounding LLMs are mitigated.
Using AI to fix issues labeled as good first issue is forbidden, since they are meant to be learning opportunities for new contributors to get familiar with the codebase.
For a detailed rationale, see the early 2026 versions of the Servo, CPython, and LLVM policies.