It looks like in xdoctest/doctest_example the:
with warnings.catch_warnings(record=True) as self.warn_list:
Might be preventing warnings from printing. In xdev I'm testing:
import warnings
def make_warnings_print_tracebacks():
"""
Makes warnings show tracebacks when displayed.
Applies a monkeypatch to warnings.formatwarning that includes a traceback
in the displayed warning message.
NOTE:
Use the context manager `:class:WarningsWithTracebacks` instead, or
:func:`WarningsWithTracebacks.apply()` if global modification is
needed.
"""
WarningsWithTracebacks.apply()
class WarningsWithTracebacks:
"""
Makes warnings show tracebacks when displayed.
Applies a monkeypatch to warnings.formatwarning that includes a traceback
in the displayed warning message.
CommandLine:
xdoctest -m xdev.tracebacks WarningsWithTracebacks:0
xdoctest -m xdev.tracebacks WarningsWithTracebacks:1
Example:
>>> from xdev.tracebacks import * # NOQA
>>> import warnings
>>> with WarningsWithTracebacks():
... warnings.warn('This is a test warning')
<string>:1: UserWarning: This is a test warning
Traceback (most recent call last):
...
Example:
>>> from xdev.tracebacks import * # NOQA
>>> import warnings
>>> warnings.warn('This warning1 has no traceback')
>>> with WarningsWithTracebacks():
>>> warnings.warn('This warning2 has a traceback')
>>> warnings.warn('This warning3 has no traceback')
Example:
>>> import warnings
>>> def my_function():
... with WarningsWithTracebacks():
... warnings.warn('This is a test warning')
>>> def driver():
>>> my_function()
>>> driver()
"""
_enter_count = 0
def __init__(self, thread_safe=True):
if thread_safe:
import threading
self._lock = threading.Lock()
else:
from contextlib import nullcontext
self._lock = nullcontext()
def __enter__(self):
with self._lock:
# Apply patching if it's the first entry in this thread
if self._enter_count == 0:
print("ENTER")
self._orig_formatwarning = warnings.formatwarning
warnings.formatwarning = self._monkeypatch_formatwarning_tb
else:
print("NOT ENTER")
self._enter_count += 1
def __exit__(self, exc_type, exc_val, exc_tb):
self._enter_count -= 1
if self._enter_count == 0:
warnings.formatwarning = self._orig_formatwarning
def _monkeypatch_formatwarning_tb(self, *args, **kwargs):
print("MONKEY MONKEY MONKEY")
import traceback
s = self._orig_formatwarning(*args, **kwargs)
if len(s.strip()):
tb = traceback.format_stack()
s += ''.join(tb[:-1])
return s
@classmethod
def apply(cls):
"""
Apply this warnings traceback patch globaly. It will not be undone.
"""
cls().__enter__()
def make_warnings_print_tracebacks2():
"""
Makes warnings show tracebacks when displayed.
Applies a monkeypatch to warnings.formatwarning that includes a traceback
in the displayed warning message.
CommandLine:
xdoctest -m xdev.tracebacks make_warnings_print_tracebacks2
Example:
>>> make_warnings_print_tracebacks2()
>>> warnings.warn('This is a test warning')
"""
import warnings
import traceback
_orig_formatwarning = warnings.formatwarning
warnings._orig_formatwarning = _orig_formatwarning
def _monkeypatch_formatwarning_tb(*args, **kwargs):
s = _orig_formatwarning(*args, **kwargs)
if len(s.strip()):
tb = traceback.format_stack()
s += ''.join(tb[:-1])
return s
warnings.formatwarning = _monkeypatch_formatwarning_tb
if __name__ == '__main__':
"""
CommandLine:
python ~/code/xdev/xdev/tracebacks.py
"""
def main():
# make_warnings_print_tracebacks2()
# warnings.warn('This is a test warning')
warnings.warn('This warning1 has no traceback')
with WarningsWithTracebacks():
warnings.warn('This warning2 has a traceback')
warnings.warn('This warning3 has no traceback')
main()
And running via xdoctest does not print MONKEY MONKEY MONKEY, but using the regular main does. Simply hacking out that line does cause the warning traceback to show.
It looks like this might be an issue witch catch_warnings. It seems like it patches warnings.showwarning, which causes formatwarning to never be called.
It looks like in xdoctest/doctest_example the:
Might be preventing warnings from printing. In xdev I'm testing:
And running via xdoctest does not print MONKEY MONKEY MONKEY, but using the regular main does. Simply hacking out that line does cause the warning traceback to show.
It looks like this might be an issue witch
catch_warnings. It seems like it patches warnings.showwarning, which causes formatwarning to never be called.