Each commit message should start with a directory or full file path prefix, so it was clear which part of codebase a commit affects. If a change affects one file, it's better to use path to a file. If it affects few files in a subdirectory, using subdirectory as a prefix is ok. For longish paths, it's acceptable to drop intermediate components, which still should provide good context of a change. It's also ok to drop file extensions.
Besides prefix, first line of a commit message should describe a change clearly and to the point, and be a grammatical sentence with final full stop. First line must fit within 72 characters. Examples of good first line of commit messages:
py/objstr: Add splitlines() method.
py: Rename FOO to BAR.
docs/machine: Fix typo in reset() description.
ports: Switch to use lib/foo instead of duplicated code.
After the first line add an empty line and in the following lines describe the change in a detail, if needed, with lines fitting within 75 characters (with an exception for long items like URLs which cannot be broken). Any change beyond 5 lines would likely require such detailed description.
To get good practical examples of good commits and their messages, browse
the git log
of the project.
When committing you must sign-off your commit by adding "Signed-off-by:"
line(s) at the end of the commit message, e.g. using git commit -s
. You
are then certifying and signing off against the following:
Both C and Python code formatting are controlled for consistency across the
MicroPython codebase. C code is formatted using the tools/codeformat.py
script which uses uncrustify.
Python code is linted and formatted using
ruff & ruff format.
After making changes, and before committing, run tools/codeformat.py
to
reformat your C code and ruff format
for any Python code. Without
arguments this tool will reformat all source code (and may take some time
to run). Otherwise pass as arguments to the tool the files that changed,
and it will only reformat those.
Only uncrustify v0.71 or v0.72 can be used for MicroPython. Different uncrustify versions produce slightly different formatting, and the configuration file formats are often incompatible. v0.73 or newer will not work.
Depending on your operating system version, it may be possible to install a pre-compiled uncrustify version:
Ubuntu versions 21.10 or 22.04LTS, and Debian versions bullseye or bookworm all include v0.72 so can be installed directly:
$ apt install uncrustify
The current Arch uncrustify version is too new. There is an old Arch package for v0.72 that can be installed from the Arch Linux archive (more information). Use the IgnorePkg feature to prevent it re-updating.
This command may work, please raise a new Issue if it doesn't:
curl -L https://github.com/Homebrew/homebrew-core/raw/2b07d8192623365078a8b855a164ebcdf81494a6/Formula/uncrustify.rb > uncrustify.rb && brew install uncrustify.rb && rm uncrustify.rb
Code spell checking is done using codespell
and runs in a GitHub action in CI. Codespell is configured via pyproject.toml
to avoid false positives. It is recommended run codespell before submitting a
PR. To simplify this, codespell is configured as a pre-commit hook and will be
installed if you run pre-commit install
(see below).
If you want to install and run codespell manually, you can do so by running:
$ pip install codespell tomli
$ codespell
To have code formatting and commit message conventions automatically checked, a configuration file is provided for the pre-commit tool.
First install pre-commit
, either from your system package manager or via
pip
. When installing pre-commit
via pip, it is recommended to use a
virtual environment. Other sources, such as Brew are also available, see
the docs for details.
$ apt install pre-commit # Ubuntu, Debian
$ pacman -Sy python-precommit # Arch Linux
$ brew install pre-commit # Brew
$ pip install pre-commit # PyPI
Next, install uncrustify (see above). Other dependencies are managed by pre-commit automatically, but uncrustify needs to be installed and available on the PATH.
Then, inside the MicroPython repository, register the git hooks for pre-commit by running:
$ pre-commit install --hook-type pre-commit --hook-type commit-msg
pre-commit will now automatically run during git commit
for both code and
commit message formatting.
The same formatting checks will be run by CI for any Pull Request submitted to MicroPython. Pre-commit allows you to see any failure more quickly, and in many cases will automatically correct it in your local working copy.
To unregister pre-commit
from your MicroPython repository, run:
$ pre-commit uninstall --hook-type pre-commit --hook-type commit-msg
Tips:
git commit -n
(for
--no-verify
).Once pre-commit is installed as per the previous section it can be manually run against the MicroPython python codebase to update file formatting on demand, with either:
pre-commit run --all-files
to fix all files in the MicroPython codebasepre-commit run --file ./path/to/my/file
to fix just one filepre-commit run --file ./path/to/my/folder/*
to fix just one folderPython code follows PEP 8 and is auto-formatted using ruff format with a line-length of 99 characters.
Naming conventions:
C code is auto-formatted using uncrustify
and the corresponding configuration file tools/uncrustify.cfg
, with a few
minor fix-ups applied by tools/codeformat.py
. When writing new C code please
adhere to the existing style and use tools/codeformat.py
to check any changes.
The main conventions, and things not enforceable via the auto-formatter, are
described below.
White space:
Braces:
Header files:
Names:
Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's important to use the correctly-sized (and signed) integer types. The general guidelines are:
Comments:
//
prefix, NOT /* ... */
. No extra fluff.Memory allocation:
Braces, spaces, names and comments:
#define TO_ADD (123)
// This function will always recurse indefinitely and is only used to show
// coding style
int foo_function(int x, int some_value) {
if (x < some_value) {
foo(some_value, x);
} else {
foo(x + TO_ADD, some_value - 1);
}
for (int my_counter = 0; my_counter < x; ++my_counter) {
}
}
Type declarations:
typedef struct _my_struct_t {
int member;
void *data;
} my_struct_t;
MicroPython generally follows CPython in documentation process and conventions. reStructuredText syntax is used for the documentation.
Specific conventions/suggestions:
*
markup to refer to arguments of a function, e.g.:.. method:: poll.unregister(obj)
Unregister *obj* from polling.
:func:`foo` - function foo in current module
:func:`module1.foo` - function foo in module "module1"
(similarly for other referent types)
:class:`Foo` - class Foo
:meth:`Class.method1` - method1 in Class
:meth:`~Class.method1` - method1 in Class, but rendered just as "method1()",
not "Class.method1()"
:meth:`title <method1>` - reference method1, but render as "title" (use only
if really needed)
:mod:`module1` - module module1
`symbol` - generic xref syntax which can replace any of the above in case
the xref is unambiguous. If there's ambiguity, there will be a warning
during docs generation, which need to be fixed using one of the syntaxes
above
.. _xref_target:
Normal non-indented text.
This is :ref:`reference <xref_target>`.
(If xref target is followed by section title, can be just
:ref:`xref_target`).
`link text <http://foo.com/...>`_
``None``, ``True``, ``False``
.. function:: foo(x)
bar(y)
Description common to foo() and bar().
More detailed guides and quickrefs:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。