Belle II Software  release-06-02-00
conf.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 #
4 # basf2 documentation build configuration file, created by
5 # sphinx-quickstart on Mon May 23 17:26:16 2016.
6 #
7 # This file is execfile()d with the current directory set to its
8 # containing dir.
9 #
10 # Note that not all possible configuration values are present in this
11 # autogenerated file.
12 #
13 # All configuration values have a default; values that are commented out
14 # serve to show the default.
15 
16 import sys
17 import os
18 import re
19 import subprocess
20 import jupytext
21 
22 sys.path.insert(0, os.path.abspath("extensions"))
23 
24 # If extensions (or modules to document with autodoc) are in another directory,
25 # add these directories to sys.path here. If the directory is relative to the
26 # documentation root, use os.path.abspath to make it absolute, like shown here.
27 # sys.path.insert(0, os.path.abspath('....'))
28 
29 # -- General configuration ------------------------------------------------
30 
31 # If your documentation needs a minimal Sphinx version, state it here.
32 # needs_sphinx = '1.0'
33 
34 # Add any Sphinx extension module names here, as strings. They can be
35 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
36 # ones.
37 extensions = [
38  'sphinx.ext.intersphinx',
39  'sphinx.ext.autodoc',
40  # 'sphinx.ext.autosummary',
41  'sphinx.ext.mathjax',
42  'sphinx.ext.napoleon',
43  'sphinx.ext.viewcode',
44  'sphinx.ext.autosectionlabel',
45  'sphinxarg.ext',
46  'basf2ext',
47  'nbsphinx',
48  'IPython.sphinxext.ipython_console_highlighting',
49 ]
50 
51 nbsphinx_allow_errors = True
52 # Anything that ends with .jupy.py will be understood as a jupyter
53 # notebook converted to a plain python file with jupytext. During the sphinx
54 # build, jupytext will converted it back to a .ipynb file and nbsphinx will
55 # build the HTML
56 nbsphinx_custom_formats = {
57  '.doc.jupy.py': lambda s: jupytext.reads(s, '.py'),
58 }
59 
60 # autosummary_generate = True
61 
62 # prefix each section with the name of the document it is in followed by a
63 # colon
64 autosectionlabel_prefix_document = True
65 
66 # Add any paths that contain templates here, relative to this directory.
67 templates_path = ['_sphinxtemplates']
68 
69 # The suffix(es) of source filenames.
70 # You can specify multiple suffix as a list of string:
71 # source_suffix = ['.rst', '.md']
72 source_suffix = '.rst'
73 
74 # The encoding of source files.
75 # source_encoding = 'utf-8-sig'
76 
77 # The master toctree document.
78 master_doc = 'index'
79 
80 # General information about the project.
81 project = 'basf2'
82 copyright = 'Belle II Collaboration'
83 author = 'Belle II Software Group'
84 
85 # The version info for the project you're documenting, acts as replacement for
86 # |version| and |release|, also used in various other places throughout the
87 # built documents.
88 #
89 # The short X.Y version.
90 version = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).decode().strip()
91 # Used for links to the repository
92 basf2_repository = "https://stash.desy.de/projects/B2/repos/basf2"
93 basf2_commitid = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().strip()
94 basf2_jira = "https://agira.desy.de"
95 
96 # The full version, including alpha/beta/rc tags.
97 release = os.environ.get('BELLE2_RELEASE', 'development')
98 if release == 'head':
99  release = 'development'
100 
101 # Add warnings in the code if this is not a release
102 keep_warnings = release == "development"
103 nitpicky = keep_warnings
104 
105 # The language for content autogenerated by Sphinx. Refer to documentation
106 # for a list of supported languages.
107 #
108 # This is also used if you do content translation via gettext catalogs.
109 # Usually you set "language" from the command line for these cases.
110 language = None
111 
112 # There are two options for replacing |today|: either, you set today to some
113 # non-false value, then it is used:
114 # today = ''
115 # Else, today_fmt is used as the format for a strftime call.
116 # today_fmt = '%B %d, %Y'
117 
118 # List of patterns, relative to source directory, that match files and
119 # directories to ignore when looking for source files.
120 # This patterns also effect to html_static_path and html_extra_path
121 exclude_patterns = ['.*', '_sphinxbuild', 'Thumbs.db', 'build', 'include', 'lib', 'bin', 'modules', 'data', 'site_scons']
122 # If we want to create the light release documentation then we need t exclude anything not in the light release.
123 if tags.has('light'): # noqa
124  light_packages = set([entry.strip('/') for entry in open('../../.light').read().split() if entry.endswith('/')])
125  for entry in os.listdir("../../"):
126  if entry.find('.') > -1 or os.path.isfile(entry) or entry in exclude_patterns or entry in light_packages:
127  continue
128  exclude_patterns.append(entry)
129  del light_packages
130 
131 # now we need to exclude everything in the build dir except for the tools_doc
132 # sub dir but there's no negative exclusion pattern so do it manually
133 exclude_patterns.remove("build")
134 exclude_patterns += ['build/html', 'build/latex', 'build/json', 'build/Linux*']
135 # Ignore jupyter notebooks by default, we only want the ones meant for documentation
136 exclude_patterns += ['**/*.ipynb', '*.ipynb']
137 
138 # The reST default role (used for this markup: `text`) to use for all
139 # documents. :any: allows easy linking to functions/classes/modules
140 default_role = 'any'
141 
142 # If true, '()' will be appended to :func: etc. cross-reference text.
143 # add_function_parentheses = True
144 
145 # If true, the current module name will be prepended to all description
146 # unit titles (such as .. function::).
147 # add_module_names = True
148 
149 # If true, sectionauthor and moduleauthor directives will be shown in the
150 # output. They are ignored by default.
151 # show_authors = False
152 
153 # The name of the Pygments (syntax highlighting) style to use.
154 pygments_style = 'sphinx'
155 
156 # A list of ignored prefixes for module index sorting.
157 # modindex_common_prefix = []
158 
159 # If true, keep warnings as "system message" paragraphs in the built documents.
160 # keep_warnings = False
161 
162 # If true, `todo` and `todoList` produce output, else they produce nothing.
163 todo_include_todos = False
164 
165 # If true, figures with captions automatically get figure numbers included at the start of the caption.
166 # Also the :numref: role is allowed for figures. Referencing figures/sections etc in this way
167 # will insert a reference to the reference number instead of the reference text/caption.
168 numfig = True
169 
170 # -- Options for HTML output ----------------------------------------------
171 
172 # The theme to use for HTML and HTML Help pages. See the documentation for
173 # a list of builtin themes.
174 html_theme = 'sphinx_rtd_theme'
175 
176 # Theme options are theme-specific and customize the look and feel of a theme
177 # further. For a list of options available for each theme, see the
178 # documentation.
179 # html_theme_options = {'stickysidebar': True}
180 
181 # Add any paths that contain custom themes here, relative to this directory.
182 html_theme_path = ["_themes", ]
183 
184 # The name for this set of Sphinx documents.
185 # "<project> v<release> documentation" by default.
186 # html_title = 'basf2 vhead'
187 
188 # A shorter title for the navigation bar. Default is the same as html_title.
189 # html_short_title = None
190 
191 # The name of an image file (relative to this directory) to place at the top
192 # of the sidebar.
193 html_logo = "b2logo.svg"
194 
195 # The name of an image file (relative to this directory) to use as a favicon of
196 # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
197 # pixels large.
198 # html_favicon = None
199 
200 # Add any paths that contain custom static files (such as style sheets) here,
201 # relative to this directory. They are copied after the builtin static files,
202 # so a file named "default.css" will overwrite the builtin "default.css".
203 html_static_path = ['_sphinxstatic']
204 
205 # Add any extra paths that contain custom files (such as robots.txt or
206 # .htaccess) here, relative to this directory. These files are copied
207 # directly to the root of the documentation.
208 # html_extra_path = []
209 
210 # If not None, a 'Last updated on:' timestamp is inserted at every page
211 # bottom, using the given strftime format.
212 # The empty string is equivalent to '%b %d, %Y'.
213 # html_last_updated_fmt = None
214 
215 # If true, SmartyPants will be used to convert quotes and dashes to
216 # typographically correct entities.
217 # html_use_smartypants = True
218 
219 # Custom sidebar templates, maps document names to template names.
220 # html_sidebars = {}
221 
222 # Additional templates that should be rendered to pages, maps page names to
223 # template names.
224 # html_additional_pages = {}
225 
226 # If false, no module index is generated.
227 # html_domain_indices = True
228 
229 # If false, no index is generated.
230 # html_use_index = True
231 
232 # If true, the index is split into individual pages for each letter.
233 # html_split_index = False
234 
235 # If true, links to the reST sources are added to the pages.
236 # html_show_sourcelink = True
237 
238 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
239 # html_show_sphinx = True
240 
241 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
242 # html_show_copyright = True
243 
244 # If true, an OpenSearch description file will be output, and all pages will
245 # contain a <link> tag referring to it. The value of this option must be the
246 # base URL from which the finished HTML is served.
247 # html_use_opensearch = ''
248 
249 # This is the file name suffix for HTML files (e.g. ".xhtml").
250 # html_file_suffix = None
251 
252 # Language to be used for generating the HTML full-text search index.
253 # Sphinx supports the following languages:
254 # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
255 # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'
256 # html_search_language = 'en'
257 
258 # A dictionary with options for the search language support, empty by default.
259 # 'ja' uses this config value.
260 # 'zh' user can custom change `jieba` dictionary path.
261 # html_search_options = {'type': 'default'}
262 
263 # The name of a javascript file (relative to the configuration directory) that
264 # implements a search results scorer. If empty, the default will be used.
265 # html_search_scorer = 'scorer.js'
266 
267 # Output file base name for HTML help builder.
268 htmlhelp_basename = 'basf2doc'
269 
270 # -- Options for LaTeX output ---------------------------------------------
271 
272 latex_elements = {
273  # The paper size ('letterpaper' or 'a4paper').
274  'papersize': 'a4paper',
275 
276  # The font size ('10pt', '11pt' or '12pt').
277  'pointsize': '10pt',
278 
279  # Additional stuff for the LaTeX preamble.
280  'preamble': '\\setcounter{tocdepth}{2}',
281 
282  # Latex figure (float) alignment
283  # 'figure_align': 'htbp',
284 }
285 
286 # Grouping the document tree into LaTeX files. List of tuples
287 # (source start file, target name, title,
288 # author, documentclass [howto, manual, or own class]).
289 latex_documents = [
290  (master_doc, 'basf2.tex', 'Belle 2 Software Documentation',
291  author, 'manual'),
292 ]
293 
294 # The name of an image file (relative to this directory) to place at the top of
295 # the title page.
296 latex_logo = "belle2-logo.pdf"
297 
298 # For "manual" documents, if this is true, then toplevel headings are parts,
299 # not chapters.
300 latex_use_parts = True
301 latex_show_urls = 'footnote'
302 latex_show_pagerefs = True
303 
304 # If true, show page references after internal links.
305 # latex_show_pagerefs = False
306 
307 # If true, show URL addresses after external links.
308 # latex_show_urls = False
309 
310 # Documents to append as an appendix to all manuals.
311 # latex_appendices = []
312 
313 # If false, no module index is generated.
314 # latex_domain_indices = True
315 
316 
317 # -- Options for manual page output ---------------------------------------
318 
319 # One entry per manual page. List of tuples
320 # (source start file, name, description, authors, manual section).
321 man_pages = [
322  (master_doc, 'basf2', 'basf2 Documentation',
323  [author], 1)
324 ]
325 
326 # If true, show URL addresses after external links.
327 # man_show_urls = False
328 
329 
330 # -- Options for Texinfo output -------------------------------------------
331 
332 # Grouping the document tree into Texinfo files. List of tuples
333 # (source start file, target name, title, author,
334 # dir menu entry, description, category)
335 texinfo_documents = [
336  (master_doc, 'basf2', 'basf2 Documentation',
337  author, 'basf2', 'One line description of project.',
338  'Miscellaneous'),
339 ]
340 
341 # Documents to append as an appendix to all manuals.
342 # texinfo_appendices = []
343 
344 # If false, no module index is generated.
345 # texinfo_domain_indices = True
346 
347 # How to display URL addresses: 'footnote', 'no', or 'inline'.
348 # texinfo_show_urls = 'footnote'
349 
350 # If true, do not generate a @detailmenu in the "Top" node's menu.
351 # texinfo_no_detailmenu = False
352 
353 # allow to have links to python documentation
354 intersphinx_mapping = {'python': ('https://docs.python.org/3.6', None)}
355 
356 
357 def process_sig(app, what, name, obj, options, signature, return_annotation):
358  """
359  remove unhelpful 'self' arguments from methods.
360  """
361  if what == 'method' and signature:
362  reg = re.compile('^\\( \\(.*\\)arg1')
363  signature = reg.sub('(', signature)
364  return (signature, return_annotation)
365 
366 
367 def improve_docstring(obj):
368  """
369  Enhances docstrings of PyROOT objects/classes.
370 
371  >>> improve_docstring(Belle2.Variable.Manager)
372 
373  or
374 
375  >>> variables = ROOT.Belle2.Variable.Manager
376  >>> improve_docstring(variables)
377  """
378  try:
379  # is this a ..._meta object?
380  classname = obj.__name__
381  pyclass = obj
382  except AttributeError:
383  classname = obj.__class__.__name__
384  pyclass = obj.__class__
385 
386  if '::' not in classname:
387  return # not a ROOT class?
388  pos = classname.find('Belle2::')
389  classname = classname[pos:]
390  if pyclass.__doc__ is None:
391  pyclass.__doc__ = ''
392 
393  pyclass.__name__ = 'Belle2.' + classname
394 
395  from ROOT import TClass
396  tclass = TClass(classname)
397  # if tclass:
398  # pyclass.__doc__ += '\n' + tclass.GetTitle()
399 
400  doxygen_url = 'https://software.belle2.org/development/class'
401  doxygen_url += '_1_1'.join(classname.split('::'))
402  doxygen_url += '.html'
403  pyclass.__doc__ += '\n`Doxygen page for %s <%s>`_' % (classname, doxygen_url)
404 
405  # TODO put this into the member docstrings directly? (sadly, readonly)
406  members = tclass.GetListOfMethods()
407  if members.GetEntries() > 0:
408  pyclass.__doc__ += '\n\nMember functions:'
409  for f in members:
410  # getattr(pyclass, f.GetName()).__doc__ = "test"
411  pyclass.__doc__ += '\n * %s %s%s' % (f.GetReturnTypeName(), f.GetName(), f.GetSignature())
412  title = f.GetTitle()
413  if title:
414  pyclass.__doc__ += ' (%s)' % (title)
415 
416  members = tclass.GetListOfAllPublicDataMembers()
417  if members.GetEntries() > 0:
418  pyclass.__doc__ += '\n\nPublic data members'
419  for f in members:
420  pyclass.__doc__ += '\n * %s' % (f.GetName())
421  title = f.GetTitle()
422  if title:
423  pyclass.__doc__ += ' (%s)' % (title)
424 
425 
426 def skipmember(app, what, name, obj, skip, options):
427  """
428  This is executed before docstring processing,
429  so try improving them a bit.
430  """
431  try:
432  improve_docstring(obj)
433  except AttributeError:
434  pass
435  return skip
436 
437 
438 def process_docstring(app, what, name, obj, options, lines):
439  """
440  convert doxygen syntax to sphinx
441  """
442  substitutions = {
443  re.compile(r'^( *)@param (.*?):? '): r':param \2: ',
444  re.compile(r'^( *)@returns? '): r':return: ',
445  }
446  newlines = []
447  for line in lines:
448  new = line
449  for reg, sub in substitutions.items():
450  new = reg.sub(sub, new)
451  if new != line:
452  # Sphinx wants a new paragraph before these, so let's add one
453  newlines += ['']
454  newlines += [new]
455  lines[:] = newlines
456 
457 
458 def setup(app):
459  """
460  Install some event handlers to improve output.
461  """
462  app.connect('autodoc-process-signature', process_sig)
463  app.connect('autodoc-process-docstring', process_docstring)
464  app.connect('autodoc-skip-member', skipmember)
465  app.add_css_file('css/custom.css')
466 
467 
468 # Work around https://github.com/sphinx-doc/sphinx/issues/9189 by monkey patching the member function in question
469 # FIXME: Not needed with sphinx>=4.0.1
470 
471 from sphinx.ext import autodoc # noqa
472 # remember the old function
473 old_directive_header = autodoc.PropertyDocumenter.add_directive_header
474 
475 
476 # make a new one that ignores the value error
477 def _fixed_directive_header(*args, **argk):
478  """Catch the ValueError and ignore it as done in https://github.com/sphinx-doc/sphinx/pull/9190"""
479  try:
480  old_directive_header(*args, **argk)
481  except ValueError:
482  return None
483 
484 
485 # and override the existing function with our new and improved version.
486 autodoc.PropertyDocumenter.add_directive_header = _fixed_directive_header