Although Python source code usually has excellent readability, it is
still possible to write code that's difficult to read. It's also nice
to if all code in a project follows the same standards and looks
similar. For this reason I've decided to put together this page of
wxPython Coding Guidelines and I'm going to ask that anybody that
contributes library code or patches follows these guidelines as much
as possible. For a general purpose style guide to assist with
programming with wxPython, please see the
Style Guide in the wiki.
These guidelines will be very similar to the general Style Guide for Python Code, but there are a few differences. If something is not explicitly stated here then fall back to the Python style guide. As stated there, consistency to this guide is important, but more important is to know when to be inconsistent. Use your best judgment in all things, but don't do it your own way just because you think my way stinks! ;-)
I release wxPython binaries for both Python 2.6 and Python 2.7. This means that any contributions to wxPython also need to be at least Python 2.6 compatible.
In my opinion liberal use of whitespace can greatly aid the readability of Python code. Here are my recommendations and what I usually try to do:
- Indentation should be done with 4 spaces per level, and never with tabs.
- Top-level classes and functions within a module are separated by at least two blank lines.
- Logical groupings of top-level classes, functions and other top-level code are separated by a blank line, a "comment divider line" (a # followed by about 75 dashes) and a blank line. This may mean that every class and function is divided, or that a number of short functions, import statements, and/or assignments are grouped together.
- Methods within a class are normally separated by two blank lines. An exception to this rule is two or more methods that are only one or two lines in length each.
- If there are methods that are quite long then they can be divided from other methods by a comment divider line that is indented to the same level as the method's 'def' line.
- Within a function or method single empty lines can be used to add clarity, etc. A function or method should never have more than one consecutive empty line within it.
- Whitespace should be used liberally within expressions, but normally only one space at a time. For example, there should be a space before and after all operators and after every comma.
- I normally don't use spaces within parenthesis except after commas, [for example foo( spam, eggs ) instead of foo(spam, eggs)] but I don't object to it too much.
Now that Python is getting a real boolean type and boolean constants, True and False should be used instead of true, false, TRUE, FALSE (although aliases for these do exist for the old namespace.) In the wx module there is some code that tests for the existence of the new constants, and creates them if they don't exist in the version of Python that is being used, and places them in __builtins__.
- Module names: Whenever possible modules should be named with a fairly short name in all lower case. One exception to this is if the module only exports one class then naming the module the same as the class is okay.
- Class names: Classes in the wxPython library should use LeadingUpperMixedCase. If there is already an existing wxWidgets class (or a possibility of one) of the same name then use a Py prefix or choose a different name.
- Method names: Although my personal preference is to use leadingLowerMixedCase for method names that is not the standard for wxWidgets. So since standards are all about consistency wxPython modules should all follow the wxWidgets pattern of using LeadingUpperMixedCase for method names.
- Private stuff: Things in a module that are not meant to be used outside the module should be named with a leading underscore. The same goes for methods or data attributes in classes. If it needs to be super private then use a leading double underscore.
Comments and Docstrings
- Block comments: Comments on a line by themselves should be indented to the same level as the code they are documenting and should normally be full english sentences. Paragraphs are separated by a line with only a # and there should normally be at least one blank line before the start of the comment.
- Inline comments: Comments on the same line as the code they document should be used sparingly. When used they should be separated by several spaces from the statement they are documenting, and if there are others in the vicinity they should be lined up vertically.
- All comments should actually explain the code, not just restate the obvious.
- Comments should be word-wrapped at margin <= to the margin used for the code, (no more than 90 characters or so.)
- Docstrings: Python documentation strings should be normally present for every module, class and method that is meant to be used by the users of a module or package. Those that are for internal use only are not required to have docstrings, although it would be nice if they did. Methods whose purpose and usage is obvious or very simple also do not require a docstring, but again it would be nice if they did.
- Always use triple double quotes for docstrings, even those that are all on one line.
- Docstrings should be compatible with the epydoc tool. For plain text usually nothing needs to be done. If you use the epytext format then be sure to specify a __docformat__ module attribute because reStructuredText is the default for the docs that I do.
Include Demo Module
All modules contributed to wxPython should have a module that can be dropped into the wxPython Demo framework. It is a very simple thing to do, just make a copy of demo/template.py and name it the same as the class to be demoed, (or some other appropriate name.) Then just add code to the TestPanel class that shows your contributed module and you're done. To test, edit Main.py and add the name of the new demo module to the _treeList list.
Don't forget to set the yourDemoModule.overview string! If the overview text starts with "<html>" then it will be shown in the wxHtmlWindow as is. If not then the demo will treat it as plain text and will preprocess it for showing in the wxHtmlWindow.
The overview should be some descriptive text that gives basic information about the classes being demoed, their capabilites, limitations, etc. If appropriate you could also give info about the API of the contributed classes. In some cases you could just set overview to wx.lib.yourContrib.__doc__.
For any updates to wxPython code, including updates to your contribution once I have accepted it and checked it in to the SVN repository, you'll need to use patch files to send updates to me. This way I can easily merge your changes with any that I have made. I will no longer accept full source code replacements for updates.
The easiest way to do a patch against the latest version of the code is to use SVN. You simply need to have a current copy of the workspace checked out to your local system and then use the svn diff command to make the patch file. You may also want to review this page.
You will need to license your contributed code with the wxWidgets License, which is essentially the LGPL with a few extensions that make the code just a little bit more Free. To set the license that your source code uses it is sufficient to just put something like "License: wxWidgets" in the header. By the way, the wxWidgets Library License is now certified by the Open Source Initiative.