Skip to content

Commit

Permalink
Merge pull request #241 from enthought/mock-traitsui-for-documentation
Browse files Browse the repository at this point in the history
Mock traitsui when building the documentation
  • Loading branch information
mdickinson committed Jun 25, 2015
2 parents d79baa4 + 510288a commit 436a6f2
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.rst
Expand Up @@ -52,3 +52,10 @@ Traits has the following optional dependencies:

* `NumPy <http://pypi.python.org/pypi/numpy>`_ to support the trait types
for arrays.
* `Traitsui <https://pypi.python.org/pypi/traitsui>`_ to support Gui
Views.

To build the full documentation one needs:

* sphinx > 1.2.3
* mock (optional if traitsui is not available)
242 changes: 242 additions & 0 deletions docs/make.bat
@@ -0,0 +1,242 @@
@ECHO OFF

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
set I18NSPHINXOPTS=%SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)

if "%1" == "" goto help

if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)

if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)


%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)

if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)

if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)

if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)

if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)

if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)

if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)

if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\SimPhoNy.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\SimPhoNy.ghc
goto end
)

if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)

if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)

if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)

if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)

if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)

if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)

if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)

if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)

if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)

if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)

if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)

if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)

if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)

if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)

:end
96 changes: 95 additions & 1 deletion docs/source/conf.py
Expand Up @@ -11,14 +11,108 @@
# All configuration values have a default value; values that are commented out
# serve to show the default value.

import sys, os
import sys
import os

# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
sys.path.append(os.path.abspath('_extensions'))
sys.path.append(os.path.abspath('../../'))


def mock_modules():
""" Optionally Mock missing modules to allow autodoc based documentation.
The ``traits.has_dynamics_view`` imports the traitsui module and
thus traitsui is needed so that the ``autodoc`` extension can
extract the docstrings from the has_dynamics_view module. This
function optionally mocks the traitsui module so that the traits
documentation can be built without the traitui optional dependency
installed.
.. note::
The mock library is needed in order to mock the traitsui
package.
"""

MOCK_MODULES = []
MOCK_TYPES = []

# Check to see if we need to mock the traitsui package
try:
import traitsui
except ImportError:
# Modules that we need to mock
MOCK_MODULES = [
'traitsui', 'traitsui.api', 'traitsui.delegating_handler']

# Collect the types from traitsui that are based on HasTraits
# We will need to mock them in a special way so that
# TraitDocumenter can properly identify and document traits.
from traits.api import HasTraits, HasPrivateTraits
MOCK_TYPES.append(
('traitsui.delegating_handler',
'DelegatingHandler', (HasTraits,)))
MOCK_TYPES.append(
('traitsui.view_element',
'ViewSubElement', (HasPrivateTraits,)))
else:
return

try:
from mock import MagicMock
except ImportError:
if len(MOCK_MODULES) != 0:
print(
'NOTE: TraitsUI is not installed and mock is not available to '
'mock the missing modules, some classes will not be documented')
return

# Create the custom types for the HasTraits based traitsui objects.
TYPES = {
mock_type: type(mock_type, bases, {'__module__': path})
for path, mock_type, bases in MOCK_TYPES}

class DocMock(MagicMock):
""" The special sphinx friendly mocking class to mock missing packages.
Based on the suggestion from http://docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules
"""

@classmethod
def __getattr__(self, name):
if name in ('__file__', '__path__'):
# sphinx does not like getting a Mock object in this case.
return '/dev/null'
else:
# Return a mock or a custom type as requested.
return TYPES.get(name, DocMock(mocked_name=name))

# MagicMock does not define __call__ we do just to make sure
# that we cover all cases.
def __call__(self, *args, **kwards):
return DocMock()

@property
def __name__(self):
# Make sure that if sphinx asks for the name of a Mocked class
# it gets a nice strings to use (instead of "DocMock")
return self.mocked_name

# Add the mocked modules to sys
sys.modules.update(
(mod_name, DocMock(mocked_name=mod_name)) for mod_name in MOCK_MODULES)

# Report on what was mocked.
print 'mocking modules {0} and types {1}'.format(
MOCK_MODULES, [mocked[1] for mocked in MOCK_TYPES])

mock_modules()

# General configuration
# ---------------------

Expand Down

0 comments on commit 436a6f2

Please sign in to comment.