Python Conventions
Note, these are guidelines used by the SCD Cloud Operations Group. They are being presented externally as they may be useful for those developing their own software, they are not being provided with the intention of the Cloud Team reviewing your code - unless you are contributing to one of our repositories.
Style guides refer to a set of standards for writing and formatting code. Having a consistent style guide makes it much easier to understand a large codebase. We recommend using the following style guides.
- 1 Python
- 1.1 Versioning
- 1.2 Variable Naming Conventions
- 1.3 Doc-strings
- 1.4 Logging
- 1.4.1 Inheritance
- 2 Guidelines
Python
Python code should follow Generic coding conventions as specified in the Style Guide for Python Code (PEP 8).
General conventions include:
4 spaces per indentation level - no hard tabs.
UTF-8 encoding
Maximum of 78 characters per line.
Versioning
Use a package manager like conda, pipenv, etc to better manage your python environments.
In general - aim to support all python versions until they reach security support EOL - Python EOL dates
Variable Naming Conventions
Of particular importance should be with with variable naming conventions
PEP 8 – Style Guide for Python Code | peps.python.org
CapWords
convention for Class namesUse
lowercase
orlowercase_with_underscores
for function, method, and variable names.For short names, joined lowercase may be used (e.g. "tagname"). Choose what is most readable.
No single-character variable names, except indices in loops that encompass a very small number of lines
Use
'single quotes'
for string literals, and"""triple double quotes"""
for docstrings.Use double quotes for strings when necessary like
"don't"
.
When using dataclasses - it should belong to the module using it
Doc-strings
We use reStructuredText (reST) format for our docstrings. This is used by default in PyCharm
"""
This is a reST style.
: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
"""
Logging
Here is an example to setup logging to a file:
import logging
logger = logging.getLogger()
logStream = logging.FileHandler("my.log")
FORMAT='%(asctime)s (UTC) [ %(levelname)s ] %(name)s %(filename)s:%(lineno)d %(funcName)s(): %(message)s'
formatter = logging.Formatter(FORMAT)
logStream.setFormatter(formatter)
logger.addHandler(logStream)
logger.setLevel(logging.DEBUG)
Use the right log filename and the appropriate logging level.
With that FORMAT
, log lines look like this:
2025-01-15 11:43:09,558 (UTC) [ INFO ] root main.py:14 main(): this is a log message
Inheritance
To ensure that both libraries and clients use the same format, the best strategy is:
clients instantiate the root logger:
libraries instantiate a named logger:
Guidelines
When contributing code, you should use a Linter.
A Linter is a tool that performs static source code analysis. The tool can check your code syntax and provide instructions on how to improve it.
For Python, recommend pylint
: https://pypi.org/project/pylint/
Flake 8 is another linter: https://flake8.pycqa.org/en/latest/index.html
For Python, code can be automatically formatted to match PEP8 style guide using black
: https://black.readthedocs.io/en/stable/
Black is an opinionated code formatter, it can take your Python code and automatically reformat it to adhere to a strict set of style guidelines. Its a good idea to run black
just before you commit and push your code to GitHub.
Versioning and Release
In general, we use http://semver.org
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner
PATCH version when you make backwards-compatible bug fixes.