Python Style Guide¶
Python code should adhere to PEP 8, with the following clarifications:
- Only use four spaces for indentation, no tabs.
- Use Unix-style end of line (
LF
, aka'\n'
character). - Spaces around operators (except for keyword arguments).
- Use
CamelCase
for classes and exception types. Useunderscore_case
for everything else.
Automated Formatting¶
Most Python code is automatically formatted using autopep8.
Use make format
to format both C/C++ and Python code in the entire
repository, or integrate it in your IDE.
Additions to PEP 8¶
Naming¶
- Avoid shadowing names of Python built-in
functions,
constants,
types, and
exceptions.
Instead of using
object
, useobj
; as for other names, the Python built-ins are very generic, so often it is better to be more specific in your naming. For example, instead of naming a listlist
, name itobjects_to_export
. Not only does this avoid shadowing a built-in name, it also is more explicit and emphasizes the contents of the list. If you want to make the type of the variable explicit, use type annotations. - Avoid overly short names. Use
mesh
andcurve
instead ofme
andcu
(or worse,m
andc
).
Unused Variables & Arguments¶
It's sometimes necessary to declare variables or arguments that aren't used, in this case it's a common convention to begin the variable with an underscore.
Tools such as pylint
will skip them when reporting unused variables.
For example, a menu's draw method always takes a context argument, which you don't necessarily need.
class EXAMPLE_MT_menu(Menu):
bl_label = ""
def draw(self, _context):
layout = self.layout
layout.menu("EXAMPLE_MT_submenu_a")
layout.menu("EXAMPLE_MT_submenu_b")
Or when iterating over a sequence some items may not be used.
Exceptions to PEP 8¶
- Line width:
Maximum width for lines is 120 for all scripts. - Imports:
We often put imports within functions body which is not pep8 compliant.
This is done to speed up Blender's startup times to avoid loading in many files and libraries which the user may never access.
Conventions for Core Scripts¶
These scripts run as part of Blender at startup (scripts/startup
and
scripts in scripts/modules
that run on startup). There are some
additional conventions for these scripts.
-
Postpone importing Python modules, where imports may be in a function or a method body.
This is done for faster startup times and avoid unnecessary overhead when running tests or rendering in background mode.
-
No type annotations (besides those necessary for
bpy.props
use).Currently we don't have a practical way to validate these, see this task for details.
-
Use
str.format(..)
to format strings (no f-string or percentage-formatting).- Pass positional arguments to
str.format
.
- Use type specifiers such as
{:s}
,{:d}
,{:f}
for strings, integers and floats respectively. Forrepr(..)
:{!r}
can also be used.
- In some exceptional cases where it's more difficult to keep track of positional arguments,
developers may optionally pass keyword arguments to
str.format
.
See Python's string formatting documentation for details.
Note that
str.format
is used in favor of f-strings because string literals often need to be translated into other languages. It makes the code-base more straightforward to use one method of string formatting. (see: Python String Formatting for details). - Pass positional arguments to
-
Single quotes for enumerator literals, double quotes for everything else.
Use single quotes for enums in checks such as
ob.type == 'MESH'
, double quotes for other strings such aslayout.label(text="Label Text")
.