You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
multipledispatch.dispatch decorator disables docstring tests of doctest #96
I am not sure I understand what you mean by "indentation level". This issue is likely because doctest only runs tests on classes and types.FunctionType objects at module scope, not all objects with a __doc__. I ran into a similar issue with toolz.curry. You can explicitly add test cases to doctest by putting a __test__ attribute at module scope. This should be a dictionary from test name (function or class name) to the object which as a __doc__ you wish to test. For example:
@dispatch(int)deffoo(n):
""" >>> a = 1 >>> a 1 """__test__= {'foo': foo}
That can be a bit cumbersome, so I often use a decorator similar to this:
defensure_doctest(f):
"""Ensure that an object gets doctested. This is useful for instances of objects like curry which are not discovered by default. Parameters ---------- f : any The thing to doctest. Returns ------- f : any ``f`` unchanged. """sys._getframe(1).f_globals.setdefault('__test__', {})[f.__name__] =freturnf
which is used like:
@ensure_doctest@dispatch(int)deffoo(n):
...
This decorator checks the calling scope (sys._getframe(1)) and looks in the globals (.f_globals) as a dictionary. It adds a __test__ dictionary if it doesn't already exist, and then it adds the function to the dict under it's given __name__.
You're right, this has nothing to do with indentation level (thought so without testing this assumption, as functions decorated by multipledispatch.dispatch have their docstrings indented one level more). Will update the issue.
Forcing doctest to search in decorated foo, by setting __test__ or with your ensure_doctest function, results in :
---------------------------------------------------------------------------ValueErrorTraceback (mostrecentcalllast)
<ipython-input-3-fb60117592cb>in<module>()
22 """
23
---> 24 print(doctest.testmod())
25 # displays TestResults(failed=0, attempted=0)
~\AppData\Local\Continuum\anaconda3\lib\doctest.py in testmod(m, name, globs, verbose, report, optionflags, extraglobs, raise_on_error, exclude_empty)
1948 runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
1949
-> 1950 for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
1951 runner.run(test)
1952
~\AppData\Local\Continuum\anaconda3\lib\doctest.py in find(self, obj, name, module, globs, extraglobs)
931 # Recursively explore `obj`, extracting DocTests.
932 tests = []
--> 933 self._find(tests, obj, name, module, source_lines, globs, {})
934 # Sort the tests by alpha order of names, for consistency in
935 # verbose-mode output. This was a feature of doctest in Pythons
~\AppData\Local\Continuum\anaconda3\lib\doctest.py in _find(self, tests, obj, name, module, source_lines, globs, seen)
1008 "must be strings, functions, methods, "
1009 "classes, or modules: %r" %->1010 (type(val),))
1011valname='%s.__test__.%s'% (name, valname)
1012self._find(tests, val, valname, module, source_lines,
ValueError: DocTestFinder.find: __test__valuesmustbestrings, functions, methods, classes, ormodules: <class'multipledispatch.dispatcher.Dispatcher'>
changed the title [-]multipledispatch.dispatch decorator disables docstring tests of doctest with additional indentation[/-][+]multipledispatch.dispatch decorator disables docstring tests of doctest[/+]on Dec 14, 2018
The main intended use for this function is in decorator functions which wrap the decorated function and return the wrapper. If the wrapper function is not updated, the metadata of the returned function will reflect the wrapper definition rather than the original function definition, which is typically less than helpful.
Activity
llllllllll commentedon Dec 13, 2018
I am not sure I understand what you mean by "indentation level". This issue is likely because
doctestonly runs tests on classes andtypes.FunctionTypeobjects at module scope, not all objects with a__doc__. I ran into a similar issue withtoolz.curry. You can explicitly add test cases todoctestby putting a__test__attribute at module scope. This should be a dictionary from test name (function or class name) to the object which as a__doc__you wish to test. For example:That can be a bit cumbersome, so I often use a decorator similar to this:
which is used like:
This decorator checks the calling scope (
sys._getframe(1)) and looks in the globals (.f_globals) as a dictionary. It adds a__test__dictionary if it doesn't already exist, and then it adds the function to the dict under it's given__name__.louis-red commentedon Dec 14, 2018
You're right, this has nothing to do with indentation level (thought so without testing this assumption, as functions decorated by multipledispatch.dispatch have their docstrings indented one level more). Will update the issue.
Forcing doctest to search in decorated
foo, by setting__test__or with yourensure_doctestfunction, results in :[-]multipledispatch.dispatch decorator disables docstring tests of doctest with additional indentation[/-][+]multipledispatch.dispatch decorator disables docstring tests of doctest[/+]louis-red commentedon Dec 14, 2018
But that worked :
giving
Thank you for your help !
tanders commentedon Nov 20, 2019
It appears using
functools.wrapswithin the decorator is another way around that, which would avoid the need for an additional decorator (likeensure_dispatch_doctest). See https://www.rosipov.com/blog/python-doctests-and-decorators-bug/Quote from update_wrapper doc (https://docs.python.org/2/library/functools.html#functools.update_wrapper)