Coding Standards

I trust you that you will obey

1. Seperate words with _

2. Widget variables Widget names are all small and the last word should be the widget type:

  • jid_comboboxentry
  • chat_button
  • new_message_menuitem

3. Callbacks The default style is used, so we have:

  • on_chat_button_clicked
  • on_new_message_menuitem_activated

In the callbacks we use 'key_press' and 'button_press' events and not the release ones. The arguments in the the callbacks (and in the .connect()s) have this sequence of 'abstract to specific'. so we write:

# notice we start from ACCOUNT ending up in contact.
foo.connect('clicked', on_foo_clicked, account, group, contact)

4. Classes The first letter must be Capital and if class has to do with widget, the last word should be the widget type it creates/handles.

5. UI See:  http://developer.gnome.org/projects/gup/hig/2.0/design-window.html

NOTE: the point is for the widgets to look nice in an objective way and aligned well. Most windows/dialog that have many children have border width 12 (else 6), and most gtk boxes have spacing 6. In tables horizontal spacing is set to 12 and vertical spacing to 6. In general the widgets you draw should look nice, so have a look at the glade file to see already implemented windows/dialogs. We write 'enter password:' in labels or where it's needed. Notice that we use ':' and we don't have a space before

We use .show()/ .hide() for windows/dialogs most of the times. See DevShowDestroy for more We use mostly dialogs cause they're more handy (ESC works out of the box etc..) and they look nicer

6. Tabulations We use tabs and not spaces. Tab width is 3.

7. Write clean, readable, optimized pythonic code We love python and we try to write the pythonic way, therefore:

  • read  Python Performance Tips and  PythonSpeed
  • Use True/False? instead of 1 and 0;
  • Use single quotes (' ') not double quotes (" ");
  • Keep the 80 chars right margin; use '\ ' when necessary, (f.e. long ifs with in/and/or);
  • Use value = model[iter][0] not value = model.get_value(iter, 0).
  • use xrange() instead of range() and use tupples () instead of lists [] for looping in and/or checking 'if foo in'. Both assure optimized code
  • write isinstance(a, dict) instead of type(a) == type({}) as it is faster
  • readability comes first and only after readability comes code optimization

8. Spacing

Put space around binary operators such as = == != + - / * etc. Unary operators get no space. Also no space around . attribute/method addressing operator or around ( and ). No space before and one space after commas. No surprises here.
Exception: When defining or invoking named function parameters, use no space around =. For example:

def myblahfunc(myparm=None):

and:

a = myblahfunc(myparm='hello')

9. Comments

Comments for developers MUST be in the form

# comment

comments for translators MUST be in the form:

#comment

Documentation style has to follow  PEP 287 and is using  reST markup

10. Write good strings

Write good english strings (easy to understand, without typos, correct syntax). Your strings should obey to  Layout GNOME Hig Rules and to 'primary text has puncation only if ? so not . in primary text. In secondary always put .' 'As HIG says alert dialogs don't have title. etcc.' READ THE HIG.

11. Using %s %d and not + for strings that the user sees or has chances to see in the future and being translation friendly

People talk hundreds of languages, keep that in mind and follow with this example:

strvar = 'you'
no_of_msgs = len(messages) # can be 0, 1, 2, 3 ...
s = i18n.ngettext('You have %d message', 'You have %d messages', no_of_msgs, no_of_msgs, no_of_msgs) # use ngettext() and use %d not %s for intvars
#%s is always 'you' here        <-- Comment for translator
s = _('I love %s') % strvar # how to use simple gettext() and pass correctly the string variable

s = _('%(nick)s has been kicked by %(who)s: %(reason)s') % { # this does NOT force usage of passive voice to translator's lang
                                                'nick': nick,
                                                'who': actor,
                                                'reason': reason }

if client == '':
        client = Q_('?Client:Unknown') # 'Unknown' string is prefixed with ?Client: so gettext treats it differently
if os == '':
        os = Q_('?OS:Unknown') # and does not merge with this unknown which is different gender

#eg. OS can be feminine and Client can be masculine. and Unknown adjective can differ between feminine and masculine

12. Use unicode strings wherever possible

We use unicode strings everywhere, but there's a couple of places to make sure you're actually using them aswell:

  • Whenever you take input or any string from GTK, you get a utf8 string. Decode it like this:

some_entry.get_text().decode('utf-8')

  • Whenever you read from a file, you get a regular string. You can use the .decode string method aswell, but there's no way of telling what encoding the file is using! UTF-8 is generally a good default though.
  • Whenever you write to a file, encode the unicode string back to a utf8 string, or you'll get exceptions:

some_file.write(my_string.encode('utf-8'))

  • Avoid str(), always use unicode() when possible! As long as whatever you're trying to convert to a string supports str(), it'll work with unicode() aswell, so just use that.

13. Alignment when breaking to avoid more than 80chars in a line

We write:

if foooooooooooooooooooooooooooooooooooooooooooo and\
bar:
	print 'yes indeed'

when we call functions/methods we do:

boo = do_this_and_that(one, two, three, four,
	five, six)

when we define functions/methods we do:

def foo(abc, doremi,
lalallala):
	print abc

generally next line after : has to be visually easy to find (indented)

14. Vim modelines

Here are some settings for your .vimrc that will help you follow the gajim coding standards. In this example, all the gajim source is found in a directory that matches the pattern: "/home/travis/devel/gajim-*/*" Modify this path to match your development environment.

" Gajim development settings
autocmd BufNewFile,BufRead /home/travis/devel/gajim-*/* set noexpandtab
autocmd BufNewFile,BufRead /home/travis/devel/gajim-*/* set shiftwidth=3

That's mainly it. Now contact us to join efforts ;-)