PyOGP Coding Guidelines

Note: New page, and pyogp is not conforming to the guidelines as of writing.
Enus Linden 18:23, 22 July 2009 (UTC)
== Source Files ==
Begin all Python source code files with this header: 
"""
@file filename
@brief brief description
Contributors: http://svn.secondlife.com/svn/linden/projects/2008/pyogp/CONTRIBUTORS.txt 
$LicenseInfo:firstyear=2008&license=apachev2$
Copyright (c) 2009, Linden Research, Inc.
Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at:
 http://svn.secondlife.com/svn/linden/projects/2008/pyogp/LICENSE.txt
$/LicenseInfo$
"""
== Code Layout ==
Generally based on http://www.python.org/dev/peps/pep-0008/, with specific details called out below.
=== General ===
One line requirements:
# line length should be 80 characters if possible, do not exceed 150 (?)
# a single blank line separates class methods/functions
# a blank line == ^$ (no unnecessary spaces)
# multiple statements on a single line is discouraged
=== Naming Conventions ===
Summarized from http://www.python.org/dev/peps/pep-0008/.
# packages and modules: short lowercase, underscores acceptable if required
# classes: CapWords (aka CamelCase)
# exceptions: CapWords, with a suffix of "Error"
# global variables: let's not have these
# functions: lowercase, underscores acceptable if required
# function and method arguments: lowercase, underscores acceptable if required
## in the case of reserved keyword collision, append a trailing underscore to the argument (id_).
# method names and variables: lowercase, underscores acceptable if required
## one leading underscore of non-public methods and variables
=== Comments ===
Comments should describe why this code is as it is, rather than what it's doing.
Block comments start with a # and are followed by a space.
Inline comments should be sparsely used.
If leaving a item to address in the future, or a question, prepend the comment string with "# ToDo: ". 
=== Whitespace ===
Conform to the pythonic standard when dealing with whitespace:
# one space is expected after a comma, semicolon, colon, around binary operators ( = ), arithmetic operators
# no spaces expected when dealing with keyword arguments or parameter values (def function(arg1, arg2=True))
=== Indentation ===
4 spaces is our standard indentation. Please do not mix in tabs. Really.
emacs
Put this in your ~/.emacs to get the desired behavior (note that this also turns on colored fonts, which you probably wanted anyway):
(defun ll-python-mode-hook()
 (font-lock-mode 1)
 (font-lock-fontify-buffer)
 (set-variable 'indent-tabs-mode nil)
 (set-variable 'py-indent-offset 4)
 (message "ll coding style function executed"))
(add-hook 'python-mode-hook 'll-python-mode-hook)
(insert instructions on using python-mode if it's not with your default emacs install)
To convert tabs to spaces in Emacs:
* Make sure your tab width is 4
** In .emacs (set-variable 'tab-width 4) (optionally inside your ll-python-mode-hook())
** Immediately: M-x set-variable[ret] tab-width[ret] 4[ret]
* Set mark at start of file: M-< ^space 
* Jump to end of file: M->
* Convert tabs to spaces within marked range: M-x untabify
vi
To use spaces instead of tabs in vi put this in ~/.vimrc:
 set tabstop=4
 set shiftwidth=4
 # When reading a file or creating a new file, uses spaces not tabs
 autocmd BufRead,BufNewFile *.py set expandtab
Another option for tabs/spaces:
 # automatically expand tab keypresses into the appropriate number of spaces
 set expandtab
=== Imports ===
* Include only one module per line
* Order your imports alphabetically (this gets a little vague with "from x in y" imports TODO: invent a rule that makes sense)
* Try not to pollute the module's namespace by importing individual functions and classes from other modules.
* Do not use 'import *'
bad:
from os.path import join, dirname, realpath
from pyogp.lib.base import agent, region
from pyogp.lib.base.datatypes import *
good:
import os.path
import socket
import urllib2
from pyogp.lib.base.agent import Agent
from pyogp.lib.base.region import Region
from pyogp.lib.base.datatypes import UUID, Vector3
=== pylint ===
Pylint can analyze a package or module for conformity to standard pythonic coding guidelines. Use this to review your code prior to checkin.
# ToDo: Enus to provide a standard pylint command...
Enus on his Macbook Pro with pylint 0.18.0:
easy_install pylint 
export PYOGPPATH="'/Users/enus/svn/pyogp/trunk/src/pyogp.lib.base/pyogp/'" (replace with path to your dependencies) 
export PYOGPDEPS="'/Users/enus/svn/pyogp/trunk/eggs/'" (replace with path to your dependencies) 
pylint --max-line-length=200 --disable-msg=E1101,C0103,R0913 --init-hook="import sys; sys.path.append($PYOGPPATH); [sys.path.append(os.path.join($PYOGPDEPS, package)) for package in os.listdir($PYOGPDEPS) if not package == '.svn' and not package == 'EXTERNALS.txt']" src/pyogp.lib.base/pyogp/lib/base/region.py 
== docstrings ==
Docstrings are required for all modules, classes, methods and functions,
The standard here is pulled from http://www.python.org/dev/peps/pep-0257/, which is our guideline.
Mechanics:
# Use triple double quotes for docstring: """this is a docstring""".
# The text should describe the functionality of the function or method, and should only describe the parameters and return values when it is not clear.
# Use one line docstrings when possible.
# When using a multiline docstring, the first line should be the description, followed by a blank line, followed by details in subsequent lines.
# Docstrings should observe the line length limit (see above)
== Unit Tests ==
Unit test coverage should come to be expected for each checkin.