The Translate styleguide is the styleguide for all Translate projects, including Translate Toolkit, Pootle, Virtaal and others. Patches are required to follow these guidelines.
This Styleguide follows PEP 8 with some clarifications. It is based almost verbatim on the Flask Styleguide.
To continue a statement you can use backslashes (preceeded by a space) in which case you should align the next line with the last dot or equal sign, or indent four spaces:
MyModel.query.filter(MyModel.scalar > 120) \
.order_by(MyModel.name.desc()) \
.limit(10)
my_long_assignment = MyModel.query.filter(MyModel.scalar > 120) \
.order_by(MyModel.name.desc()) \
.limit(10)
this_is_a_very_long(function_call, 'with many parameters') \
.that_returns_an_object_with_an_attribute
If you break in a statement with parentheses or braces, align to the braces:
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 the opening brace:
items = [
'this is the first', 'set of items', 'with more items',
'to come in this line', 'like this'
]
Top level functions and classes are separated by two lines, everything else by one. Do not use too many blank lines to separate logical segments 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'
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']
While PEP 8 calls for spaces around operators a = b + c this results in flags when you use a[b+1:c-1] but would allow the rather unreadable a[b + 1:c - 1] to pass. PEP 8 is rather quiet on slice notation.
Good:
a[1:2]
a[start:end]
a[(start - 1):(end + var + 2)] # Brackets help group things and don't hide the slice
a[-1:(end + 1)]
Bad:
a[start: end] # No spaces around :
a[start-1:end+var+2] # Insanely hard to read, especially when your expressions are more complex
a[start - 1:end + 2] # You lose sight of the fact that it is a slice
a[- 1:end] # -1 is unary, no space
Note
String slice formating is still under discussion.
Good:
if length >= (upper + 2)
if (length >= 25 and
string != "Something" and
not careful):
do_something()
Bad:
if length >= upper + 2:
if (length...
and string !=...
Note
This has not been implemented or discussed. The Translate code is not at all consistent with these conventions.
Protected members are prefixed with a single underscore. Double underscores are reserved for mixin classes.
On classes with keywords, trailing underscores are appended. Clashes with builtins are allowed and must not be resolved by appending an underline to the variable name. If the function needs to access a shadowed builtin, rebind the builtin to a different name instead.
We use Sphinx to generate our API and user documentation. Read the reStructuredText primer and Sphinx documentation as needed.
We introduce a number of special roles for documentation:
All docstrings are formatted with reStructuredText as understood by Sphinx. Depending on the number of lines in the docstring, they are laid out differently. If it’s just one line, the closing triple quote is on the same line as the opening, otherwise the text is on the same line as the opening quote and the triple quote that closes the 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.
"""
Please read PEP 257 (Docstring Conventions) for a general overview, the important parts though are:
def foo(bar):
"""One line description.
Further explanations that might be needed.
:param bar: Parameter descriptions.
"""
def addunit(self, unit):
"""Appends the given unit to the object's list of units.
This method should always be used rather than trying to modify the
list manually.
:type unit: TranslationUnit
:param unit: Any object that inherits from :class:`TranslationUnit`.
"""
self.units.append(unit)
Document parameters using reST field lists as follows:
def foo(bar):
"""Simple docstring
:param bar: Something
:type bar: Some type
:return: Returns something
:rtype: Return type
"""
Note
We still Need to gather the useful ones that we want you to use and how to use then. E.g. how to talk about a paramter in the docstring. How to reference classes in the module. How to reference other modules, etc.
The module header consists of an utf-8 encoding declaration, copyright attribution, license block and a standard docstring:
# -*- coding: utf-8 -*-
#
... LICENSE BLOCK...
"""A brief description"""
Good:
# Good comment with space before and full sentence.
statement # Good comment with two spaces
Bad:
#Bad comment no space before
statement # Bad comment, needs two spaces
Rules for comments are similar to docstrings. Both are formatted with reStructuredText. If a comment is used to document an attribute, put a colon 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)