diff -r 948d8ea8e7a6 Lib/warnings.py --- a/Lib/warnings.py Mon Aug 17 13:04:41 2015 -0400 +++ b/Lib/warnings.py Mon Aug 17 18:03:18 2015 -0700 @@ -160,6 +160,12 @@ return cat +def _internal_frame(frame): + """Signal whether the frame is an internal CPython implementation detail.""" + filename = frame.f_code.co_filename + return 'importlib' in filename and '_bootstrap' in filename + + # Code typically replaced by _warnings def warn(message, category=None, stacklevel=1): """Issue a warning, or maybe ignore it or raise an exception.""" @@ -174,13 +180,25 @@ "not '{:s}'".format(type(category).__name__)) # Get context information try: - caller = sys._getframe(stacklevel) + if stacklevel < 0: + frame = sys._getframe(stacklevel) + else: + # Basically a funky do...while loop. + frame = sys._getframe() + if not _internal_frame(frame): + stacklevel -= 1 + while stacklevel >= 0: + frame = frame.f_back + if frame is None: + raise ValueError + elif not _internal_frame(frame): + stacklevel -= 1 except ValueError: globals = sys.__dict__ lineno = 1 else: - globals = caller.f_globals - lineno = caller.f_lineno + globals = frame.f_globals + lineno = frame.f_lineno if '__name__' in globals: module = globals['__name__'] else: @@ -370,11 +388,10 @@ _warnings_defaults = False try: from _warnings import (filters, _defaultaction, _onceregistry, - warn, warn_explicit, _filters_mutated) + warn_explicit, _filters_mutated) defaultaction = _defaultaction onceregistry = _onceregistry _warnings_defaults = True - except ImportError: filters = [] defaultaction = "default"