wxPython Documentation Project

The purpose of this wiki page is to explain how to add reference documentation to the various wxPython modules, and how to submit those documentation snippets back to the wxPython project. The goal is to eventually be able to replace the wxWidgets C++ docs in the wxPython distributions, and to make the Python specific docs sufficient for the needs of the wxpython programmer.

Epydoc

Epydoc is the tool chosen to put the wxPython docs into a usable format. It is able to extract docstrings from Python modules and add simple formatting, linking to related docs, an index, and etc. Epydoc supports various forms of document markup, including epytextas well as ReStructuredText.

wxPython has standardized on using the ReStructuredText format, because it is a cleaner markup syntax that doesn't get in the way as much when reading the document as plain text, and also because there is much familiarity with it within the Python community. However, if a module author prefers to use epytext or another of epydoc's supported formats, then the format can be specified for that module by defining a module-level string variable __docformat__, containing the name of the module's markup language.

A slightly customized version of epydoc 2.1 is being used for the wxPython documentation. You can get a copy of the source tarball, as well as some installers, at the wxPython tools page.

What to document

Keep in mind that the things specified here are just guidelines. I expect that there will be varying circumstances with different modules, and some things may make more sense in various cases. So feel free to adapt these guidelines to fit those needs.

Modules

Every module should have a module level docstring that describes the contents and purpose of the module. The content of the module docstring will appear in two places in the docs. The first place is on a page that gives a listing and summary of the classes and functions in the module. (Example) The second place is on the page for the package that the module belongs to. (Example) In this case the first sentence of the module's docstring is used as summary text, so care should be taken that the first sentence makes sense and gives enough information about the module to let the reader know if that is what he or she is looking for, but without being too verbose.

Depending on the content of the module, it may make some sense to do things like bits of sample code that demonstrates how to use the classes and functions in the module.

Sometimes there are things in a module that should not be documented. For example, there may be a helper function intended to be used by the other things in the module, but not by code external to the module. There are 2 ways to cause something in a module to be skipped by epydoc, both of these methods follow the example of how Python importing works:

If the module has a global variable named __all__ that is a list of names then only those named items will be documented by epydoc.

Similarly, any item within the module whose name starts with an underscore will not be included in the epydoc generated documentation.

Classes

Epydoc generates class documentation in a similar pattern to how it does for modules. There is a page devoted to the class, and which contains the full docstring for the class, along with a summary of the contents (the methods) of the class. Also, the first sentence of the class' docstring is used for the contents summary listing in the module's page so, again, care should be taken that the first sentence is descriptive of the purpose of the class.

Class docs can be anywhere from a couple paragraphs, to several pages in length, depending on the class and the needs for explaining things to the reader. For UI classes this is a good place to document the styles accepted by the constructor, or the events generated by the widget. In this examplea table is used to display these.

Functions and methods

Every function or method intended for use outside of the module or class should have a docstring. Once again, the first sentence of the docstring for functions and methods will be used in a summary listing. Beyond that the level of detail needed is dependent on the function being documented. In many cases just the first sentence will be enough. In other cases much more detail would be useful. (Example) The function's parameters can be documented (see below for the markup used to do this) but if the purpose of the parameters are real obvious I don't mind leaving them undocumented. For example, a function that sets the position of something doesn't need to have the x and y parameters described in excruciating detail.

Any class methods that are not meant to be used outside of the class do not need to have their docstrings (if any) appear in the reference docs. The easiest way to do this it to name the methods with a leading underscore character. This will signal epydoc to not generate documentation for it, and is also an accepted convention for programmers to know that the method is not part of the public API of the class.

Markup Examples

Please see the ReStructuredText Specificationfor more details, but following are some examples of the basic markup as used in the wxPython documentation.

Paragraphs

Like many plain-text based markup languages, (including that used by this wiki) paragraphs consist of one or more lines indented at the same level, and separated by blank lines.

Basic Markup

Various forms of punctuation are used for inline markup of the text.

Emphasis:

Surround text by *asterisk*

Strong emphasis:

Surround text by **double asterisk**

Inline literal:

Use text surrounded by ``double backticks``

Interdocument link:

To make a link to other classes, functions, etc. you can surround the name with `single backticks` and epydoc will make the link for you if it can find an object with that name.

Bullet Lists:

Use a series of indented paragraphs starting with an asterisk.
Here is a list of items:
* item one
* item two
* item three

Numbered lists:

Here is a list of items:
1 item one
2 item two
3 item three

Literal blocks:

Literal blocks are good for giving examples of code or similar
situations when you want to have a block of monospaced text. You
do it by indenting a block of text, and ending the preceding
paragraph with a double colon. Like this::
The text in this block will be rendered
in a monospaced font.

Various "field" tags are used to control other forms of epydoc output. For example, for specifying parameters and return types, making "see also" links, notes or warning messages, etc. When using the structured text format fields are specified by putting a colon in front of and after the field.

:param p: text

The text describes the parameter p.

:type p: text

Specify the type of parameter p.

:return: text

Describe the return value of a function

:rtype: text

Specify the type of the return value

:see: text

Puts text after a "See also" header

:todo: text

Puts text after a "Todo" tag

For more supported fields and their explanations, see the epydoc page.

Samples

def Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
"""
Bind an event to an event handler.
:param event: One of the EVT_* objects that specifies the
type of event to bind,
:param handler: A callable object to be invoked when the
event is delivered to self. Pass None to
disconnect an event handler.
:param source: Sometimes the event originates from a
different window than self, but you still
want to catch it in self. (For example, a
button event delivered to a frame.) By
passing the source of the event, the event
handling system is able to differentiate
between the same event type from different
controls.
:param id: Used to spcify the event source by ID instead
of instance.
:param id2: Used when it is desirable to bind a handler
to a range of IDs, such as with EVT_MENU_RANGE.
"""

class MultiSplitterWindow(wx.PyPanel):
"""
This class is very similar to `wx.SplitterWindow` except that it
allows for more than two windows and more than one sash. Many of
the same styles, constants, and methods behave the same as in
wx.SplitterWindow. The key differences are seen in the methods
that deal with the child windows managed by the splitter, and also
those that deal with the sash positions. In most cases you will
need to pass an index value to tell the class which window or sash
you are refering to.
The concept of the sash position is also different than in
wx.SplitterWindow. Since the wx.Splitterwindow has only one sash
you can think of it's position as either relative to the whole
splitter window, or as relative to the first window pane managed
by the splitter. Once there is more than one sash then the
distinciton between the two concepts needs to be clairified. I've
chosen to use the second definition, and sash positions are the
distance (either horizontally or vertically) from the origin of
the window just before the sash in the splitter stack.
NOTE: These things are not yet supported:
* Using negative sash positions to indicate a position offset
from the end.
* User controlled unsplitting (with double clicks on the sash
or dragging a sash until the pane size is zero.)
* Sash gravity
"""

class PySimpleApp(wx.App):
"""
A simple application class. You can just create one of these and
then then make your top level windows later, and not have to worry
about OnInit. For example::
app = wx.PySimpleApp()
frame = wx.Frame(None, title='Hello World')
frame.Show()
app.MainLoop()
:see: `wx.App`
"""