Coding Guidelines

Preface:


Coding guidelines are an important set of rules to follow for formating source code documents. A clean easy to read code base makes adding improvements, maintaining, and correcting bugs much easier. Part of the philosophy of this project is to create an interface that is easy to use for most users, this practice also extends to the way the code is written

This document present and layout the coding guidelines used when writing code for Editra. Its purpose is are as follows:

  1. Act as reference for anyone wishing to contribute code to the project.
  2. A reference to those who wish to read and study the code.

It is broken into two sections the first section shows the absolute rules that must be followed, the second section contains a listing of guidelines that are good practice to follow but not necessarily absolute.



General Style Guidelines


Documentation:

Documentation is an absolute. Every Module, Class, and Function definition must have a docstring associated with it. See the example below for how to properly format a docstring. Editra has started to use epydoc format strings for generating documentation as well this is not an enforced rule but it is good to include epydoc tags where applicable.

Example Docstrings
def MyNewFunction():
    """Single line docstring about function"""
 
def MyOtherFunction():
    """A docstring that takes up multiple
    lines should look like this
 
    """
 
def MyThirdFunction(name):
    """This docstring will use some epydoc
    tags, note that they usually start with a '@'.
 
    @param name: param tag is for paramater descriptions
    @return: what does this function return
    @rtype: type of the return value
    """


Commenting

The use of comments that are the same line as what they are commenting should be used sparingly, it is usually better to put it on the line above, see the example below.

Example 1
def MyFunction(): # TODO make xxx do yyy
    """Single line docstring about function"""
 
# TODO make xxx do yyy
def MyFunction():
    """Single line docstring about function"""

There are also some keywords to use in comments that have a particular meaning. These keywords are as follows (TODO, FIXME, HACK, XXX), also note that they are in all CAPITAL letters.

  • TODO comments usually mean that there is something incomplete that needs to be done.
  • FIXME is used to note that somthing needs fixing (duh).
  • HACK can take many meanings but I usually use it to note ugly code or a block of code that most likely has a much more elegant solution available.
  • XXX is used for general notes that are of a higher importance than regular comments or contain a discussion of some sort with tidbits to think about. The use of these keywords is helpful as it allows for a quick grep of the source to see what files have issues and where they are. Some examples are below.
Example 2
# TODO this function needs to handle more error conditions
def MyPartialFunction():
    """Single line docstring about function"""
 
# FIXME This function sometimes returns incorrect data when ...
def MyBrokenFunction():
    """Single line docstring about function"""
 
# HACK I had to do some real ugly namespace 
#      mangling to get x to work in ...
def MyDirtyFunction():
    """Single line docstring about function"""
 
# XXX This function works well and does what is intended
#     but there are some design issues that will limit
#     the portability of it to ...
def MyFunction():
    """Single line docstring about function"""


Line Length:

For readablility lines should try to be under 80 characters wide, in certain cases this is not possible or practical so it is allowable to have lines that are at an absolute maximum of 100 characters wide when it is absolutely necessary.



Indentation:

Indentation must use spaces and not tabs, most editors have the functionality to use "Soft Tabs" so make sure you are using when working on code related to Editra. Editra has the ability to use soft tabs so make sure it is set.

Indentation Must be done in levels of 4 spaces.



Function/Class Naming

Editra uses the wxPython library extensivly throught out most modules. wxPython uses mixed case lettering for Class and Function objects, always begining with an upper case letter followed by lower case letters and another upper case letter for all other words that are part of the name, this style is also sometimes also refered to as camel toe lettering. In order to preserve consistancy Editra's code also follows these conventions, with all class and function names using mixed case naming. The exceptions to this rule are for private and protected members which start with 1 or 2 underscores. See the example below.

Example of a Class/Function Name
class MyTestNameClass(object):
    """Docstring about this class"""
 
def MyTestNameFunction():
    """Single line docstring about function"""
 
def __init__():
    """Initializes the object"""


Variable Naming

Variable names should never be only a single character, but there is an exception to this rule for iterators used in a local scope, but in python its usually better to loop over an iterable object instead of using a counter variable like you would in C. See the below example. Variable names should also be in all lower case and contain only alphnumeric + the _ character.

Example Variable Naming
# Bad Example
i = myfile.read()
 
# Acceptable
i = 0
while i < 10:
    i += 1
 
# Better Choice
for i in xrange(10):
    print i
 
# Other Variable Examples
main_win = wx.GetApp().GetMainWindow()
children = main_win.GetChildren()

Global variables in Editra are named in all upper case letters with underscore's "_" being used to delimit words.

Example Global Variable Naming
HOMEPAGE = "http://editra.org"
MAX_SIZE = 500

Due to wxPython being an event driven system, variables for object Ids are very common to use. All Id variables must start with "ID_" then be followed by the Id name in all uppercase letters with "_" used as a delimiter between words

Example ID Naming
ID_OPEN_PAGE = wx.NewId()
ID_CLOSE = wx.NewId()


Spacing Guidelines

For consistency the following guidelines should be followed for spacing between text

Keyword parameters should have no spaces between the parameter name, the = sign, and the default value.

def FunctionParameters(param1, keyword=0):
    """Single line docstring about function"""
    pass
 
# Also when calling a function
FunctionParameters(100, keyword = 25)   # Bad
FunctionParameters(100, keyword=25)     # Good

Parenthesis should not be followed or proceeded by extra spaces

lst = sorted( someList )   # Bad
lst = sorted(someList)     # Good

All other places besides in a function signature or call operators should be separated by 1 space

a=3+5     # Bad
a = 3 + 5 # Good

Commas should always have 1 space after them and no spaces before them

t = (1,2,3,4,5,6)      # Bad
t = (1, 2, 3, 4, 5, 6) # Good
 
t = (1 , 2 , 3) # Bad
t = (1, 2, 3)   # Good

Other Guidelines to Consider


Delimiting Code Blocks

Blocks of code such as a class definition, listing of imports, related functions, should be delimited by a "#" followed by 77 "-" and a closing "#"

Example:
#-----------------------------------------------------------------------------#


Delimiting Sections in Long Functions

In long functions or loops its often good to delimit sections and label what each area is doing. The delimiter should be formatted as follows "#---- Section Label ----#".



Organizing Functions

Function definitions inside of class should typically be defined in the following order.

  1. Private Members (i.e. __init__(), __str__(), ect...)
  2. Protected Members (i.e _DoSomething(), _DoSomethingElse(), ect...)
  3. Public Functions (i.e AddText(), GetLabel(), ect...)

The functions should also be listed in alphabetical order to make it easier to find them. Exceptions to this rule are for functions that are very closely related or dependant upon each other. In this case it is often better to have them listed in close proximity to each other.



Quality Checking

Install pylint and use it on your code. It is very beneficial for catching bugs that may not otherwise be realized under normal usage. Often times it's suggestions are also useful for improving areas of code that could be better implemented than they are, and of course it helps promote good coding practices. There are a few warnings that can be ignored in its usage with Editra.

Function naming conventions are different so don't worry about them the too many methods warnings are unavoidable with so many of the object inheriting methods from multiple super classes its isn't possible or practical to have all classes with less than 20 member functions.


Links: