Programming guidelines

From Gramps
Revision as of 15:31, 18 September 2007 by Zfoldvari (Talk | contribs)

Jump to: navigation, search


As more and more people start editing the code, we need to establish a few guidelines to make sure the code remains maintainable.

  • Write PEP 8 compatible code. This is important to have a consistent, readable codebase.
  • Do not use tabs. Use whitespace. If you use an editor with tabs, go into the preferences, and change the tab behavior to a number of spaces. In GRAMPS we use 4 spaces for indentation.
  • New modules should follow the GRAMPS convention of module structuring:
  1. GRAMPS header (programm name, copyright owner, license);
  2. SVN $Id$;
  3. Module docstring;
  4. Author and revision (using SVN $Revision$);
  5. Imports in the following order, separated with proper headers: Python modules, Logging, Gnome/Gtk modules, GRAMPS modules;
  6. Constants with header;
  7. Global variables, module functions, classes, etc.
  #
  # Gramps - a GTK+/GNOME based genealogy program
  #
  # Copyright (C) 2000-2007  <Copyright Owner>
  #
  # This program is free software; you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation; either version 2 of the License, or
  # (at your option) any later version.
  #
  # 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  #

  # $Id$

  """Module docstring.
  """

  __author__   = "Your Name"
  __revision__ = "$Revision$"

  #------------------------------------------------------------------------
  #
  # Python modules
  #
  #------------------------------------------------------------------------
  import os

  #------------------------------------------------------------------------
  #
  # Set up logging
  #
  #------------------------------------------------------------------------
  import logging
  log = logging.getLogger(".NameOfYourModule")

  #-------------------------------------------------------------------------
  #
  # Gnome/GTK modules
  #
  #-------------------------------------------------------------------------
  import gtk

  #------------------------------------------------------------------------
  #
  # Gramps modules
  #
  #------------------------------------------------------------------------
  import RelLib

  #------------------------------------------------------------------------
  #
  # Constants
  #
  #------------------------------------------------------------------------

  # brief description of each constant
  TEST_VALUE = 72.0

  # etc.
  • Class headers. Each class should have a simple header to help mark it in the file. This is not used for documentation - it is used to help find the class when multiple classes exist in the same file.

 #------------------------------------------------------------
 #
 # MyClass
 #
 #------------------------------------------------------------

  • Docstrings. Python provides a docstrings to document classes and functions. If the class is a class used by others (such as the RelLib classes), the docstrings should follow the epydoc format. This allows us to extract API documentation. Classes that are not core reusable classes do not have to follow this format, but should be documented using docstrings.

 class MyClass:
     """
     MyClass is a sample class.
     """
    
     def my_function(self):
         """
         The my_function task serves no purpose whatsoever.
         """
         pass

  • Private class functions (functions that cannot be called outside the class) should be preceded with two underscores. Protected functions (functions that can only be called by the class or derived classes) should be preceded with one underscore.

 def __private_function(self):
     pass
  
 def _protected_function(self):
     pass

  • Run pylint on your code before checking in, and use the output to reasonably clean up the code. Note that you must run pylint in the src directory.