Skip to content
Back to top
View this page

# Developer’s Overview

## Quick Start for Contributors

- Fork the repository on GitHub and clone your fork.

- Create a new branch for your changes.

- Set up your development environment.

- Make your changes, add/update tests and documentation as needed.

- Run tox to check your changes.

- Push your branch and open a pull request.

## Contributing

Welcome! Thank you for your interest in python-can. Whether you want to fix a bug, add a feature, improve documentation, write examples, help solve issues, or simply report a problem, your contribution is valued. Contributions are made via the python-can GitHub repository. If you have questions, feel free to open an issue or start a discussion on GitHub.

If you’re new to the codebase, see the next section for an overview of the code structure. For more about the internals, see Internal API and information on extending the `can.io` module.

### Code Structure

The modules in `python-can` are:

Module | Description
--- | ---
interfaces | Contains interface dependent code.
bus | Contains the interface independent Bus object.
message | Contains the interface independent Message object.
io | Contains a range of file readers and writers.
broadcastmanager | Contains interface independent broadcast manager code.

### Step-by-Step Contribution Guide

1. Fork and Clone the Repository

   - Fork the python-can repository on GitHub to your own account.

   - Clone your fork:

         git clone https://github.com/<your-username>/python-can.git
         cd python-can

   - Create a new branch for your work:

         git checkout -b my-feature-branch

   - Ensure your branch is up to date with the latest changes from the main repository. First, add the main repository as a remote (commonly named upstream) if you haven’t already:

         git remote add upstream https://github.com/hardbyte/python-can.git

     Then, regularly fetch and rebase from the main branch:

         git fetch upstream
         git rebase upstream/main

2. Set Up Your Development Environment

   We recommend using uv to install development tools and run CLI utilities. uv is a modern Python packaging tool that can quickly create virtual environments and manage dependencies, including downloading required Python versions automatically. The uvx command allows you to run CLI tools in isolated environments, separate from your global Python installation. This is useful for installing and running Python applications (such as tox) without affecting your project’s dependencies or environment.

   Install tox (if not already available):

       uv tool install tox --with tox-uv

   Quickly running your local python-can code

   To run a local script (e.g., snippet.py) using your current python-can code, you can use either the traditional virtualenv and pip workflow or the modern uv tool.

   Traditional method (virtualenv + pip):

   Create a virtual environment and install the package in editable mode. This allows changes to your local code to be reflected immediately, without reinstalling.

       # Create a new virtual environment
       python -m venv .venv

       # Activate the environment
       .venv\Scripts\activate    # On Windows
       source .venv/bin/activate  # On Unix/macOS

       # Upgrade pip and install python-can in editable mode with development dependencies
       python -m pip install --upgrade pip
       pip install -e .[dev]

       # Run your script
       python snippet.py

   Modern method (uv):

   With uv, you can run your script directly:

       uv run snippet.py

   When `uv run ...` is called inside a project, uv automatically sets up the environment and symlinks local packages. No editable install is needed—changes to your code are reflected immediately.

3. Make Your Changes

   - Edit code, documentation, or tests as needed.

   - If you fix a bug or add a feature, add or update tests in the `test/` directory.

   - If your change affects users, update documentation in `doc/` and relevant docstrings.

4. Test Your Changes

   This project uses tox to automate all checks (tests, lint, type, docs). Tox will set up isolated environments and run the right tools for you.

   To run all checks:

       tox

   To run a specific check, use:

       tox -e lint      # Run code style and lint checks (black, ruff, pylint)
       tox -e type      # Run type checks (mypy)
       tox -e docs      # Build and test documentation (sphinx)
       tox -e py        # Run tests (pytest)

   To run all checks in parallel (where supported), you can use:

       tox p

   Some environments require specific Python versions. If you use uv, it will automatically download and manage these for you.

5. Add a News Fragment for the Changelog

   This project uses towncrier to manage the changelog in `CHANGELOG.md`. For every user-facing change (new feature, bugfix, deprecation, etc.), you must add a news fragment:

   - News fragments are short files describing your change, stored in `doc/changelog.d`.

   - Name each fragment `<issue-or-description>.<type>.md`, where `<type>` is one of: `added`, `changed`, `deprecated`, `removed`, `fixed`, or `security`.

   - Example (for a feature added in PR #1234):

         echo "Added support for CAN FD." > doc/changelog.d/1234.added.md

   - Or use the towncrier CLI:

         uvx towncrier create --dir doc/changelog.d -c "Added support for CAN FD." 1234.added.md

   - For changes not tied to an issue/PR, the fragment name must start with a plus symbol (e.g., `+mychange.added.md`). Towncrier calls these “orphan fragments”.

   Note

   You do not need to manually update `CHANGELOG.md`—maintainers will build the changelog at release time.

6. (Optional) Build Source Distribution and Wheels

   If you want to manually build the source distribution (sdist) and wheels for python-can, you can use uvx to run the build and twine tools:

       uv build
       uvx twine check --strict dist/*

7. Push and Submit Your Contribution

   - Push your branch:

         git push origin my-feature-branch

   - Open a pull request from your branch to the `main` branch of the main python-can repository on GitHub.

   Please be patient — maintainers review contributions as time allows.

## Creating a new interface/backend

Attention

Please note: Pull requests that attempt to add new hardware interfaces directly to the python-can codebase will not be accepted. Instead, we encourage contributors to create plugins by publishing a Python package containing your `can.BusABC` subclass and using it within the python-can API. We will mention your package in this documentation and add it as an optional dependency. For current best practices, please refer to Plugin Interface.

The following guideline is retained for informational purposes only and is not valid for new contributions.

These steps are a guideline on how to add a new backend to python-can.

- Create a module (either a `*.py` or an entire subdirectory depending on the complexity) inside `can.interfaces`. See `can/interfaces/socketcan` for a reference implementation.

- Implement the central part of the backend: the bus class that extends `can.BusABC`. See Extending the BusABC class for more info on this one!

- Register your backend bus class in `BACKENDS` in the file `can.interfaces.__init__.py`.

- Add docs where appropriate. At a minimum add to `doc/interfaces.rst` and add a new interface specific document in `doc/interface/*`. It should document the supported platforms and also the hardware/software it requires. A small snippet of how to install the dependencies would also be useful to get people started without much friction.

- Also, don’t forget to document your classes, methods and function with docstrings.

- Add tests in `test/*` where appropriate. For example, see `test/back2back_test.py` and add a test case like `BasicTestSocketCan` for your new interface.

## Creating a new Release

Releases are automated via GitHub Actions. To create a new release:

- Build the changelog with towncrier:

  - Collect all news fragments and update `CHANGELOG.md` by running:

        uvx towncrier build --yes --version vX.Y.Z

    (Replace `vX.Y.Z` with the new version number. The version must exactly match the tag you will create for the release.) This will add all news fragments to the changelog and remove the fragments by default.

    Note

    You can generate the changelog for prereleases, but keep the news fragments so they are included in the final release. To do this, replace `--yes` with `--keep`. This will update `CHANGELOG.md` but leave the fragments in place for future builds.

  - Review `CHANGELOG.md` for accuracy and completeness.

- Ensure all tests pass and documentation is up-to-date.

- Update `CONTRIBUTORS.txt` with any new contributors.

- For larger changes, update `doc/history.rst`.

- Create a new tag and GitHub release (e.g., `vX.Y.Z`) targeting the `main` branch. Add release notes and publish.

- The CI workflow will automatically build, check, and upload the release to PyPI and other platforms.

- You can monitor the release status on: PyPi, Read the Docs and GitHub Releases.