#summary Style guide for Python code contributed to Melange
#labels Contents-Draft,Phase-Guidelines

The [SoCOverview SoC framework], and
[MelangeIntro Melange web applications] built upon it, are implemented in
Python (since that is the only programming language currently supported by
[http://code.google.com/appengine/ Google App Engine]).  This style guide is a
list of dos and don'ts for Python contributions to the Melange project.

The rules below are not guidelines or recommendations, but strict rules. You
may not disregard the rules we list below except as approved on a need-to-use
basis. But note also the advice on [PythonStyleGuide#Conclusion consistency]
at the end of the guide.

If you have questions about these guidelines, you can send mail to the
[MailingListsGuidelines#Developer_list developer mailing list].
Please put *Python style:* in the subject line to make it easier to locate
these discussions in the mailing list archives.

Since this style guide is documented in the Melange wiki, it can be changed via
the existing [DocumentationReviews documentation review process].  However,
changes to the style guide should not be made lightly, since
[PythonStyleGuide#Conclusion consistency] is one of the key goals
of this style guide, and old code will not necessarily be updated for new
style guide changes.

= Summary =

== Python Language Rules ==

 # [PythonStyleGuide#pychecker pychecker]: _Recommended_
 # [PythonStyleGuide#Module_and_package_imports Module and package imports]: _Yes, *except for wildcard imports*_
 # [PythonStyleGuide#Packages Packages]: _Yes_
 # [PythonStyleGuide#Exceptions Exceptions]: _Yes_
 # [PythonStyleGuide#Global_variables Global variables]: _Use sparingly_
 # [PythonStyleGuide#Nested_Local_Inner_Classes_and_Functions Nested/Local/Inner Classes and Functions]: _Yes_
 # [PythonStyleGuide#List_Comprehensions List Comprehensions]: _Yes, *if simple*_
 # [PythonStyleGuide#Default_Iterators_and_Operators Default Iterators and Operators]: _Yes_
 # [PythonStyleGuide#Generators Generators]: _Yes_
 # [PythonStyleGuide#Using_apply_filter_map_reduce Using apply, filter, map, reduce]: _Yes, *for one-liners*_
 # [PythonStyleGuide#Lambda_functions Lambda functions]: _Yes, *for one-liners*_
 # [PythonStyleGuide#Default_Argument_Values Default Argument Values]: _Yes_
 # [PythonStyleGuide#Properties Properties]: _Yes_
 # [PythonStyleGuide#True_False_evaluations True/False evaluations]: _Yes_
 # [PythonStyleGuide#Boolean_built_in_type Boolean built-in type]: _Yes_
 # [PythonStyleGuide#String_Methods String Methods]: _Yes_
 # [PythonStyleGuide#Lexical_Scoping Lexical Scoping]: _Yes_
 # [PythonStyleGuide#Function_and_Method_Decorators Function and Method Decorators]: _Yes, *in moderation*_
 # [PythonStyleGuide#Threading Threading]: _*do not use* (not available in [http://code.google.com/appengine/kb/general.html#libraries Google App Engine])_
 # [PythonStyleGuide#Power_features Power features]: _*No*_

== Python Style Rules ==

Programs are much easier to maintain when all files have a consistent
style. Here is the canonical Melange Python style.

 # [PythonStyleGuide#Semicolons Semicolons]: _*Avoid*_
 # [PythonStyleGuide#Line_length Line length]: _*80* columns maximum_
 # [PythonStyleGuide#Parentheses Parentheses]: _*Use sparingly*_
 # [PythonStyleGuide#Indentation Indentation]: _*2* spaces (*no tabs*)_
 # [PythonStyleGuide#Blank_lines Blank lines]: _*2* for functions and classes, *1* for methods_
 # [PythonStyleGuide#Whitespace Whitespace]: _Sparingly within a line_
 # [PythonStyleGuide#Python_Interpreter Python Interpreter]: _the one supported by_ [http://code.google.com/appengine/docs/python/purepython.html Google App Engine]: `#!/usr/bin/python2.5`
 # [PythonStyleGuide#Comments Comments]: _`__doc__` strings, block, inline_
   * [PythonStyleGuide#Doc_strings `__doc__` Strings]
   * [PythonStyleGuide#Modules Modules]
   * [PythonStyleGuide#Functions_and_Methods Functions and Methods]
   * [PythonStyleGuide#Classes Classes]
   * [PythonStyleGuide#Block_and_Inline_Comments Block and Inline Comments]
 # [PythonStyleGuide#Classes Classes]: _Inherit from object_
 # [PythonStyleGuide#Strings Strings]: _Avoid repeated use of `+` and `+=`_
 # [PythonStyleGuide#TODO_style TODO style]: `TODO(username):` _use a consistent style_
 # [PythonStyleGuide#Imports_grouping_and_order Imports grouping and order]: _One per line, grouped and ordered by packages_
 # [PythonStyleGuide#Statements Statements]: _One per line, avoid [PythonStyleGuide#Semicolons Semicolons]_
 # [PythonStyleGuide#Access_control Access control]: _`foo` if lightweight, `GetFoo()` and `SetFoo()` otherwise_
 # [PythonStyleGuide#Naming Naming]: _`foo_bar.py` not `foo-bar.py`_
 # [PythonStyleGuide#Main Main]: `if __name__ == '__main__':`
 # [PythonStyleGuide#Conclusion Conclusion]: _Look at what's around you!_

= Python Language Rules =

== pychecker ==

*What it is:* `pychecker` is a tool for finding bugs in Python source code.
It finds problems that are typically caught by a compiler for less dynamic
languages like C and C++. It is similar to lint. Because of the dynamic
nature of Python, some warnings may be incorrect; however, spurious
warnings should be fairly infrequent.

*Pros:* Catches easy-to-miss errors like typos, use-vars-before-assignment, etc.

*Cons:* `pychecker` isn't perfect. To take advantage of it, we'll need to
sometimes: a) Write around it b) Suppress its warnings c) Improve it or
d) Ignore it.

*Decision:* Make sure you run `pychecker` on your code.

To suppress warnings, you can set a module-level variable named
`__pychecker__` to suppress appropriate warnings. For example:

{{{
__pychecker__ = 'no-callinit no-classattr'
}}}

Suppressing in this way has the advantage that we can easily search for
suppressions and revisit them.

You can get a list of `pychecker` warnings by doing `pychecker --help`.

Unused argument warnings can be suppressed by using `_` as the identifier
for the unused argument or prefixing the argument name with `unused_`.
In situations where changing the argument name is infeasible, you can
mention them at the begining of the function. For example:

{{{
def Foo(a, unused_b, unused_c, d=None, e=None):
  d, e = (d, e)  # silence pychecker
  return a
}}} 

Ideally, `pychecker` would be extended to ensure that such
'unused declarations' were true.

You can find more information on the
[http://www.google.com/url?sa=D&q=http://pychecker.sourceforge.net  PyChecker homepage].

== Module and package imports ==

*What it is:* Reusability mechanism for sharing code from one module to another.

*Pros:* Simplest way of sharing things and the most commonly used one, too.

*Cons:* `from foo import *` or `from foo import Bar` is very nasty and can
lead to serious maintenance issues because it makes it hard to find module
dependencies.

*Decision:* Use `import x` for importing packages and modules. Use
`from x import y` only when `x` is a package and `y` is a module. This
allows the importer to refer to the module without specifying the full
package prefix. For example the module `sound.effects.echo` may be
imported as follows:

{{{
from sound.effects import echo
...
echo.echofilter(input, output, delay=0.7, atten=4)
}}} 

Even if the module is in the same package, do not directly import the module
without the full package name. This might cause the package to be imported
twice and have unintended side effects.

== Packages ==

*What it is:* Each module is imported and referred to using the full
pathname location of that module.

*Pros:* Avoids conflicts in module names. Makes it easier to find modules.

*Cons:* Makes it harder to deploy code because you have to replicate the
package hierarchy.

*Decision:* All new code should refer to modules based on their package
name. Do not modify `sys.path` or `PYTHONPATH` to import modules from
other directories. (There may be some situations in which path modification
is still needed, but this should be avoided if at all possible.)

Imports should be as follows:

{{{
# Reference in code with complete name.
import soc.logging

# Reference in code with just module name.
from soc import logging
}}}

Some module names might be the same as common local variable names.  In
those cases, to avoid confusion, it sometimes makes sense to only import
the containing package, and then explicitly import the module.  The
result looks something like this:

{{{
from soc import models
import soc.models.user

...
  user = models.user.User()
}}}

It probably best to avoid module names that lead to this confusion in the
first place, but sometimes using the obvious module name (such as in the
`soc.models` package example above) _will_ result in the need for
workarounds like the one above.

== Exceptions ==

*What they are:* Exceptions are a means of breaking out of the normal flow
of control of a code block to handle errors or other exceptional conditions.

*Pros:* The control flow of normal operation code is not cluttered by
error-handling code. It also allows the control flow to skip multiple
frames when a certain condition occurs, e.g., returning from N nested
functions in one step instead of having to carry-through error codes.

*Cons:* May cause the control flow to be confusing. Easy to miss error
cases when making library calls.

*Decision:* Exceptions are very Pythonic so we allow them, too, but only
as long as certain conditions are met:

 * Raise exceptions like this: `raise MyException("Error message")` or `raise MyException`. Do not use the two-argument form (`raise MyException, "Error message"`) or deprecated string-based exceptions (`raise "Error message"`).
 * Modules or packages should define their own domain-specific base exception class, which should inherit from the built-in `Exception` class. The base exception for a module should be called `Error`.

{{{
class Error(Exception):
  """Base exception for all exceptions raised in module Foo."""
  pass
}}}

 * Never use catch-all `except:` statements, or catch `Exception` or `StandardError`, unless you are re-raising the exception or in the outermost block in your thread (and printing an error message). Python is very tolerant in this regard and `except:` will really catch everything including Python syntax errors. It is easy to hide real bugs using `except:`.
 * Minimize the amount of code in a `try/except` block. The larger the body of the `try`, the more likely that an exception will be raised by a line of code that you didn't expect to raise an exception. In those cases, the `try/except` block hides a real error.
 * Use the `finally` clause to execute code whether or not an exception is raised in the `try` block. This is often useful for cleanup, i.e., closing a file. 

== Global variables ==

*What it is:* Variables that are declared at the module level.

*Pros:* Occasionally useful.

*Cons:* Has the potential to change module behavior during the import,
because assignments to module-level variables are done when the module is
imported.

*Decision:* Avoid global variables in favor of class variables. Some
exceptions are:

 * Default options for scripts.
 * Module-level constants. For example: `PI = 3.14159`. Constants should be named using all- caps with underscores; see [PythonStyleGuide#Naming Naming] below.
 * It is sometimes useful for globals to cache values needed or returned by functions.
 * If needed, globals should be made internal to the module and accessed through public module level functions; see [PythonStyleGuide#Naming Naming] below. 

== Nested Local Inner Classes and Functions ==

*What they are:* A class can be defined inside of a function or class. A
function can be defined inside a function. Nested functions have read-only
access to variables defined in enclosing scopes.

*Pros:* Allows definition of utility classes and functions that are only
used inside of a very limited scope. Very ADT-y.

*Cons:* Instances of nested or local classes cannot be pickled.

*Decision:* They are fine.

== List Comprehensions ==

*What they are:* List comprehensions and generator expressions provide a
concise and efficient way to create lists and iterators without resorting
to the use of `map()`, `filter()`, or `lambda`.

*Pros:* Simple list comprehensions can be clearer and simpler than other
list creation techniques. Generator expressions can be very efficient,
since they avoid the creation of a list entirely.

*Cons:* Complicated list comprehensions or generator expressions can be
hard to read.

*Decision:* OK to use for one-liners, or when the `x for y in z` fits on one
line and a conditional on another (but see the example with the very-long
`x` below, which is a three-line case that is acceptable). Use loops
instead when things get more complicated. This is a judgment call.

*No:*

{{{
# too complicated, use nested for loops instead
result = [(x, y) for x in range(10)
                   for y in range(5)
                     if x * y > 10]
}}}

*Yes:*

{{{
# this case is complicated enough *not* to use a list comprehension
result = []
for x in range(10):
  for y in range(5):
    if x * y > 10:
      result.append((x, y))

# a nice, simple one-liner
squares = [x * x for x in range(10)]

# a two-line generator (not list comprehension) case that is also OK
Eat(jelly_bean for jelly_bean in jelly_beans
    if jelly_bean.color == 'black')

# three-line case that is still debatably more readable than the equivalent loop
result = [someReallyLongWayToEatAJellyBean(jelly_bean)
          for jelly_bean in jelly_beans
          if jelly_bean != 'black')
}}}    

== Default Iterators and Operators ==

*What they are:* Container types, like dictionaries and lists, define
default iterators and membership test operators (e.g `in` and `not in`).

*Pros:* The default iterators and operators are simple and efficient. They
express the operation directly, without extra method calls. A function that
uses default operators is generic. It can be used with any type that
supports the operation.

*Cons:* You can't tell the type of objects by reading the method names
(e.g. `has_key()` means a dictionary). This is also an advantage.

*Decision:* Use default iterators and operators for types that support
them, like lists, dictionaries, and files. The built-in types define
iterator methods, too. Prefer these methods to methods that return
lists, except that you should not mutate a container while iterating
over it.

*Yes:*

{{{
for key in adict: ...

if key not in adict: ...

if obj in alist: ...

for line in afile: ...

for k, v in dict.iteritems(): ...
}}}

*No:*

{{{
for key in adict.keys(): ...

if not adict.has_key(key): ...

for line in afile.readlines(): ...
}}}

== Generators ==

*What they are:* A generator function returns an iterator that yields a
value each time it executes a `yield` statement. After it yields a value,
the runtime state of the generator function is suspended until the next
value is needed.

*Pros:* Simpler code, because the state of local variables and control
flow are preserved for each call. A generator uses less memory than a
function that creates an entire list of values at once.

*Cons:* None.

*Decision:* Fine. Use `"Yields:"` rather than `"Returns:"` in the
`__doc__` string for generator functions.

== Using apply filter map reduce ==

*What they are*: Built-in functions useful for manipulating lists.
Commonly used in conjunction with `lambda` functions.

*Pros:* Code is compact.

*Cons:* Higher-order functional programming tends to be harder to understand.

*Decision:* Use list comprehensions when possible and limit use of these
built-in functions to simple code and one-liners. In general, if such code
gets anywhere longer than 60-80 characters or if it uses multi-level function
calls (e.g., `map(lambda x: x[1], filter(...)))`, that's a signal that you
are better off writing a regular loop instead. Compare:

*map/filter:*

{{{
map(lambda x:x[1], filter(lambda x:x[2] == 5, my_list))
}}}

*list comprehensions:*

{{{
[x[1] for x in my_list if x[2] == 5]
}}}

== Lambda functions ==

*What they are:* Lambdas define anonymous functions in an expression, as
opposed to a statement. They are often used to define callbacks or
operators for higher-order functions like `map()` and `filter()`.

*Pros:* Convenient.

*Cons:* Harder to read and debug than local functions. The lack of names
means stack traces are more difficult to understand. Expressiveness is
limited because the function may only contain an expression.

*Decision:* OK to use them for one-liners. If the code inside the `lambda`
function is any longer than 60-80 characters, it's probably better to define it
as a regular (nested) function.

For common operations like addition, use the functions from the operator
module instead of `lambda` functions. For example, prefer `operator.add`
to `lambda x, y: x + y`. (The built-in `sum()` function would be better
than either alternative.)

== Default Argument Values ==

*What they are:* You can specify values for variables at the end of a
function's parameter list, e.g., `def foo(a, b=0):`. If `foo` is called
with only one argument, `b` is set to `0`. If it is called with two
arguments, `b` has the value of the second argument.

*Pros:* Often you have a function that uses lots of default values,
but _rarely_ you want to override the defaults. Default argument values
allow an easy way to do this, without having to define lots of functions
for the rare exceptions. Also, Python does not support overloaded
methods/functions and default arguments are an easy way of "faking"
the overloading behavior.

*Cons:* Default arguments are evaluated once at module load time. This
may cause problems if the argument is a mutable object such as a list or
a dictionary. If the function modifies the object (e.g., by appending an
item to a list), the default value is modified.

*Decision:* OK to use with the following caveats:

 * Do not use mutable objects as default values in the function or method
definition.

*Yes:*

{{{
def foo(a, b=None):
  if b is None:
    b = []
}}}

*No:*

{{{
def foo(a, b=[]):
  ...
}}}    

Calling code must use named values for the default args. This helps
document the code somewhat and helps prevent and detect interface
breakage when more arguments are added.

{{{
def foo(a, b=1):
  ...
}}}

*Yes:*

{{{
foo(1)
foo(1, b=2)
}}}

*No:*

{{{
foo(1, 2)
}}}  

== Properties ==

*What they are:* A way to wrap method calls for getting and setting an
attribute as a standard attribute access when the computation is lightweight.

*Pros:* Readability is increased by eliminating explicit `get` and `set`
method calls for simple attribute access. Allows calculations to be lazy.
Considered the Pythonic way to maintain the interface of a class. In terms
of performance, allowing properties bypasses needing trivial accessor
methods when a direct variable access is reasonable while allowing future
accessor methods to be possible without breaking the interface.

*Cons:* Properties are specified after the getter and setter methods are
declared, requiring one to notice they are used for properties farther down
in the code (except for read-only properties created with the `@property`
decorator - see below). Must inherit from object. Can hide side-effects
much like operator overloading. Can be confusing for subclasses.

*Decision:* Use properties in code where you are accessing or setting
data where you would normally have used simple, lightweight accessor or
setter methods. Read-only properties should be created with the
`@property` [PythonStyleGuide#Function_and_Method_Decorators decorator].

Inheritance with properties can be non-obvious if the property itself
is not overridden. Thus one must make sure that accessor methods are
called indirectly to ensure methods overridden in subclasses are called
by the property (using the Template Method design pattern).

*Yes:*

{{{
import math

class Square(object):
  """Basic square with writable 'area' property, read-only 'perimeter' property.

  To use:
  >>> sq = Square(3)
  >>> sq.area
  9
  >>> sq.perimeter
  12
  >>> sq.area = 16
  >>> sq.side
  4
  >>> sq.perimeter
  16
  """

  def __init__(self, side):
    self.side = side

  def _getArea(self):
    """Calculation for 'area' property"""
    return self.side ** 2

  def __getArea(self):
    """Indirect accessor for 'area' property"""
    return self._getArea()

  def _setArea(self, area):
    """Setter for 'area' property"""
    self.side = math.sqrt(area)

  def __setArea(self, area):
    """Indirect setter for 'area' property"""
    self._setArea(area)

  area = property(__setArea, __setArea,
                  doc="""Get or set the area of the square""")

  @property
  def perimeter(self):
    return self.side * 4
}}}     

== True False evaluations ==

*What it is:* Python evaluates certain values as "false" when in a boolean
context. A quick "rule of thumb" is that all "empty" values are considered
"false" so `0`, `None`, `[]`,` {}`, `""` all evaluate as "false" in a
boolean context.

*Pros:* Conditions using Python booleans are easier to read and less
error-prone. In most cases, it's also faster.

*Cons:* May look strange to C/C++ developers.

*Decision:* Use the "implicit" false if at all possible, e.g.,
`if foo:` rather than `if foo != []:`. There are a few caveats that you
should keep in mind though:

 * Comparisons to singletons like `None` should always be done with `is` or `is not`. Also, beware of writing `if x:` when you really mean `if x is not None:` -e.g., when testing whether a variable or argument that defaults to `None` was set to some other value. The other value might be a value that's false in a boolean context!
 * For sequences (strings, lists, tuples), use the fact that empty sequences are false, so `if not seq:` or `if seq:` is preferable to `if len(seq):` or `if not len(seq):`.
 * Note that `'0'` (i.e., 0 as string) evaluates to true. 

== Boolean built in type ==

*What it is:* A boolean type has been available in Python since version 2.3.
Two new built-in constants were added: `True` and `False`.

*Pros:* It makes code easier to read and is backward-compatible with the
use of integers as boolean in previous versions.

*Cons:* None.

*Decision:* Use booleans.

== String Methods ==

*What they are:* String objects include methods for functions that used to
be in the `string` module.

*Pros:* No need to import the `string` module; methods work with both
regular byte-strings and unicode-strings.

*Cons:* None.

*Decision:* Use them. The `string` module is deprecated in favor of
string methods.

*No:* `words = string.split(foo, ':')`

*Yes:* `words = foo.split(':')`

== Lexical Scoping ==

*What it is:* A nested Python function can refer to variables defined
in enclosing functions, but can not assign to them. Variable bindings are
resolved using lexical scoping, that is, based on the static program text.
Any assignment to a name in a block will cause Python to treat all
references to that name as a local variable, even if the use precedes
the assignment. If a global declaration occurs, the name is treated as a
global variable.

An example of the use of this feature is:

{{{
def getAdder(summand1):
  """getAdder returns a function that adds numbers to a given number."""
  def anAdder(summand2):
    return summand1 + summand2

  return anAdder
}}}

*Pros:* Often results in clearer, more elegant code. Especially comforting
to experienced Lisp and Scheme (and Haskell and ML and ...) programmers.

*Cons:* None.

*Decision:* Okay to use.

== Function and Method Decorators ==

*What they are:* Decorators for Functions and Methods, added in Python 2.4
(a.k.a "the `@` notation"). The most common decorators are `@classmethod`
and `@staticmethod`, for converting ordinary methods to class or static
methods. However, the decorator syntax allows for user-defined decorators
as well. Specifically, for some function `myDecorator`, this:

{{{
class C(object):
  @myDecorator
  def aMethod(self):
    # method body ...
}}}       

is equivalent to:

{{{
class C(object):
  def aMethod(self):
    # method body ...
    method = myDecorator(method)
}}}

*Pros:* Elegantly specifies some transformation on a method; the
transformation might eliminate some repetitive code, enforce invariants, etc.

*Cons:* Decorators can perform arbitrary operations on a function's
arguments or return values, resulting in surprising implicit behavior.
Additionally, decorators execute at import time. Failures in decorator code
are pretty much impossible to recover from.

*Decision:* Use decorators judiciously when there is a clear advantage.
Decorators should follow the same import and naming guidelines as functions.
Decorator `__doc__` string should clearly state that the function is a
decorator. Write unit tests for decorators.

Avoid external dependencies in the decorator itself (e.g. don't rely on
files, sockets, database connections, etc.), since they might not be
available when the decorator runs (at import time, perhaps from `pychecker`
or other tools). A decorator that is called with valid parameters should
(as much as possible) be guaranteed to succeed in all cases.

Decorators are a special case of "top level code" - see
[PythonStyleGuide#Main Main] for more discussion.

== Threading ==

Threading
[http://code.google.com/appengine/kb/general.html#libraries is not available in Google App Engine],
so do not use it in the SoC framework or Melange web applications.

== Power features ==

*What it is:* Python is an extremely flexible language and gives you
many fancy features such as metaclasses, access to bytecode, on-the-fly
compilation, dynamic inheritance, object reparenting, import hacks,
reflection, modification of system internals, etc.

*Pros:* These are powerful language features. They can make your code
more compact.

*Cons:* It's very tempting to use these "cool" features when they're not
absolutely necessary. It's harder to read, understand, and debug code
that's using unusual features underneath. It doesn't seem that way at
first (to the original author), but when revisiting the code, it tends
to be more difficult than code that is longer but is straightforward.

*Decision:* Avoid these features in Melange code.  Discuss exceptions on the
[MailingListsGuidelines#Developer_list developer mailing list].

= Python Style Rules =

== Semicolons ==

Do not terminate your lines with semi-colons and do not use semi-colons
to put two commands on the same line.

== Line length ==

Maximum line length is 80 characters.

*Exception:* lines importing modules may end up longer than 80 characters.

Make use of Python's implicit line joining inside parentheses, brackets
and braces. If necessary, you can add an extra pair of parentheses around
an expression.

*Yes:*

{{{
fooBar(self, width, height, color='black', design=None, x='foo',
       emphasis=None, highlight=0)


if ((width == 0) and (height == 0)
    and (color == 'red') and (emphasis == 'strong')):
}}}    

When a literal string won't fit on a single line, use parentheses for
implicit line joining.

{{{
x = ('This will build a very long long '
     'long long long long long long string')
}}}    

Make note of the indentation of the elements in the line continuation
examples above; see the
[PythonStyleGuide#Indentation indentation section] for explanation.

== Parentheses ==

Use parentheses sparingly. Do not use them:

 * in `return` statements
 * in conditional statements unless using parentheses for implied line continuation (see above)
 * around tuples, unless they are necessary syntactically or for clarity

It is, however, fine to use parentheses:

 * for implied line continuation
 * around sub-expressions in a larger expression (including the sub-expressions that are part of a conditional statemenet)

In fact, parentheses around sub-expressions is preferred to relying solely
on operator precedence.

*Yes:*

{{{
if foo:

while x:

if x and y:

if not x:

if (x < 3) and (not y):

return foo

for x, y in dict.items():

x, (y, z) = funcThatReturnsNestedTuples()
}}}

*No:*

{{{
if (x):

while (x):

if not(x):

if ((x < 3) and (not y)):

return (foo)

for (x, y) in dict.items():

(x, (y, z)) = funcThatReturnsNestedTuples()
}}}

== Indentation ==

Indent your code blocks with 2 spaces. Never use tabs or mix tabs and
spaces. In cases of implied line continuation, you should align wrapped
elements either vertically, as per the examples in the line length
section; or using a hanging indent of *4* spaces (not 2, so as not to be
confused with an immediately-following nested block), in which case there
should be no argument on the first line.

*Yes:*

{{{
# Aligned with opening delimiter 
foo = longFunctionName(var_one, var_two,
                       var_three, var_four)

# 4-space hanging indent; nothing on first line
foo = longFunctionName(
    var_one, var_two, var_three,
    var_four)
}}}

*No:*

{{{
# Stuff on first line forbidden
foo = longFunctionName(var_one, var_two,
    var_three, var_four)

# 2-space hanging indent forbidden
foo = longFunctionName(
  var_one, var_two, var_three,
  var_four)
}}}    

== Blank lines ==

Two blank lines between top-level definitions, be they function or class
definitions. One blank line between method definitions and between the
class line and the first method. One blank line between
[PythonStyleGuide#Doc_strings `__doc__` strings] and the code that follows
them. Use single blank lines as you judge appropriate within functions or
methods.

== Whitespace ==

No whitespace inside parentheses, brackets or braces.

*Yes:* `spam(ham[1], {eggs: 2}, [])`

*No:* `spam( ham[ 1 ], { eggs: 2 }, [ ] )`

No whitespace before a comma, semicolon, or colon. _Do_ use whitespace
after a comma, semicolon, or colon except at the end of the line.

*Yes:*

{{{
if x == 4:

print x, y

x, y = y, x
}}}

*No:*

{{{
if x == 4 :

print x , y

x , y = y , x
}}}

No whitespace before the open paren/bracket that starts an argument
list, indexing or slicing.

*Yes:* `spam(1)`

*No:* `spam (1)`

*Yes:* `dict['key'] = list[index]`

*No:*  `dict ['key'] = list [index]`

Surround binary operators with a single space on either side for
assignment (`=`), comparisons (`==`, `<`, `>`, `!=`, `<>`, `<=`, `>=`,
`in`, `not in`, `is`, `is not`), and booleans (`and`, `or`, `not`). Use
your better judgment for the insertion of spaces around arithmetic
operators but always be consistent about whitespace on either side of
a binary operator.

*Yes:* `x == 1`

*No:*  `x<1`

Don't use spaces around the '`=`' sign when used to indicate a keyword
argument or a default parameter value.

*Yes:* `def Complex(real, imag=0.0): return Magic(r=real, i=imag)`

*No:* `def Complex(real, imag = 0.0): return Magic(r = real, i = imag)`

=== Python Interpreter ==

Modules should begin with a "shebang" line specifying the Python
interpreter used to execute the program:

`#!/usr/bin/python2.5`

[http://code.google.com/appengine/docs/python/purepython.html Google App Engine requires Python 2.5].

== Comments ==

=== Doc strings ===

Python has a unique commenting style using `__doc__` strings. A `__doc__`
string is a string that is the first statement in a package, module,
class or function. These strings can be extracted automatically through
the `__doc__()` member of the object and are used by `pydoc`. (Try
running `pydoc` on your module to see how it looks.) Our convention for
`__doc__` strings is to use the three double-quote format for strings.
A `__doc__` string should be organized as a summary line (one physical
line, [PythonStyleGuide#Line_length 80 characters or less]) terminated
by a period, followed by a blank line, followed by the rest of the
`__doc__` string starting at the same cursor position as the first quote
of the first line. There are more formatting guidelines for `__doc__`
strings below.

=== Modules ===

Every file should contain a block comment with a copyright notice and
license statement at the top of the file.

==== Copyright and license notices ====

{{{
#!/usr/bin/python2.5
#
# Copyright [current year] the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
}}}

This should be followed by a `__doc__` string describing the contents
of the module.  Author information is then included after this string.
If an optional email is provided, then the entire author string
added to the `__authors__` list needs to be an
[http://www.ietf.org/rfc/rfc2821.txt RFC 2821 compliant] email address.

==== Module header and authors ====

{{{
"""A one line summary of the module or script, terminated by a period.

Leave one blank line.  The rest of this __doc__ string should contain an
overall description of the module or script.  Optionally, it may also
contain a brief description of exported classes and functions.

  ClassFoo: One line summary.
  functionBar(): One line summary.
"""

__authors__ = [
  # alphabetical order by last name, please
  '"John Smith" <johnsmith@example.com>',
  'Joe Paranoid',  # email address is optional
]
}}}

If a new contributor is not yet present in the
[http://soc.googlecode.com/svn/trunk/AUTHORS AUTHORS file], that contributor
should be added to that file as part of the first commit from that
contributor.

=== Functions and Methods ===

Any function or method which is not both obvious and very short needs
a `__doc__` string. Additionally, any externally accessible function
or method regardless of length or simplicity needs a `__doc__` string.
The `__doc__` string should include what the function does and have
detailed descriptions of the input ("`Args:`") and output
("`Returns:`", "`Raises:`", or "`Yields:`").  The `__doc__` string
should give enough information to write a call to the function without
looking at a single line of the function's code. The `__doc__` string
should specify the expected types where specific types are required,
and it should mention any default argument values.  A "`Raises:`" section
should list all exceptions that can be raised by the function. The
`__doc__` string for generator functions should use "`Yields:`" rather
than "`Returns:`".

The function or method `__doc__` string should not, generally, describe
implementation details unless it's some complicated algorithm. For
tricky code, block/inline comments within the code are more appropriate.

{{{
def fetchRows(table, keys):
  """Fetch rows from a table.

  Args:
    table: An open table.Table instance.
    keys: A sequence of strings representing the key of each table
      row to fetch.

  Returns:
    A dict mapping keys to the corresponding table row data
    fetched. Each row is represented as a tuple of strings. For
    example:

    {'Serak': ('Rigel VII', 'Preparer'),
     'Zim': ('Irk', 'Invader'),
     'Lrrr': ('Omicron Persei 8', 'Emperor')}

    If a key from the keys argument is missing from the dictionary,
    then that row was not found in the table.

  Raises:
    IOError: An error occurred accessing the table.Table object.
  """
  pass
}}}

=== Classes ===

Classes should have a `__doc__` string below the class definition
describing the class. If your class has public attributes they should
be documented here in an `Attributes:` section.

{{{
class SampleClass(object):

  """Summary of class here.

  Longer class information....
  Longer class information....

  Attributes:
    likes_spam: A boolean indicating if we like SPAM or not.
    eggs: An integer count of the eggs we have laid.
  """

  def __init__(self, likes_spam=False):
    """Inits SampleClass with blah.

    Args:
      likes_spam: Initial indication of if the SampleClass
        instance likes SPAM or not (default is False)
    """
    self.likes_spam = likes_spam
    self.eggs = 0

  def publicMethod(self):
    """Perform operation blah."""
    pass
}}}

=== Block and Inline Comments ===

The final place to have comments is in tricky parts of the code. If
you're going to have to explain it at the next code review, you should
comment it now. Complicated operations get a few lines of comments
before the operations commence. Non-obvious ones get comments at the
end of the line.

{{{
# We use a weighted dictionary search to find out where i is in
# the array.  We extrapolate position based on the largest number
# in the array and the array size and then do binary search to
# get the exact number.

if i & (i-1) == 0:        # true iff i is a power of 2
}}}    

These comments should be separated from the code to improve legibility.
Block comments should be preceded by a blank line.  In general,
end-of-line comments should be at least 2 spaces away from the code. These
end-of-line comments _can_ be lined up if there are many in a row (or
in a function), but this is not required.

On the other hand, never describe the code. Assume the person reading
the code knows Python (though not what you're trying to do) better
than you do.

{{{
# BAD COMMENT: Now go through the b array and make sure whenever i occurs
# the next element is i+1
}}}    

== Classes ==

If a class inherits from no other base classes, explicitly inherit from
`object`. This also applies to nested classes.

*No:*

{{{
class SampleClass:
  pass

class OuterClass:
  class InnerClass:
    pass
}}}    

*Yes:*

{{{
class SampleClass(object):
  pass

class OuterClass(object):
  class InnerClass(object):
    pass

class ChildClass(ParentClass):
  """Explicitly inherits from another class already."""
  pass
}}}    

Inheriting from `object` is needed to make properties work properly, and
it will protect our code from one particular flavor of things that might
break once we switch to Python 3000. It also defines special methods that
implement the default semantics of objects including `__new__`,
`__init__`, `__delattr__`, `__getattribute__`, `__setattr__`, `__hash__`,
`__repr__`, and `__str__`.

== Strings ==

Use the `%` operator for formatting strings, even when the parameters
are all strings. Use your best judgement to decide between `+` and `%`
though.

*No:*

{{{
x = '%s%s' % (a, b)  # use + in this case
x = imperative + ', ' + expletive + '!'
x = 'name: ' + name + '; score: ' + str(n)
}}}    

*Yes:*

{{{
x = a + b
x = '%s, %s!' % (imperative, expletive)
x = 'name: %s; score: %d' % (name, n)
}}}    

Avoid using the `+` and `+=` operators to accumulate a string within
a loop. Since strings are immutable, this creates unnecessary temporary
objects and results in quadratic rather than linear running time.
Instead, add each sub-string to a `list` and `''.join()` that list after
the loop terminates.

*No:*

{{{
employee_table = '<table>'
for last_name, first_name in employee_list:
  employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name)
employee_table += '</table>'
}}}    

*Yes:*

{{{
items = ['<table>']
for last_name, first_name in employee_list:
  items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name))
items.append('</table>')
employee_table = ''.join(items)
}}}    

Use `"""` for multi-line strings rather than `'''`. Note, however, that
it is often cleaner to use implicit line joining since multi-line
strings do not flow with the indentation of the rest of the program:

*No:*
{{{
    print """This is pretty ugly.
Don't do this.
"""
}}}

*Yes:*

{{{
    print ("This is much nicer.\n"
           "Do it this way.\n")
}}}    

== TODO style ==

Use `TODO` comments for code that is temporary, a short-term solution,
or good-enough but not perfect.

`TODO`s should include the string `TODO` in all caps, followed by your
`username` in parentheses: `TODO(username)`. A colon is optional. The
main purpose is to have a consistent `TODO` format searchable by `username`.

{{{
# TODO(someuser): Use a "*" here for concatenation operator.
# TODO(anotheruser) change this to use relations.
}}}

If your `TODO` is of the form "At a future date do something" make sure
that you either include a very specific date ("Fix by November 2008")
or a very specific event ("Remove this code after the Foo entities in
the datastore have all added the new fubar property.").

== Imports grouping and order ==

Imports should be on separate lines, e.g.:

*Yes:*

{{{
import sys
import os
}}}

*No:*

{{{
import sys, os
}}}    

Imports are always put at the top of the file, just after any module
comments and `__doc__` strings and before module globals and constants.
Imports should be grouped with the order being most generic to least
generic:

 * standard library imports
 * Google App Engine imports
 * SoC framework imports
 * application specific imports

== Statements ==

Generally only one statement per line. However, you may put the result
of a test on the same line as the test only if the entire statement
fits on one line. In particular, you can never do so with `try/except`
since the `try` and `except` can't both fit on the same line, and you
can only do so with an `if` if there is no `else`.

*Yes:*

{{{
if foo: fuBar(foo)
}}}

*No:*

{{{
if foo: fuBar(foo)
else:   fuBaz(foo)

try:               fuBar(foo)
except ValueError: fuBaz(foo)

try:
  fuBar(foo)
except ValueError: fuBaz(foo)
}}}    

== Access control ==

If an accessor function would be trivial you should use public variables
instead of accessor functions to avoid the extra cost of function calls
in Python. When more functionality is added you can use property to keep
the syntax consistent.

On the other hand, if access is more complex, or the cost of accessing
the variable is significant, you should use function calls (following
the [PythonStyleGuide#Naming Naming guidelines]) such as `getFoo()` and
`setFoo()`. If the past behavior allowed access through a property, do
not bind the new accessor functions to the property. Any code still
attempting to access the variable by the old method should break visibly
so callers are made aware of the change in complexity.

== Naming ==

=== Names to avoid ===

 * single character names, except for counters or iterators
 * dashes (`-`) in any package/module name
 * `__double_leading_and_trailing_underscore__` names (reserved by Python) 

=== Naming convention ===

 * "Internal" means internal to a module or protected or private within a class.
 * Prepending a single underscore (`_`) has some support for protecting module variables and functions (not included with `import * from`).
 * Prepending a double underscore (`__`) to an instance variable or method effectively serves to make the variable or method private to its class (using name mangling).
 * Place related classes and top-level functions together in a module. Unlike Java, there is no need to limit yourself to one class per module. However, make sure the classes and top-level functions in the same module have [http://en.wikipedia.org/wiki/Cohesion_(computer_science) high cohesion].
 * Use `CapWords` for class names, but `lower_with_under.py` for module names.

=== Naming examples ===

|| *Type* || *Public* || *Internal* ||
|| _Packages_ || `lower_with_under` || ||
|| _Modules_ || `lower_with_under` || `_lower_with_under` ||
|| _Classes_ || `CapWords` || `_CapWords` ||
|| _Exceptions_ || `CapWords` || ||
|| _Functions_ || `firstLowerCapWords()` || `_firstLowerCapWords()` ||
|| _Global/Class Constants_ || `CAPS_WITH_UNDER` || `_CAPS_WITH_UNDER` ||
|| _Global/Class Variables_ || `lower_with_under` || `_lower_with_under` ||
|| _Instance Variables_ || `lower_with_under` || `_lower_with_under` _(protected)_ or `__lower_with_under` _(private)_ ||
|| _Method Names_^*^ || `firstLowerCapWords()` || `_firstLowerCapWords()` _(protected)_ or `__firstLowerCapWords()` _(private)_ ||
|| _Function/Method Parameters_ || `lower_with_under` || ||
|| _Local Variables_ || `lower_with_under` || ||

^*^ Consider just using
[PythonStyleGuide#Access_control direct access to public attributes]
in preference to getters and setters, as function calls are expensive
in Python, and `property` can be used later to turn attribute access into a
function call without changing the access syntax.

== Main ==

Every Python source file should be importable. In Python, `pychecker`,
`pydoc`, and unit tests require modules to be importable. Your code
should always check `if __name__ == '__main__':` before executing your
main program so that the main program is not executed when the module
is imported. The capitalization of `main()` is intentionally inconsistent
with the rest of the naming conventions, which would suggest `Main()`.

{{{
if __name__ == '__main__':
  # parse arguments
  main()
}}}

All code at the top level will be executed when the module is imported.
Be careful not to call functions, create objects, or perform other
operations that should not be executed when the file is being `pycheck`ed
or `pydoc`ed.

== Conclusion ==

_BE CONSISTENT._

If you are editing code, take a few minutes to look at the code around
you and determine its style. If spaces are used around the `if` clauses,
you should, too. If the comments have little boxes of stars around them,
make your comments have little boxes of stars around them, too.

The point of having style guidelines is to have a common vocabulary
of coding so people can concentrate on what you are saying rather than
on how you are saying it. We present global style rules here so people
know the vocabulary, but local style is also important. If code you add
to a file looks drastically different from the existing code around it,
it throws readers out of their rhythm when they go to read it. Try to
avoid this.

----
_Copyright 2008 Google Inc._
_This work is licensed under a_
[http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-attribution-2_5.html Creative Commons Attribution 2.5 License].
[http://creativecommons.org/licenses/by/2.5/ http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-2_5-88x31.png]
