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.

A current snapshot of the wxPython reference docs can be found here.

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 epytext as 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.

   1 """
   2 This is the module docstring for B{MyMmodule}.
   3 """
   4 __docformat__ = "epytext"

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:

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 example a 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 Specification for 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.

Fields

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.

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` 
    """

Giving docstrings to SWIG generated code

Submitting docstring updates

wxPython Documentation Project (last edited 2008-03-11 10:50:24 by localhost)