All changes to code and documentation should be submitted via a pull request to the GitHub repository for the project.

Most projects have a dedicated contribution guide with details specific to that project, or specific types of contribution. This documentation can be found on Read the Docs. For example, Briefcase's documentation contains contribution guides for both code and documentation.

All submissions should abide by the BeeWare Code of Conduct.

Change Notes

Several BeeWare projects, notably Briefcase and Toga, require that each pull request is submitted with a change note. These change notes are compiled together when a new release is cut for the project, producing the release notes for the new release.

BeeWare uses Towncrier to manage change notes.

A change note file should be created in the changes directory and named using this format:

<PR/Issue #>.<Change Type>.rst

For instance, a pull request that fixes GitHub issue #42 would be named 42.bugfix.rst. If a pull request is not associated with a specific issue, then the pull request number can be used instead. You may need to create the pull request without a change note to get a pull request number allocated, then push an update that includes the change note with the newly allocated pull request number.

The change types for the change note should be one of the following:

  • feature
  • bugfix
  • doc
  • removal
  • misc

The misc type is reserved for changes that do not affect users, and don't need to be noted in the release notes. Minor typographical fixes in documentation, updates to CI configuration, and bug fixes for features that haven't yet been formally released are examples of features that would be described using misc markers.

A change note should be a single line of text, providing a high level summary of the change from the perspective of the user, not a deep technical description or implementation detail. It is distinct from a commit message. A commit message describes what has been done so that future developers can follow the reasoning for a change. A change note is a "user facing" description, described in terms of the new capability that is available as a result of change. It may help to think of the change note as a press release announcing the change, rather than a commit description.

For example, if you fix a bug caused by date handling, the commit message or pull request description might read:

Added a MM-DD-YYYY format validator to the DateWidget validation chain.

This describes the change that was made to the implementation - detail that will be helpful to the person reviewing the code. However, the corresponding change note might read something like:

Date widgets can now accept dates in US format.

This describes the functional change as it will be experienced by end users. A user can read this description without needing to know anything about the implementation.

Code style

BeeWare's projects use Pre-commit to automate code style adherence. These checks are defined in the .pre-commit-config.yaml file for each repository and are automatically run in CI when a Pull Request is opened.

To automate the Pre-commit checks in your local development environment with each git commit, run pre-commit install.

Included Pre-commit checks:

  • Black ensures uniform code formatting
  • docformatter ensures uniform formatting for docstrings and comments
  • pyupgrade ensures code is using the latest best practices for Python
  • isort ensures uniform import statements
  • flake8 checks for common coding and syntax issues
  • Misc checks that validate structured documents such as TOML files and remove unnecessary whitespace

Additional guidelines:

  • Avoid use of "we" in comments, e.g. "Loop over" rather than "We loop over"

  • Use underscores, not camelCase, for variable, function and method names

  • Use InitialCaps for class names (or for factory functions that return classes)

  • Use Sphinx-style docstrings and PEP 257; type annotation with PEP 484 is optional but encouraged.

    For example:

    def function_name(param1: int, param2: str) -> bool:
        """Example function with types and a docstring.
        :param param1: The first parameter.
        :param param2: The second parameter.
        :returns: The return value. True for success, False otherwise.
  • In test docstrings, state the expected behavior that each test demonstrates. Don't include preambles such as "Tests that" or "Ensures that".

  • Reserve ticket references for obscure issues where the ticket has additional details that can't be easily described in docstrings or comments. Include the ticket number at the end of a sentence like this:

    def test_foo():
        """A test docstring looks like this (#123456)."""
  • Unless otherwise specified, follow PEP 8 (with careful attention paid to Section 2).