Difference between revisions of "PyOGP Coding Guidelines"

From Second Life Wiki
Jump to navigation Jump to search
Line 1: Line 1:
'''Note:''' New page, and pyogp is not conforming to the guidelines as of writing.
[[User:Enus Linden|Enus Linden]] 18:23, 22 July 2009 (UTC)
== Source Files ==
== Source Files ==



Revision as of 10:23, 22 July 2009

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:

  1. max line length should be 150 (?)
  2. a single blank line separates class methods/functions
  3. a blank line == ^$ (no unnecessary spaces)
  4. multiple statements on a single line is discouraged

Naming Conventions

Summarized from http://www.python.org/dev/peps/pep-0008/.

  1. packages and modules: short lowercase, underscores acceptable if required
  2. classes: CapWords (aka CamelCase)
  3. exceptions: CapWords, with a suffix of "Error"
  4. global variables: let's not have these
  5. functions: lowercase, underscores acceptable if required
  6. function and method arguments: lowercase, underscores acceptable if required
    1. in the case of reserved keyword collision, append a trailing underscore to the argument (id_).
  7. method names and variables: lowercase, underscores acceptable if required
    1. 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:

  1. one space is expected after a comma, semicolon, colon, around binary operators ( = ), arithmetic operators
  2. 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.

bad:

from os.path import join, dirname, realpath
from pyogp.lib.base import agent, region

good:

import os.path
import socket
import urllib2
from pyogp.lib.base.agent import Agent
from pyogp.lib.base.region import Region

pylint

Pylint can analyze a package or module for conformity to standard pythonic coding guidelines. Use this to review your code prior to checkin.

  1. 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:

  1. Use triple double quotes for docstring: """this is a docstring""".
  2. 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.
  3. Use one line docstrings when possible.
  4. When using a multiline docstring, the first line should be the descriptive, followed by a blank line, followed by details in subsequent lines.

Unit Tests

Unit test coverage should come to be expected for each checkin.