Why do warnings behave differently in these two situations?
They don't. From the docs:
Repetitions of a particular warning for the same source location are
typically suppressed.
import warnings
def f():
warnings.warn("dep", DeprecationWarning)
print('in f')
f()
warnings.resetwarnings()
eval('f()')
Or:
import warnings
def f():
warnings.warn("dep", DeprecationWarning)
print('in f')
# don't call f()
#f()
eval('f()')
Both show the warning from the eval('f()') call:
# with warnings.resetwarnings() between f() and eval('f()')
in f
/home/gir/local/dev/pcws/local/main.py:7: DeprecationWarning: dep
in f
warnings.warn("dep", DeprecationWarning)
/home/gir/local/dev/pcws/local/main.py:7: DeprecationWarning: dep
warnings.warn("dep", DeprecationWarning)
# without calling f() directly
/home/gir/local/dev/pcws/local/main.py:5: DeprecationWarning: dep
in f
warnings.warn("dep", DeprecationWarning)