1. Introduction
This document describes coding conventions for the Python code used in Project Kusu. It is heavily adapted from the PEP 8 document. What follows is mostly from the PEP 8 document itself but are re-printed here for emphasis.
Please refer to the original PEP 8 for the general information but where there is conflict between this document and the PEP, this document will take precedence.
2. General Considerations
As described in PEP 8, it is stated by Guido that code is read much more often that it is written. The guidelines provided here are intended to improve the readability of code and make it consistent across the Kusu sub-projects.
When coding, there may be situations where applying the guidelines may result in poor readability and inconsistency. When in doubt, use your best judgement. Look at other examples and decide what looks best. And do not hesitate to ask.
Two good reasons to break a particular rule:- When applying the rule would make the code less readable, even for someone who is used to reading code that follows the rules.
- To be consistent with surrounding code that also breaks it (maybe for historic reasons) -- although this is also an opportunity to clean up someone else's mess (in true XP style).
3. Version Bookkeeping and License information
Since the source for Project Kusu is hosted on a Subversion system, the following crud may be included near the top of your source file before any other docstrings or code:
[code]# $Id$
#
# Copyright (C) <year> <copyright owner>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#[/code]
Note that the appropriate settings for your Subversion config file should be correct for the above to work properly.
4. Code Layout
Indentation: Use 4 spaces per indentation. If you are using VIM, the following options can be used in your .vimrc file (or download this .vimrc):
Code:
set tabstop=4
set shiftwidth=4
set expandtab
The above will enable VIM to set tabs to 4 spaces and expand the tabs to spaces (as opposed to merely using tab character).
Imports: Imports should usually be on separate lines, e.g:
Code:
import os
import sys
And not like the following:
It is okay to do this however:
Code:
from subprocess import Popen, PIPE
Comments: Comments that contradict the code are worse than no comments. Always make a priority of keeping the comments up-to-date when the code changes!
Comments should be complete sentence. If a comment is a phrase or sentence, its first word should be capitalized, unless it is an identifier that being with a lowercase letter (never alter the case of identifiers!).
If a comment is short, the period at the end can be omitted. Block comments generally consist of one or more paragraphs built out of complete sentences and each sentence should end in a period.
Block comments generally apply to some (or all) code that follows them and are indented to the same level as that code. Each line of a block comment starts with # and a single space (unless it is indented text inside the comment).
Paragraphs inside a block comment are separated by a line containing a single #. Doctrings: Write docstrings for all public modules, functions, classes and methods. Docstrings are not necessary for non-public methods but you should have a comment that describes what the method does. This comment should appear after the 'def' line.
5. Naming Conventions
Modules Names: Modules are mapped to filenames and should have short, all-lowercase names. Underscores can be used in the module name if it improves readability.
Class Names: Class names use the CapitalizedWords convention. Classes for internal use have a leading underscore in addition.
Exception Names: Because exceptions should be classes, the class naming convention applies here. The suffix 'Error' should be used on your exception names if the exception is an error exception.
Function and Method Names: Function and method names should be mixedCase (differs from the CapitalizedWords by the initial lowercase character).
Function and Method arguments: The convention for function names should apply here. Always use 'self' for the first argument to instance and class methods. If a function's argument clashes with a reserved keyword, it is recommended to a synonym else append a single trailing underscore rather than using an abbreviation or a spelling corruption.
Other considerations: To denote non-public methods and instance variables, a single leading underscore should be used.
6. Programming Recommendations
Comparisons to singletons like None should always be done with 'is' or 'is not'. Do not use equality operators. Also, beware of writing 'if x' when you really mean 'if x is not None'! Always go for readability and clarity above all.
When catching exceptions, mention specific exceptions whenever possible instad of using a bare except: clause. For example, use:
Code:
try:
import foomodule
except ImportError:
import barmodule
Use string methods instead of the string module. Use '.startswith()' and 'endswith()' instead of string slicing for prefixes or suffixes. They are more clean and less error prone.
Object type comparisons should always use isinstance() instead of comparing types directly.
When dealing with strings, keep in mind they might be unicode strings too.
For sequences (like strings, lists, tuples), use the fact that empty sequences are false. For example:
Code:
if not seq:
if seq:
And _not_ like the following:
Code:
if len(seq)
if not len(seq)
Do not compare boolean values to True or False using ==. For example, the following is recommended: if greeting:
And _not_ like the the following:
Code:
if greeting == True:
Or even the following is not recommended:
Code:
if greeting is True:
Know when to use the range and xrange functions. range returns a list, while xrange returns an iterator. Typically you would want to use xrange when looping:
Code:
for i in xrange(50000):
doSomething(i)
Please refer any comments or questions regarding this document to Najib Ninaba at najib at osgdc dot org.