Pocoo Styleguide
The Pocoo styleguide is the styleguide for all Pocoo Projects, includingFlask. This styleguide is a requirement for Patches to Flask and arecommendation for Flask extensions.
In general the Pocoo Styleguide closely follows PEP 8 with some smalldifferences and extensions.
General Layout
- Indentation:
4 real spaces. No tabs, no exceptions.
Maximum line length:
79 characters with a soft limit for 84 if absolutely necessary. Tryto avoid too nested code by cleverly placing break, continue andreturn statements.
Continuing long statements:
- To continue a statement you can use backslashes in which case you shouldalign the next line with the last dot or equal sign, or indent fourspaces:
- this_is_a_very_long(function_call, 'with many parameters') \
- .that_returns_an_object_with_an_attribute
- MyModel.query.filter(MyModel.scalar > 120) \
- .order_by(MyModel.name.desc()) \
- .limit(10)
If you break in a statement with parentheses or braces, align to thebraces:
- this_is_a_very_long(function_call, 'with many parameters',
- 23, 42, 'and even more')
For lists or tuples with many items, break immediately after theopening brace:
- items = [
- 'this is the first', 'set of items', 'with more items',
- 'to come in this line', 'like this'
- ]
- Blank lines:
- Top level functions and classes are separated by two lines, everythingelse by one. Do not use too many blank lines to separate logicalsegments in code. Example:
- def hello(name):
- print 'Hello %s!' % name
- def goodbye(name):
- print 'See you %s.' % name
- class MyClass(object):
- """This is a simple docstring"""
- def __init__(self, name):
- self.name = name
- def get_annoying_name(self):
- return self.name.upper() + '!!!!111'
Expressions and Statements
- General whitespace rules:
No whitespace for unary operators that are not words(e.g.:
-
,~
etc.) as well on the inner side of parentheses.Whitespace is placed between binary operators.
Good:
- exp = -1.05
- value = (item_value / item_count) * offset / exp
- value = my_list[index]
- value = my_dict['key']
Bad:
- exp = - 1.05
- value = ( item_value / item_count ) * offset / exp
- value = (item_value/item_count)*offset/exp
- value=( item_value/item_count ) * offset/exp
- value = my_list[ index ]
- value = my_dict ['key']
- Yoda statements are a no-go:
- Never compare constant with variable, always variable with constant:
Good:
- if method == 'md5':
- pass
Bad:
- if 'md5' == method:
- pass
- Comparisons:
against arbitrary types:
==
and!=
against singletons with
is
andis not
(eg:foo is notNone
)never compare something with
True
orFalse
(for example neverdofoo == False
, donot foo
instead)
Negated containment checks:
use
foo not in bar
instead ofnot foo in bar
Instance checks:
isinstance(a, C)
instead oftype(A) is C
, but try to avoidinstance checks in general. Check for features.
Naming Conventions
Class names:
CamelCase
, with acronyms kept uppercase (HTTPWriter
and notHttpWriter
)Variable names:
lowercase_with_underscores
Method and function names:
lowercase_with_underscores
Constants:
UPPERCASE_WITH_UNDERSCORES
precompiled regular expressions:
name_re
Protected members are prefixed with a single underscore. Doubleunderscores are reserved for mixin classes.
On classes with keywords, trailing underscores are appended. Clashes withbuiltins are allowed and must not be resolved by appending anunderline to the variable name. If the function needs to access ashadowed builtin, rebind the builtin to a different name instead.
- Function and method arguments:
class methods:
cls
as first parameterinstance methods:
self
as first parameterlambdas for properties might have the first parameter replacedwith
x
like indisplay_name = property(lambda x: x.real_nameor x.username)
Docstrings
- Docstring conventions:
- All docstrings are formatted with reStructuredText as understood bySphinx. Depending on the number of lines in the docstring, they arelaid out differently. If it’s just one line, the closing triplequote is on the same line as the opening, otherwise the text is onthe same line as the opening quote and the triple quote that closesthe string on its own line:
- def foo():
- """This is a simple docstring"""
- def bar():
- """This is a longer docstring with so much information in there
- that it spans three lines. In this case the closing triple quote
- is on its own line.
- """
- Module header:
- The module header consists of a utf-8 encoding declaration (if nonASCII letters are used, but it is recommended all the time) and astandard docstring:
- # -*- coding: utf-8 -*-
- """
- package.module
- ~~~~~~~~~~~~~~
- A brief description goes here.
- :copyright: (c) YEAR by AUTHOR.
- :license: LICENSE_NAME, see LICENSE_FILE for more details.
- """
Please keep in mind that proper copyrights and license files are arequirement for approved Flask extensions.
Comments
Rules for comments are similar to docstrings. Both are formatted withreStructuredText. If a comment is used to document an attribute, put acolon after the opening pound sign (#
):
- class User(object):
- #: the name of the user as unicode string
- name = Column(String)
- #: the sha1 hash of the password + inline salt
- pw_hash = Column(String)