Skip to content

Contributor guidance

Random bits explaining some decisions

  • Application layout - Python Packaging Authority recommends the src layout
  • Standard to store version number in the package's __init__.py PEP8
  • Also store the version in pyproject.toml
  • Makefile contains most of the commonly used commands from this write-up. This file is used by GitHub workflow
  • Follow semantic versioning MAJOR.MINOR.PATCH

Setting up dev environment

  • install poetry
  • clone repo
  • set up a dev environment

    poetry install --with docs lint test semver notebook
    poetry run pre-commit install
    poetry run pre-commit install --hook-type pre-push
    

  • check it works: (you may need to download maps first)

    poetry run python tests/test_bots/melee_bot.py
    

Linting and autoformatting

  • ruff for autoformatting (enforced by GitHub actions)

ruff format .

  • ruff for linting (enforced by GitHub actions)

ruff check .

  • mypy for checking type annotations (enforced by GitHub actions)

mypy .

These tools can be configured to run automatically in your favourite IDE.

For mypy we configure via pyproject.toml, see docs See more here

Using via makefile

We put all these into a makefile, which allows us to do: make format Use the ruff formatter make lint Use the ruff and mypy linters

However, using makefiles on Windows requires a bit more setup

Unit tests

Read this, no point repeating it here

Each test should be small and self-contained

Simply run pytest to run existing tests.

Pre-commit

We use pre-commit to run our linters and formatters automatically before committing. Simply run pre-commit install to install the hooks, and then pre-commit run --all-files to run them on all files.

Git commit guidelines

See conventional commits, all commits and PR's should follow these guidelines

A github workflow is setup to enforce this, see here

Layout:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

Commit message no longer than 100 characters (scope is optional)

text This is a very short description of the change. - use imperative, present tense: “change” not “changed” nor “changes” - don't capitalize first letter - no dot (.) at the end

Python Semantic Release will recognise the types of commits to automatically determine a new version

  • fix: commit is a PATCH
  • feat: commit is a MINOR
  • BREAKING CHANGE or ! is a MAJOR
  • build:, chore:, ci:, docs:, style:, refactor:, perf:, test: do not increase version

A scope can also be added in parentheses. For example: feat(combat): add kiting behavior

Example of breaking change commit message feat(api)!: send an email to the customer when a product is shipped

Github workflow

All formatters and linters are run in a github workflow, we use the makefile here.

Coverage

Indicates how much code is covered by tests

Run coverage through pytest: pytest --cov=src --cov-report term-missing --cov-report=html

Run specific tests pytest -v -s tests/managers/test_building_manager.py::TestBuildingManager::test_construct_gas

Offical docs

Automatic documentation

Using mkdocs for no particular reason other than found a good tutorial using it

poetry add --group docs mkdocs mkdocs-material

Sphinx is another alternative

To build docs locally: mkdocs build

Push to github pages: (shouldn't need to use this) mkdocs gh-deploy -m "docs: update documentation" -v --force

Docstrings

Using numpy docstrings style

poetry add --group docs "mkdocstrings[python]"

At the relevant place in a markdown file add for example:

::: ares.example_docstrings
    options:
        show_root_heading: true
Where ares.example_docstrings is the python file containing numpy style docstrings

Pytest will run tests on any Examples in docstrings in Github workflow pytest --doctest-modules

Versioning and automatic releases

Use Python Semantic Release to create automatic releases based on the commits, therefore git commits should follow the Angular commit style

poetry add --group semver python-semantic-release

Python Semantic Release commands

In general if Github actions is working, these shouldn't need to be manually called.

Get current version: semantic-release print-version --current

Compute a version bump: semantic-release print-version --next

Get current changelog: semantic-release changelog --released

Generate a new changelog: semantic-release changelog --unreleased

Publish a release: semantic-release publish --noop

Poetry

Takes care of env, dependency, building and publishing

Useful commands

See Basic usage

Init new project, generates pyproject.toml that contains the entire package configuration. Fine to edit this

poetry init --name ares-sc2 --no-interaction

Run in virtual env (poetry uses venv) Managing poetry environments:

poetry run python src/ares/main.py

Run tests

poetry run pytest

Create and activate an environment (can also use PyCharm to create new env):

poetry env use python

On Linux possibly: poetry env use python3.10

Find environment in file system:

poetry env list --full-path

Use this path to add existing env in PyCharm

Can get a shell into the environment:

poetry shell

Install dependencies:

poetry add burnysc2

Create a lock file. Should be added to git. Ensures all people working on project using the same library versions. Automatically generated and shouldn't be edited

poetry lock

Install all dependencies based on the lock file

This command will read the TOML file, resolve all the dependencies and finally install them in a virtual environment that poetry will create by default under {cache-dir}/virtualenvs/.

poetry install

Install without dev tools

poetry install --without lint

List all installed dependencies:

poetry show

List current and latest available version

poetry show -l

Same as above, but only show outdated

poetry show -o

Update dependencies:

poetry update

Poetry can organise dependencies by groups, since dev tools etc are not required in the package release, eg:

poetry add --group lint isort black flake8 mypy

Notes about pyproject.toml

  • what backend to build the package: build-system (Instead of setup.py/setup.cfg or others, the backend to build the package is poetry)
  • some metadata for the project: tool.poetry (the initial version of the package*, description etc.)
  • the dependencies for the app: tool.poetry.dependencies
  • gotcha - The name in pyproject.toml should be the same as the package

Working with jupyter notebook

It's possible to run jupyter notebook using an existing poetry environment. Install the following package at the global or user level:

pip install --user poetry-kernel

As long as ares-sc2 was installed with the notebook dependencies, then when launching jupyter notebook there should be an option to open a notebook with the poetry kernel