Source code for traits.util.trait_documenter
# -*- coding: utf-8 -*-
"""
A Trait Documenter
(Subclassed from the autodoc ClassLevelDocumenter)
:copyright: Copyright 2012 by Enthought, Inc
"""
import traceback
import sys
import inspect
import tokenize
import token
import StringIO
from sphinx.ext.autodoc import ClassLevelDocumenter
from ..trait_handlers import TraitType
from ..has_traits import MetaHasTraits
def _is_class_trait(name, cls):
""" Check if the name is in the list of class defined traits of ``cls``.
"""
return isinstance(cls, MetaHasTraits) and name in cls.__class_traits__
[docs]class TraitDocumenter(ClassLevelDocumenter):
""" Specialized Documenter subclass for trait attributes.
The class defines a new documenter that recovers the trait definition
signature of module level and class level traits.
To use the documenter, append the module path in the extension
attribute of the `conf.py`.
.. warning::
Using the TraitDocumenter in conjunction with TraitsDoc is not
advised.
"""
### ClassLevelDocumenter interface #####################################
objtype = 'traitattribute'
directivetype = 'attribute'
member_order = 60
# must be higher than other attribute documenters
priority = 12
@classmethod
[docs] def can_document_member(cls, member, membername, isattr, parent):
""" Check that the documented member is a trait instance.
"""
check = (isattr and issubclass(type(member), TraitType) or
_is_class_trait(membername, parent.object))
return check
[docs] def document_members(self, all_members=False):
""" Trait attributes have no members """
pass
[docs] def add_content(self, more_content, no_docstring=False):
""" Never try to get a docstring from the trait."""
ClassLevelDocumenter.add_content(self, more_content,
no_docstring=True)
[docs] def import_object(self):
""" Get the Trait object.
Notes
-----
Code adapted from autodoc.Documenter.import_object.
"""
try:
__import__(self.modname)
current = self.module = sys.modules[self.modname]
for part in self.objpath[:-1]:
current = self.get_attr(current, part)
name = self.objpath[-1]
self.object_name = name
self.object = None
self.parent = current
return True
# this used to only catch SyntaxError, ImportError and
# AttributeError, but importing modules with side effects can raise
# all kinds of errors.
except Exception, err:
if self.env.app and not self.env.app.quiet:
self.env.app.info(traceback.format_exc().rstrip())
msg = ('autodoc can\'t import/find {0} {r1}, it reported error: '
'"{2}", please check your spelling and sys.path')
self.directive.warn(msg.format(self.objtype, str(self.fullname),
err))
self.env.note_reread()
return False
def _get_trait_definition(self):
""" Retrieve the Trait attribute definition
"""
# Get the class source and tokenize it.
source = inspect.getsource(self.parent)
string_io = StringIO.StringIO(source)
tokens = tokenize.generate_tokens(string_io.readline)
# find the trait definition start
trait_found = False
name_found = False
while not trait_found:
item = tokens.next()
if name_found and item[:2] == (token.OP, '='):
trait_found = True
continue
if item[:2] == (token.NAME, self.object_name):
name_found = True
# Retrieve the trait definition.
definition_tokens = []
for type, name, start, stop, line in tokens:
if type == token.NEWLINE:
break
item = (type, name, (1, start[1]), (1, stop[1]), line)
definition_tokens.append(item)
return tokenize.untokenize(definition_tokens).strip()
[docs]def setup(app):
""" Add the TraitDocumenter in the current sphinx autodoc instance. """
app.add_autodocumenter(TraitDocumenter)