2

Consider the following function:

# in mymodule.py:

def myfunc(num,mystring):
    """
    replicates a string

    :param num: a positive integer
    :param mystring: a string
    :return: string concatenated with itself num times

    :Example:
        >>> num = 3
        >>> mystring = "lol"
        >>> myfunc(num, mystring)
            "lollollol"
    """
    return num*mystring

How can I make Sphinx doctest work, in order to verify the example code in

:Example:´ actually does work? Whenever I runmake doctest`

it says that 3 tests were run, but 1 fails. Deleting the last two rows, starting with

myfunc(num, mystring),

it says that 2 tests were run sucessfully. So I must be doing something wrong with that line. But what?

EDIT Here's the terminal output (traceback) for the full code; it seems that somehow it can't find the function for which I've written the docstring and I'm running the doctest:

Running Sphinx v1.8.3
loading pickled environment... done
building [mo]: targets for 0 po files that are out of date
building [doctest]: targets for 1 source files that are out of date
updating environment: [] 0 added, 1 changed, 0 removed
reading sources... [100%] index                                                 
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
running tests...

Document: index
---------------
**********************************************************************
File "index.rst", line ?, in default
Failed example:
    myfunc(num, mystring)
Exception raised:
    Traceback (most recent call last):
      File "/usr/lib/python3.6/doctest.py", line 1330, in __run
        compileflags, 1), test.globs)
      File "<doctest default[2]>", line 1, in <module>
        myfunc(num, mystring)
    NameError: name 'myfunc' is not defined
**********************************************************************
1 items had failures:
   1 of   3 in default
3 tests in 1 items.
2 passed and 1 failed.
***Test Failed*** 1 failures.

Doctest summary
===============
    3 tests
    1 failure in tests
    0 failures in setup code
    0 failures in cleanup code
build finished with problems.
Makefile:19: recipe for target 'doctest' failed
Demi-Lune
  • 1,446
  • 2
  • 11
  • 20
l7ll7
  • 1,039
  • 1
  • 8
  • 15

2 Answers2

2

Sphinx+doctest is not importing the module. You can either help him in the docstring:

    :Example:
        >>> from mymodule import myfunc
        >>> myfunc(3, 'lol')
        'lollollol'

or add this in conf.py:

doctest_global_setup = '''
#if required, modif sys.path:
import sys
sys.path.append('../directory_containing_mymodule/')
from mymodule import *
'''

cf. https://www.sphinx-doc.org/en/master/usage/extensions/doctest.html

I'll be interested to hear if there are simpler answers.

Demi-Lune
  • 1,446
  • 2
  • 11
  • 20
  • This almost worked! The import in `:Example:` works, but if I add it to the `conf.py` it doesn't. Is there anything I could to get `conf.py` to work? – l7ll7 Oct 02 '19 at 09:09
  • Is there actually any way that I could import everything in `conf.py` from the folder I'm working in, so that I dont' each time I create a new module and write docstrings for functions/methods inside it, I have to add those to `conf.py`? – l7ll7 Oct 02 '19 at 09:14
  • Is your module already packaged (with `setup.py` and `__init__.py`)? sphinx may not be running in the folder that contains `mymodule.py`, so you probably need a `setup.py` or  set `PYTHONPATH` to be safe. – Demi-Lune Oct 02 '19 at 10:50
  • No, my module is just a file in `myproject`, whereas all Sphinx-related files are in `myproject/docs`. I've never packaged a module (and I don't know what to do with `PYTHONPATH` either), because I'm pretty new to Python; sorry :( – l7ll7 Oct 02 '19 at 12:28
  • @l7ll7, PYTHONPATH (or sys.path) tells where your personal modules are (when they are not in current directory), see for example: https://stackoverflow.com/questions/3402168/permanently-add-a-directory-to-pythonpath – Demi-Lune Oct 02 '19 at 20:17
  • I've added for example in conf.py a `sys.path` manipulation. You'll need to adapt to your files locations. – Demi-Lune Oct 02 '19 at 21:24
1

On my terminal and outside Sphinx, I have to left align "lollollol" and use simple quotes in order to successfully run doctest:

    :Example:
        >>> num = 3
        >>> mystring = "lol"
        >>> myfunc(num, mystring)
        'lollollol'
aflp91
  • 591
  • 4
  • 11
  • Unfortunately it doesn't seem to work either :(. I've attaced the traceback to my question. – l7ll7 Oct 02 '19 at 07:18
  • Correct alignment and single quotes are indeed part of the solution. When executing `3 * "lol"` in an interactive session, the output is `'lollollol'`. Doctest does not accept `"lollollol"` as the expected output. – mzjn Oct 02 '19 at 09:01