Description
Bug report
Bug description:
In the REPL, running doctests contained in the docstring of a class is broken since version 3.10. Example:
import doctest
class A:
"""Docstring of A, with tests.
>>> 1 + 2
3
"""
pass
doctest.run_docstring_examples(A, globals(), name='A', verbose=True)
In version 3.9, this code works and executes the doctest in the docstring of the class A
. In version 3.10 (and onward), the call to doctest.run_docstring_examples
fails with OSError: source code not available
.
This only fails in the REPL and not in regular Python files. In particular, this also fails in (Jupyter) notebook environments.
Cause
This change in behavior is caused by 48a6255 as a fix for #88814. Previously, inspect.getsourcefile()
could only fail with TypeError
, but this can now also be OSError
. The new exception type is not being handled by doctest, only TypeError
is caught:
Lines 924 to 927 in 713e428
The call to inspect.getsourcefile()
is only used by doctest to determine line numbers, if available. Thus, failing to find the source file can safely fail silently in environments where line numbers are not available (such as the REPL).
Proposed changes
- Also catch
OSError
in the doctest finder (in the linked snippet). - Update the documentation to reflect that
inspect.getsourcefile()
can also fail withOSError
.
An alternative would be to change the exception type in 48a6255 to also be TypeError
in the case the source file is not available. I do not think this a desired change.
I am happy to contribute a pull request with these changes.
CPython versions tested on:
3.9, 3.10, 3.11
Operating systems tested on:
Linux
Activity
gaogaotiantian commentedon Dec 20, 2023
This makes sense to me as we documented inspect.getsourcelines that it could raise
OSError
. The changes to doctest is reasonable to me as well.I think the change should not be too difficult, so maybe you can make the PR if you want? I'm fairly confident that the doctest fix would be accepted, even if it's not, the documentation should definitely be updated.
pythongh-113329: Catch OSError in doctest finder
Merge branch 'main' into pythongh-113329
serhiy-storchaka commentedon Dec 22, 2023
Thank you for your report and PR @stenwessel. It LGTM in general if we keep OSError (we need also to add
versionchanged
directives and a What's New entry). But I wonder whether changing the exception type to TypeError is a better solution. I do not feel that OSError fits here.serhiy-storchaka commentedon Dec 22, 2023
@ambv, please take your attention.
stenwessel commentedon Dec 22, 2023
Hi @serhiy-storchaka, I agree that the OSError might be an undesired exception type in this case, especially since this may break functionality in more places than just this doctest issue.
On the other hand,
inspect.getsourcelines
andinspect.getsource
do fail with OSError as well when the source code cannot be found since version 3.3 (and this is documented as such). Additionally changing toTypeError
will break code that catches TypeError assuming this means builtin class, while this is not necessarily the case.Either way, I am of course happy to change the PR when necessary (also with the other updates for e.g. documentation and release notes, as I am not entirely sure what is required)