Page Contents

This Page

Developer’s corner

This section describes a set of guidelines for the developers of the Enaml.

Note

The content of this section is currently under discussion and the guidelines are only suggestions.

Documentation

Sphinx Configuration

A Sphinx extension enamldoc, found in enamldoc.sphinx_ext lets Sphinx recognize and document Enaml objects.

Sphinx Directives and Roles

.. enaml:enaml_decl::

For Enaml declarations. It will format similarly to a function, but with the base object in the place arguments.

Enaml declared component Foo(Bar)
Enaml declared component enaml.stdlib.fields.RandomField
.. autoenaml_decl:: import.hierarchy.enaml_declaration::

Automatically generate the object description from an Enaml file. Specify the object to document as though you were importing it.

Enaml declared component enaml.stdlib.fields.IntField(derives from <class 'enaml.widgets.field.Field'>)

A field that only accept integer inputs.

.. enaml:enaml_defn::

For Enaml enamldef statements. Arguments display as with functions.

.. autoenaml_defn:: import.hierarchy.enaml_defn::

Automatically generate the object description from an Enaml file. Specify the object to describe as though you were importing it.

.. automodule::::

automodule works for Enaml files as it does for python modules. No special syntax is necessary.

Including the Sphinx extension refactor_doc allows use of formatted docstrings as described below.

enamldoc

Automatically insert docstrings for enaml built-in and derived widgets and components, mirroring and borrowing heavily from the autodoc extension. Enaml widgets and components are Python objects that are imported in the enaml.imports() context

class enamldoc.sphinx_ext.EnamlComponentDocumenter(directive, name, indent=u'')[source]

Bases: sphinx.ext.autodoc.ModuleLevelDocumenter

Enaml component documenter class

The main purpose of this class is to be distinct from Python components and change the domain in the Documenter instance to ‘enaml’

__init__(directive, name, indent=u'')[source]

Need to override the parent __init__ so that we can set self.domain, which is an instance variable.

check_module()[source]

For Enaml objects, the module name returned by self.object.__module__ points to the enaml parsing compiler, rather than the logical module name stored in self.modname. Therefore, this check will verify that the module points to enaml.parsing.enaml_compiler.

Note - after a fix to correct the .__module__ and .__file__ attributes, this method will not be necessary and will need to be deleted.

format_signature()[source]

Thin method for debugging signature formatting.

class enamldoc.sphinx_ext.EnamlDocstringSignatureMixin[source]

Bases: sphinx.ext.autodoc.DocstringSignatureMixin

Mixin for FunctionDocumenter and MethodDocumenter to provide the feature of reading the signature from the docstring.

identical to the autodoc.DocstringSignatureMixin it subclasses and included here as an indicator of a possible future avenue for working with docstring signatures in enaml – possibly to replace refactordoc.

class enamldoc.sphinx_ext.DeclarativeDocumenter(directive, name, indent=u'')[source]

Bases: enamldoc.sphinx_ext.EnamlDocstringSignatureMixin, enamldoc.sphinx_ext.EnamlComponentDocumenter

Specialized Documenter subclass for Enaml declarations.

format_args()[source]

Derivation is shown where normally arguments are shown in a function prototype.

class enamldoc.sphinx_ext.EnamlModuleDocumenter(directive, name, indent=u'')[source]

Bases: sphinx.ext.autodoc.ModuleDocumenter

Subclass of the module documenter for enaml autodocumenting.

The main purpose of the subclass is to set the domain so that member directives are formed properly.

__init__(directive, name, indent=u'')[source]

Need to override the parent __init__ so that we can set self.domain, which is an instance variable.

get_object_members(want_all)[source]

Shim method for debugging

enamldoc.sphinx_ext.add_documenter(cls)[source]

Register a new Documenter.

This autodoc function is overridden here solely for the sake of the proper error message.

enamldoc.sphinx_ext.setup(app)[source]

enamldoc extension setup function.

The setup function is called by Sphinx when loading extensions. app is the instance of the calling app, Sphinx in this case.

enamldoc borrows heavily from autodoc, so additions to setup and configuration are minimal.

class enamldoc.sphinx_ext.testcls[source]

test doc string

__setattr__(x, y)[source]

Attr setter.

Inheritance diagram of enamldoc.sphinx_ext.EnamlComponentDocumenter, enamldoc.sphinx_ext.EnamlDocstringSignatureMixin, enamldoc.sphinx_ext.DeclarativeDocumenter, enamldoc.sphinx_ext.EnamlModuleDocumenter

Sphinx Source

For Sphinx source, please use 4 spaces for indention and a UTF-8 encoding. The line length is preferred to be between 72-74 characters.

Due to the magic under the hood of the traits objects, automatically extracting documentation from the source with the standard autodoc tools is a little tricky. Enaml’s Sphinx source should therefore use the following conventions:

  • When documenting classes with Traits the sphinx directive .. autoattribute:: does not work. To document single attributes use the (undocumented) .. autoattributeinstance:: directive instead.
  • The ..autoclass:: directive works fine as long as specific members are not specified in the :members: context parameter.

Source Code

The coding style follows the PEP 8 guidelines and uses 4 spaces for indention. The maximum line length is 80 characters; however, the documentation is preferred to be between 72-74 characters.

Preamble

The preamble of each file contains copyright notice. The following example can be used as a template

#------------------------------------------------------------------------------
#  Copyright (c) 2012, Enthought, Inc.
#  All rights reserved.
#------------------------------------------------------------------------------

Docstrings

The current documentation uses the autodoc extension of the Sphinx distribution. The autodoc parsing is also extended to convert heading-based docstring descriptions to standard reStructedText role directives.

Traits classes

In order to create autodoc-friendly docstrings for classes that inherit from traits.HasTraits, please consider the following:

  • Avoid placing headings (except those that are described below) in the multi-line docstrings since they are not rendered properly by Sphinx.

  • Document the class attributes using one or multiple lines commented with #: before (i.e. above) the attribute definition. These will be picked up by the autodoc commands and used as the docstring for the following value:

    <other code>
    
    # this comment will not appear since it lacks the ':'
    #: The file name of the .qbc file to load
    filename = File
  • Alternative you can document the attributes at the main class using the Attribute heading. The current autodoc extension supports the following headings for classes:

    Heading

    Description

    Methods

    Class methods

    Attributes

    Set of attributes

    Notes

    Useful notes (one paragraph)

    See Also

    References

For example, the Python code

#------------------------------------------------------------------------------
#  Copyright (c) 2011, Enthought, Inc.
#  All rights reserved.
#------------------------------------------------------------------------------
from traits.api import HasTraits, Float


class Myclass(HasTraits):
    """ This is a example class

    It is used to demonstrate the proposed guidelines for documenting traits
    based classes in an "sphinx-friendly" way.

    The traits are documented close to their definition by using a special
    comment ``#:`` prefix.

    """

    #: The x Float trait (default = 150.0)
    x = Float(150.0)

    # This is a comment autodoc ignores it
    #: The y Float trait (default = 0.0)
    y = Float(0.0)


class Otherclass(HasTraits):
    """ This is another example class using traits

    It is used to demonstrate the alternative method for documenting traits
    based classes in an "sphinx-friendly" way.

    The traits are documented at the start of the class definition.

    Attributes
    ----------
    x : Float, default = 150.0
        The x Float trait

    y : Float, default = 150.0
        The y Float trait

    """

    x = Float(150.0)

    # This is a comment autodoc ignores it
    y = Float(0.0)

leads to this Sphinx output (using ..autoclass::):

class traits_class.Myclass[source]

Bases: traits.has_traits.HasTraits

This is a example class

It is used to demonstrate the proposed guidelines for documenting traits based classes in an “sphinx-friendly” way.

The traits are documented close to their definition by using a special comment #: prefix.

x = None

The x Float trait (default = 150.0)

y = None

The y Float trait (default = 0.0)

__implements__

alias of __NoInterface__

class traits_class.Otherclass[source]

Bases: traits.has_traits.HasTraits

This is another example class using traits

It is used to demonstrate the alternative method for documenting traits based classes in an “sphinx-friendly” way.

The traits are documented at the start of the class definition.

x = Float, default = 150.0

The x Float trait

y = Float, default = 150.0

The y Float trait

__implements__

alias of __NoInterface__

Functions

In order to create autodoc-friendly docstrings for functions, please consider the following:

  • The current parser extension supports the following headings for functions:

    Heading

    Description

    Arguments

    Set of function arguments and their usage

    Returns

    Return values of the function

    Raises

    Errors and the cases in which they are raised

    Yields

    Successive results of the generator

  • Each section/heading can accept items with one of the following structures (spaces around : are important):

    <heading>
    ---------
    <name> : <type>
        <description>
    
    <name> : <type>
        <description>
    
    <name> :
        <description>
    
    <heading>
    ---------
        <description>

    The last form is useful when a paragraph is more appropriate than a an item list.

  • Empty headings are removed and do not appear in the sphinx documentation

Note

The use of the headings is optional. The developer can use directly the rst role directives to format the docstrings. However, using the headings, the dosctring is also readable in interactive python sessions.

Example
"""Extract the fields from the docstring

Parse the fields into tuples of name, type and description in a
list of strings. The strings are also removed from the list.

Arguments
---------
indent : str, optional
    the indent argument is used to make sure that only the lines
    with the same indent are considered when checking for a
    field header line. The value is used to define the field
    checking function.

field_check : function
    Optional function to use for checking if the next line is a
    field. The signature of the function is ``foo(line)`` and it
    should return ``True`` if the line contains a valid field
    The default function is checking for fields of the following
    formats::

        <name> : <type>

    or::

        <name> :

    Where the name has to be one word.

Returns
-------
parameters : list of tuples
    list of parsed parameter tuples as returned from the
    :meth:`~BaseDocstring.parse_field` method.

"""
FunctionDoc.extract_fields(indent='', field_type=None)

Extract the fields from the docstring

Parse the fields in the description of a section into tuples of name, type and description in a list of strings. The parsed lines are also removed from original list.

Parameters:
  • indent (str, optional) – the indent argument is used to make sure that only the lines with the same indent are considered when checking for a field header line. The value is used to define the field checking function.
  • field_check (function) –

    Optional function to use for checking if the next line is a field. The signature of the function is foo(line) and it should return True if the line contains a valid field The default function is checking for fields of the following formats:

    <name> : <type>

    or:

    <name> :

    Where the name has to be one word.

Returns:

parameters (list of tuples) – list of parsed parameter tuples as returned from the parse_field() method.