Python Development
Git Branching Strategy
We utilize a variation of the Gitlab Flow strategy.
Feature Branches
A feature branch is a dedicated branch used to implement a single feature in the project. When starting the development of a new feature, create a feature branch from the main as your starting point. If you anticipate that your work will depend on another branch, you may also branch out from that specific branch (and merge back into it later). Branches should be named following the format: feature/<feature-description>
, for example, feature/uniswap-min-liquidity. If the feature is actually a bug fix, name it as fix/<fix-description>
, such as fix/threading-issue. Upon completing the feature, merge the changes into the main branch using a pull request.
Release Branches
A release branch supports a new production release. When it's time for a new release, create a release branch using the main branch as a starting point. The branch should be named following this format: release-<major>.<minor>
, for example, release-1.0 or release-2.3. After the release branch is published, the following items can be added to the branch:
- Bug fixes
- Minor features, if a new release is not possible (for example, due to the presence of commits not ready for production in the main) If possible, first merge these fixes into main, and then cherry-pick them into the release branch. This approach is known as "upstream first".
rebase
and force push
The use of rebase
or force push
commands on any branch should only be executed after obtaining consent from all individuals interacting with that branch (including those who are just reading, for example, during code review).
Versioning
Each project is versioned in accordance with the Semver specification.
The version structure consists of three components: major, minor, and patch versions. Each is incremented as follows:
- Major version (0.x.y): Currently, the major version is consistently set to 0.
- Minor version (x.MINOR.y): The minor version is incremented when backwards incompatible changes are introduced.
- Patch version (x.y.PATCH): The patch version is incremented in all other cases, such as when backwards compatible changes are made or bugs are fixed.
Dependency Versioning
The management of dependency versions differs between library and non-library projects.
Non-Library Projects
Non-library projects, such as validator
, pin exact dependency versions. For example, requests==2.18.4
would be used instead of requests>=2.18.4
. This approach ensures stability, reliability, and prevents updates without necessity, guaranteeing reproducibility across all environments.
Libraries
Libraries, like quoting
, validator-shared
, and commons
, adopt a flexible versioning strategy, such as requests^2.18.4
, allowing for versions compatible with 2.18.4. This balances flexibility and stability, catering to the needs of both developers and users.
Style Guide
The default rule is to follow the style you see in the project.
Python Docstrings
We use a variation of the Sphinx format for docstrings. It is based on reStructuredText (reST) recommended by the PEP 287 and used by default in JetBrains PyCharm.
Example:
"""
Summary.
:param param1: this is a first param
:param param2: this is a second param
:returns: this is a description of what is returned
:raises keyError: raises an exception
"""
We adhere to the following specific practices:
- Docstring starts with an empty line
- Empty line after summary block is omitted
- Description block after summary may be omitted in obvious cases
- Docstrings can be omitted completely in private methods and functions