1*cda5da8dSAndroid Build Coastguard Worker"""Python part of the warnings subsystem.""" 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard Workerimport sys 4*cda5da8dSAndroid Build Coastguard Worker 5*cda5da8dSAndroid Build Coastguard Worker 6*cda5da8dSAndroid Build Coastguard Worker__all__ = ["warn", "warn_explicit", "showwarning", 7*cda5da8dSAndroid Build Coastguard Worker "formatwarning", "filterwarnings", "simplefilter", 8*cda5da8dSAndroid Build Coastguard Worker "resetwarnings", "catch_warnings"] 9*cda5da8dSAndroid Build Coastguard Worker 10*cda5da8dSAndroid Build Coastguard Workerdef showwarning(message, category, filename, lineno, file=None, line=None): 11*cda5da8dSAndroid Build Coastguard Worker """Hook to write a warning to a file; replace if you like.""" 12*cda5da8dSAndroid Build Coastguard Worker msg = WarningMessage(message, category, filename, lineno, file, line) 13*cda5da8dSAndroid Build Coastguard Worker _showwarnmsg_impl(msg) 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard Workerdef formatwarning(message, category, filename, lineno, line=None): 16*cda5da8dSAndroid Build Coastguard Worker """Function to format a warning the standard way.""" 17*cda5da8dSAndroid Build Coastguard Worker msg = WarningMessage(message, category, filename, lineno, None, line) 18*cda5da8dSAndroid Build Coastguard Worker return _formatwarnmsg_impl(msg) 19*cda5da8dSAndroid Build Coastguard Worker 20*cda5da8dSAndroid Build Coastguard Workerdef _showwarnmsg_impl(msg): 21*cda5da8dSAndroid Build Coastguard Worker file = msg.file 22*cda5da8dSAndroid Build Coastguard Worker if file is None: 23*cda5da8dSAndroid Build Coastguard Worker file = sys.stderr 24*cda5da8dSAndroid Build Coastguard Worker if file is None: 25*cda5da8dSAndroid Build Coastguard Worker # sys.stderr is None when run with pythonw.exe: 26*cda5da8dSAndroid Build Coastguard Worker # warnings get lost 27*cda5da8dSAndroid Build Coastguard Worker return 28*cda5da8dSAndroid Build Coastguard Worker text = _formatwarnmsg(msg) 29*cda5da8dSAndroid Build Coastguard Worker try: 30*cda5da8dSAndroid Build Coastguard Worker file.write(text) 31*cda5da8dSAndroid Build Coastguard Worker except OSError: 32*cda5da8dSAndroid Build Coastguard Worker # the file (probably stderr) is invalid - this warning gets lost. 33*cda5da8dSAndroid Build Coastguard Worker pass 34*cda5da8dSAndroid Build Coastguard Worker 35*cda5da8dSAndroid Build Coastguard Workerdef _formatwarnmsg_impl(msg): 36*cda5da8dSAndroid Build Coastguard Worker category = msg.category.__name__ 37*cda5da8dSAndroid Build Coastguard Worker s = f"{msg.filename}:{msg.lineno}: {category}: {msg.message}\n" 38*cda5da8dSAndroid Build Coastguard Worker 39*cda5da8dSAndroid Build Coastguard Worker if msg.line is None: 40*cda5da8dSAndroid Build Coastguard Worker try: 41*cda5da8dSAndroid Build Coastguard Worker import linecache 42*cda5da8dSAndroid Build Coastguard Worker line = linecache.getline(msg.filename, msg.lineno) 43*cda5da8dSAndroid Build Coastguard Worker except Exception: 44*cda5da8dSAndroid Build Coastguard Worker # When a warning is logged during Python shutdown, linecache 45*cda5da8dSAndroid Build Coastguard Worker # and the import machinery don't work anymore 46*cda5da8dSAndroid Build Coastguard Worker line = None 47*cda5da8dSAndroid Build Coastguard Worker linecache = None 48*cda5da8dSAndroid Build Coastguard Worker else: 49*cda5da8dSAndroid Build Coastguard Worker line = msg.line 50*cda5da8dSAndroid Build Coastguard Worker if line: 51*cda5da8dSAndroid Build Coastguard Worker line = line.strip() 52*cda5da8dSAndroid Build Coastguard Worker s += " %s\n" % line 53*cda5da8dSAndroid Build Coastguard Worker 54*cda5da8dSAndroid Build Coastguard Worker if msg.source is not None: 55*cda5da8dSAndroid Build Coastguard Worker try: 56*cda5da8dSAndroid Build Coastguard Worker import tracemalloc 57*cda5da8dSAndroid Build Coastguard Worker # Logging a warning should not raise a new exception: 58*cda5da8dSAndroid Build Coastguard Worker # catch Exception, not only ImportError and RecursionError. 59*cda5da8dSAndroid Build Coastguard Worker except Exception: 60*cda5da8dSAndroid Build Coastguard Worker # don't suggest to enable tracemalloc if it's not available 61*cda5da8dSAndroid Build Coastguard Worker tracing = True 62*cda5da8dSAndroid Build Coastguard Worker tb = None 63*cda5da8dSAndroid Build Coastguard Worker else: 64*cda5da8dSAndroid Build Coastguard Worker tracing = tracemalloc.is_tracing() 65*cda5da8dSAndroid Build Coastguard Worker try: 66*cda5da8dSAndroid Build Coastguard Worker tb = tracemalloc.get_object_traceback(msg.source) 67*cda5da8dSAndroid Build Coastguard Worker except Exception: 68*cda5da8dSAndroid Build Coastguard Worker # When a warning is logged during Python shutdown, tracemalloc 69*cda5da8dSAndroid Build Coastguard Worker # and the import machinery don't work anymore 70*cda5da8dSAndroid Build Coastguard Worker tb = None 71*cda5da8dSAndroid Build Coastguard Worker 72*cda5da8dSAndroid Build Coastguard Worker if tb is not None: 73*cda5da8dSAndroid Build Coastguard Worker s += 'Object allocated at (most recent call last):\n' 74*cda5da8dSAndroid Build Coastguard Worker for frame in tb: 75*cda5da8dSAndroid Build Coastguard Worker s += (' File "%s", lineno %s\n' 76*cda5da8dSAndroid Build Coastguard Worker % (frame.filename, frame.lineno)) 77*cda5da8dSAndroid Build Coastguard Worker 78*cda5da8dSAndroid Build Coastguard Worker try: 79*cda5da8dSAndroid Build Coastguard Worker if linecache is not None: 80*cda5da8dSAndroid Build Coastguard Worker line = linecache.getline(frame.filename, frame.lineno) 81*cda5da8dSAndroid Build Coastguard Worker else: 82*cda5da8dSAndroid Build Coastguard Worker line = None 83*cda5da8dSAndroid Build Coastguard Worker except Exception: 84*cda5da8dSAndroid Build Coastguard Worker line = None 85*cda5da8dSAndroid Build Coastguard Worker if line: 86*cda5da8dSAndroid Build Coastguard Worker line = line.strip() 87*cda5da8dSAndroid Build Coastguard Worker s += ' %s\n' % line 88*cda5da8dSAndroid Build Coastguard Worker elif not tracing: 89*cda5da8dSAndroid Build Coastguard Worker s += (f'{category}: Enable tracemalloc to get the object ' 90*cda5da8dSAndroid Build Coastguard Worker f'allocation traceback\n') 91*cda5da8dSAndroid Build Coastguard Worker return s 92*cda5da8dSAndroid Build Coastguard Worker 93*cda5da8dSAndroid Build Coastguard Worker# Keep a reference to check if the function was replaced 94*cda5da8dSAndroid Build Coastguard Worker_showwarning_orig = showwarning 95*cda5da8dSAndroid Build Coastguard Worker 96*cda5da8dSAndroid Build Coastguard Workerdef _showwarnmsg(msg): 97*cda5da8dSAndroid Build Coastguard Worker """Hook to write a warning to a file; replace if you like.""" 98*cda5da8dSAndroid Build Coastguard Worker try: 99*cda5da8dSAndroid Build Coastguard Worker sw = showwarning 100*cda5da8dSAndroid Build Coastguard Worker except NameError: 101*cda5da8dSAndroid Build Coastguard Worker pass 102*cda5da8dSAndroid Build Coastguard Worker else: 103*cda5da8dSAndroid Build Coastguard Worker if sw is not _showwarning_orig: 104*cda5da8dSAndroid Build Coastguard Worker # warnings.showwarning() was replaced 105*cda5da8dSAndroid Build Coastguard Worker if not callable(sw): 106*cda5da8dSAndroid Build Coastguard Worker raise TypeError("warnings.showwarning() must be set to a " 107*cda5da8dSAndroid Build Coastguard Worker "function or method") 108*cda5da8dSAndroid Build Coastguard Worker 109*cda5da8dSAndroid Build Coastguard Worker sw(msg.message, msg.category, msg.filename, msg.lineno, 110*cda5da8dSAndroid Build Coastguard Worker msg.file, msg.line) 111*cda5da8dSAndroid Build Coastguard Worker return 112*cda5da8dSAndroid Build Coastguard Worker _showwarnmsg_impl(msg) 113*cda5da8dSAndroid Build Coastguard Worker 114*cda5da8dSAndroid Build Coastguard Worker# Keep a reference to check if the function was replaced 115*cda5da8dSAndroid Build Coastguard Worker_formatwarning_orig = formatwarning 116*cda5da8dSAndroid Build Coastguard Worker 117*cda5da8dSAndroid Build Coastguard Workerdef _formatwarnmsg(msg): 118*cda5da8dSAndroid Build Coastguard Worker """Function to format a warning the standard way.""" 119*cda5da8dSAndroid Build Coastguard Worker try: 120*cda5da8dSAndroid Build Coastguard Worker fw = formatwarning 121*cda5da8dSAndroid Build Coastguard Worker except NameError: 122*cda5da8dSAndroid Build Coastguard Worker pass 123*cda5da8dSAndroid Build Coastguard Worker else: 124*cda5da8dSAndroid Build Coastguard Worker if fw is not _formatwarning_orig: 125*cda5da8dSAndroid Build Coastguard Worker # warnings.formatwarning() was replaced 126*cda5da8dSAndroid Build Coastguard Worker return fw(msg.message, msg.category, 127*cda5da8dSAndroid Build Coastguard Worker msg.filename, msg.lineno, msg.line) 128*cda5da8dSAndroid Build Coastguard Worker return _formatwarnmsg_impl(msg) 129*cda5da8dSAndroid Build Coastguard Worker 130*cda5da8dSAndroid Build Coastguard Workerdef filterwarnings(action, message="", category=Warning, module="", lineno=0, 131*cda5da8dSAndroid Build Coastguard Worker append=False): 132*cda5da8dSAndroid Build Coastguard Worker """Insert an entry into the list of warnings filters (at the front). 133*cda5da8dSAndroid Build Coastguard Worker 134*cda5da8dSAndroid Build Coastguard Worker 'action' -- one of "error", "ignore", "always", "default", "module", 135*cda5da8dSAndroid Build Coastguard Worker or "once" 136*cda5da8dSAndroid Build Coastguard Worker 'message' -- a regex that the warning message must match 137*cda5da8dSAndroid Build Coastguard Worker 'category' -- a class that the warning must be a subclass of 138*cda5da8dSAndroid Build Coastguard Worker 'module' -- a regex that the module name must match 139*cda5da8dSAndroid Build Coastguard Worker 'lineno' -- an integer line number, 0 matches all warnings 140*cda5da8dSAndroid Build Coastguard Worker 'append' -- if true, append to the list of filters 141*cda5da8dSAndroid Build Coastguard Worker """ 142*cda5da8dSAndroid Build Coastguard Worker assert action in ("error", "ignore", "always", "default", "module", 143*cda5da8dSAndroid Build Coastguard Worker "once"), "invalid action: %r" % (action,) 144*cda5da8dSAndroid Build Coastguard Worker assert isinstance(message, str), "message must be a string" 145*cda5da8dSAndroid Build Coastguard Worker assert isinstance(category, type), "category must be a class" 146*cda5da8dSAndroid Build Coastguard Worker assert issubclass(category, Warning), "category must be a Warning subclass" 147*cda5da8dSAndroid Build Coastguard Worker assert isinstance(module, str), "module must be a string" 148*cda5da8dSAndroid Build Coastguard Worker assert isinstance(lineno, int) and lineno >= 0, \ 149*cda5da8dSAndroid Build Coastguard Worker "lineno must be an int >= 0" 150*cda5da8dSAndroid Build Coastguard Worker 151*cda5da8dSAndroid Build Coastguard Worker if message or module: 152*cda5da8dSAndroid Build Coastguard Worker import re 153*cda5da8dSAndroid Build Coastguard Worker 154*cda5da8dSAndroid Build Coastguard Worker if message: 155*cda5da8dSAndroid Build Coastguard Worker message = re.compile(message, re.I) 156*cda5da8dSAndroid Build Coastguard Worker else: 157*cda5da8dSAndroid Build Coastguard Worker message = None 158*cda5da8dSAndroid Build Coastguard Worker if module: 159*cda5da8dSAndroid Build Coastguard Worker module = re.compile(module) 160*cda5da8dSAndroid Build Coastguard Worker else: 161*cda5da8dSAndroid Build Coastguard Worker module = None 162*cda5da8dSAndroid Build Coastguard Worker 163*cda5da8dSAndroid Build Coastguard Worker _add_filter(action, message, category, module, lineno, append=append) 164*cda5da8dSAndroid Build Coastguard Worker 165*cda5da8dSAndroid Build Coastguard Workerdef simplefilter(action, category=Warning, lineno=0, append=False): 166*cda5da8dSAndroid Build Coastguard Worker """Insert a simple entry into the list of warnings filters (at the front). 167*cda5da8dSAndroid Build Coastguard Worker 168*cda5da8dSAndroid Build Coastguard Worker A simple filter matches all modules and messages. 169*cda5da8dSAndroid Build Coastguard Worker 'action' -- one of "error", "ignore", "always", "default", "module", 170*cda5da8dSAndroid Build Coastguard Worker or "once" 171*cda5da8dSAndroid Build Coastguard Worker 'category' -- a class that the warning must be a subclass of 172*cda5da8dSAndroid Build Coastguard Worker 'lineno' -- an integer line number, 0 matches all warnings 173*cda5da8dSAndroid Build Coastguard Worker 'append' -- if true, append to the list of filters 174*cda5da8dSAndroid Build Coastguard Worker """ 175*cda5da8dSAndroid Build Coastguard Worker assert action in ("error", "ignore", "always", "default", "module", 176*cda5da8dSAndroid Build Coastguard Worker "once"), "invalid action: %r" % (action,) 177*cda5da8dSAndroid Build Coastguard Worker assert isinstance(lineno, int) and lineno >= 0, \ 178*cda5da8dSAndroid Build Coastguard Worker "lineno must be an int >= 0" 179*cda5da8dSAndroid Build Coastguard Worker _add_filter(action, None, category, None, lineno, append=append) 180*cda5da8dSAndroid Build Coastguard Worker 181*cda5da8dSAndroid Build Coastguard Workerdef _add_filter(*item, append): 182*cda5da8dSAndroid Build Coastguard Worker # Remove possible duplicate filters, so new one will be placed 183*cda5da8dSAndroid Build Coastguard Worker # in correct place. If append=True and duplicate exists, do nothing. 184*cda5da8dSAndroid Build Coastguard Worker if not append: 185*cda5da8dSAndroid Build Coastguard Worker try: 186*cda5da8dSAndroid Build Coastguard Worker filters.remove(item) 187*cda5da8dSAndroid Build Coastguard Worker except ValueError: 188*cda5da8dSAndroid Build Coastguard Worker pass 189*cda5da8dSAndroid Build Coastguard Worker filters.insert(0, item) 190*cda5da8dSAndroid Build Coastguard Worker else: 191*cda5da8dSAndroid Build Coastguard Worker if item not in filters: 192*cda5da8dSAndroid Build Coastguard Worker filters.append(item) 193*cda5da8dSAndroid Build Coastguard Worker _filters_mutated() 194*cda5da8dSAndroid Build Coastguard Worker 195*cda5da8dSAndroid Build Coastguard Workerdef resetwarnings(): 196*cda5da8dSAndroid Build Coastguard Worker """Clear the list of warning filters, so that no filters are active.""" 197*cda5da8dSAndroid Build Coastguard Worker filters[:] = [] 198*cda5da8dSAndroid Build Coastguard Worker _filters_mutated() 199*cda5da8dSAndroid Build Coastguard Worker 200*cda5da8dSAndroid Build Coastguard Workerclass _OptionError(Exception): 201*cda5da8dSAndroid Build Coastguard Worker """Exception used by option processing helpers.""" 202*cda5da8dSAndroid Build Coastguard Worker pass 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Worker# Helper to process -W options passed via sys.warnoptions 205*cda5da8dSAndroid Build Coastguard Workerdef _processoptions(args): 206*cda5da8dSAndroid Build Coastguard Worker for arg in args: 207*cda5da8dSAndroid Build Coastguard Worker try: 208*cda5da8dSAndroid Build Coastguard Worker _setoption(arg) 209*cda5da8dSAndroid Build Coastguard Worker except _OptionError as msg: 210*cda5da8dSAndroid Build Coastguard Worker print("Invalid -W option ignored:", msg, file=sys.stderr) 211*cda5da8dSAndroid Build Coastguard Worker 212*cda5da8dSAndroid Build Coastguard Worker# Helper for _processoptions() 213*cda5da8dSAndroid Build Coastguard Workerdef _setoption(arg): 214*cda5da8dSAndroid Build Coastguard Worker parts = arg.split(':') 215*cda5da8dSAndroid Build Coastguard Worker if len(parts) > 5: 216*cda5da8dSAndroid Build Coastguard Worker raise _OptionError("too many fields (max 5): %r" % (arg,)) 217*cda5da8dSAndroid Build Coastguard Worker while len(parts) < 5: 218*cda5da8dSAndroid Build Coastguard Worker parts.append('') 219*cda5da8dSAndroid Build Coastguard Worker action, message, category, module, lineno = [s.strip() 220*cda5da8dSAndroid Build Coastguard Worker for s in parts] 221*cda5da8dSAndroid Build Coastguard Worker action = _getaction(action) 222*cda5da8dSAndroid Build Coastguard Worker category = _getcategory(category) 223*cda5da8dSAndroid Build Coastguard Worker if message or module: 224*cda5da8dSAndroid Build Coastguard Worker import re 225*cda5da8dSAndroid Build Coastguard Worker if message: 226*cda5da8dSAndroid Build Coastguard Worker message = re.escape(message) 227*cda5da8dSAndroid Build Coastguard Worker if module: 228*cda5da8dSAndroid Build Coastguard Worker module = re.escape(module) + r'\Z' 229*cda5da8dSAndroid Build Coastguard Worker if lineno: 230*cda5da8dSAndroid Build Coastguard Worker try: 231*cda5da8dSAndroid Build Coastguard Worker lineno = int(lineno) 232*cda5da8dSAndroid Build Coastguard Worker if lineno < 0: 233*cda5da8dSAndroid Build Coastguard Worker raise ValueError 234*cda5da8dSAndroid Build Coastguard Worker except (ValueError, OverflowError): 235*cda5da8dSAndroid Build Coastguard Worker raise _OptionError("invalid lineno %r" % (lineno,)) from None 236*cda5da8dSAndroid Build Coastguard Worker else: 237*cda5da8dSAndroid Build Coastguard Worker lineno = 0 238*cda5da8dSAndroid Build Coastguard Worker filterwarnings(action, message, category, module, lineno) 239*cda5da8dSAndroid Build Coastguard Worker 240*cda5da8dSAndroid Build Coastguard Worker# Helper for _setoption() 241*cda5da8dSAndroid Build Coastguard Workerdef _getaction(action): 242*cda5da8dSAndroid Build Coastguard Worker if not action: 243*cda5da8dSAndroid Build Coastguard Worker return "default" 244*cda5da8dSAndroid Build Coastguard Worker if action == "all": return "always" # Alias 245*cda5da8dSAndroid Build Coastguard Worker for a in ('default', 'always', 'ignore', 'module', 'once', 'error'): 246*cda5da8dSAndroid Build Coastguard Worker if a.startswith(action): 247*cda5da8dSAndroid Build Coastguard Worker return a 248*cda5da8dSAndroid Build Coastguard Worker raise _OptionError("invalid action: %r" % (action,)) 249*cda5da8dSAndroid Build Coastguard Worker 250*cda5da8dSAndroid Build Coastguard Worker# Helper for _setoption() 251*cda5da8dSAndroid Build Coastguard Workerdef _getcategory(category): 252*cda5da8dSAndroid Build Coastguard Worker if not category: 253*cda5da8dSAndroid Build Coastguard Worker return Warning 254*cda5da8dSAndroid Build Coastguard Worker if '.' not in category: 255*cda5da8dSAndroid Build Coastguard Worker import builtins as m 256*cda5da8dSAndroid Build Coastguard Worker klass = category 257*cda5da8dSAndroid Build Coastguard Worker else: 258*cda5da8dSAndroid Build Coastguard Worker module, _, klass = category.rpartition('.') 259*cda5da8dSAndroid Build Coastguard Worker try: 260*cda5da8dSAndroid Build Coastguard Worker m = __import__(module, None, None, [klass]) 261*cda5da8dSAndroid Build Coastguard Worker except ImportError: 262*cda5da8dSAndroid Build Coastguard Worker raise _OptionError("invalid module name: %r" % (module,)) from None 263*cda5da8dSAndroid Build Coastguard Worker try: 264*cda5da8dSAndroid Build Coastguard Worker cat = getattr(m, klass) 265*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 266*cda5da8dSAndroid Build Coastguard Worker raise _OptionError("unknown warning category: %r" % (category,)) from None 267*cda5da8dSAndroid Build Coastguard Worker if not issubclass(cat, Warning): 268*cda5da8dSAndroid Build Coastguard Worker raise _OptionError("invalid warning category: %r" % (category,)) 269*cda5da8dSAndroid Build Coastguard Worker return cat 270*cda5da8dSAndroid Build Coastguard Worker 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard Workerdef _is_internal_frame(frame): 273*cda5da8dSAndroid Build Coastguard Worker """Signal whether the frame is an internal CPython implementation detail.""" 274*cda5da8dSAndroid Build Coastguard Worker filename = frame.f_code.co_filename 275*cda5da8dSAndroid Build Coastguard Worker return 'importlib' in filename and '_bootstrap' in filename 276*cda5da8dSAndroid Build Coastguard Worker 277*cda5da8dSAndroid Build Coastguard Worker 278*cda5da8dSAndroid Build Coastguard Workerdef _next_external_frame(frame): 279*cda5da8dSAndroid Build Coastguard Worker """Find the next frame that doesn't involve CPython internals.""" 280*cda5da8dSAndroid Build Coastguard Worker frame = frame.f_back 281*cda5da8dSAndroid Build Coastguard Worker while frame is not None and _is_internal_frame(frame): 282*cda5da8dSAndroid Build Coastguard Worker frame = frame.f_back 283*cda5da8dSAndroid Build Coastguard Worker return frame 284*cda5da8dSAndroid Build Coastguard Worker 285*cda5da8dSAndroid Build Coastguard Worker 286*cda5da8dSAndroid Build Coastguard Worker# Code typically replaced by _warnings 287*cda5da8dSAndroid Build Coastguard Workerdef warn(message, category=None, stacklevel=1, source=None): 288*cda5da8dSAndroid Build Coastguard Worker """Issue a warning, or maybe ignore it or raise an exception.""" 289*cda5da8dSAndroid Build Coastguard Worker # Check if message is already a Warning object 290*cda5da8dSAndroid Build Coastguard Worker if isinstance(message, Warning): 291*cda5da8dSAndroid Build Coastguard Worker category = message.__class__ 292*cda5da8dSAndroid Build Coastguard Worker # Check category argument 293*cda5da8dSAndroid Build Coastguard Worker if category is None: 294*cda5da8dSAndroid Build Coastguard Worker category = UserWarning 295*cda5da8dSAndroid Build Coastguard Worker if not (isinstance(category, type) and issubclass(category, Warning)): 296*cda5da8dSAndroid Build Coastguard Worker raise TypeError("category must be a Warning subclass, " 297*cda5da8dSAndroid Build Coastguard Worker "not '{:s}'".format(type(category).__name__)) 298*cda5da8dSAndroid Build Coastguard Worker # Get context information 299*cda5da8dSAndroid Build Coastguard Worker try: 300*cda5da8dSAndroid Build Coastguard Worker if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)): 301*cda5da8dSAndroid Build Coastguard Worker # If frame is too small to care or if the warning originated in 302*cda5da8dSAndroid Build Coastguard Worker # internal code, then do not try to hide any frames. 303*cda5da8dSAndroid Build Coastguard Worker frame = sys._getframe(stacklevel) 304*cda5da8dSAndroid Build Coastguard Worker else: 305*cda5da8dSAndroid Build Coastguard Worker frame = sys._getframe(1) 306*cda5da8dSAndroid Build Coastguard Worker # Look for one frame less since the above line starts us off. 307*cda5da8dSAndroid Build Coastguard Worker for x in range(stacklevel-1): 308*cda5da8dSAndroid Build Coastguard Worker frame = _next_external_frame(frame) 309*cda5da8dSAndroid Build Coastguard Worker if frame is None: 310*cda5da8dSAndroid Build Coastguard Worker raise ValueError 311*cda5da8dSAndroid Build Coastguard Worker except ValueError: 312*cda5da8dSAndroid Build Coastguard Worker globals = sys.__dict__ 313*cda5da8dSAndroid Build Coastguard Worker filename = "sys" 314*cda5da8dSAndroid Build Coastguard Worker lineno = 1 315*cda5da8dSAndroid Build Coastguard Worker else: 316*cda5da8dSAndroid Build Coastguard Worker globals = frame.f_globals 317*cda5da8dSAndroid Build Coastguard Worker filename = frame.f_code.co_filename 318*cda5da8dSAndroid Build Coastguard Worker lineno = frame.f_lineno 319*cda5da8dSAndroid Build Coastguard Worker if '__name__' in globals: 320*cda5da8dSAndroid Build Coastguard Worker module = globals['__name__'] 321*cda5da8dSAndroid Build Coastguard Worker else: 322*cda5da8dSAndroid Build Coastguard Worker module = "<string>" 323*cda5da8dSAndroid Build Coastguard Worker registry = globals.setdefault("__warningregistry__", {}) 324*cda5da8dSAndroid Build Coastguard Worker warn_explicit(message, category, filename, lineno, module, registry, 325*cda5da8dSAndroid Build Coastguard Worker globals, source) 326*cda5da8dSAndroid Build Coastguard Worker 327*cda5da8dSAndroid Build Coastguard Workerdef warn_explicit(message, category, filename, lineno, 328*cda5da8dSAndroid Build Coastguard Worker module=None, registry=None, module_globals=None, 329*cda5da8dSAndroid Build Coastguard Worker source=None): 330*cda5da8dSAndroid Build Coastguard Worker lineno = int(lineno) 331*cda5da8dSAndroid Build Coastguard Worker if module is None: 332*cda5da8dSAndroid Build Coastguard Worker module = filename or "<unknown>" 333*cda5da8dSAndroid Build Coastguard Worker if module[-3:].lower() == ".py": 334*cda5da8dSAndroid Build Coastguard Worker module = module[:-3] # XXX What about leading pathname? 335*cda5da8dSAndroid Build Coastguard Worker if registry is None: 336*cda5da8dSAndroid Build Coastguard Worker registry = {} 337*cda5da8dSAndroid Build Coastguard Worker if registry.get('version', 0) != _filters_version: 338*cda5da8dSAndroid Build Coastguard Worker registry.clear() 339*cda5da8dSAndroid Build Coastguard Worker registry['version'] = _filters_version 340*cda5da8dSAndroid Build Coastguard Worker if isinstance(message, Warning): 341*cda5da8dSAndroid Build Coastguard Worker text = str(message) 342*cda5da8dSAndroid Build Coastguard Worker category = message.__class__ 343*cda5da8dSAndroid Build Coastguard Worker else: 344*cda5da8dSAndroid Build Coastguard Worker text = message 345*cda5da8dSAndroid Build Coastguard Worker message = category(message) 346*cda5da8dSAndroid Build Coastguard Worker key = (text, category, lineno) 347*cda5da8dSAndroid Build Coastguard Worker # Quick test for common case 348*cda5da8dSAndroid Build Coastguard Worker if registry.get(key): 349*cda5da8dSAndroid Build Coastguard Worker return 350*cda5da8dSAndroid Build Coastguard Worker # Search the filters 351*cda5da8dSAndroid Build Coastguard Worker for item in filters: 352*cda5da8dSAndroid Build Coastguard Worker action, msg, cat, mod, ln = item 353*cda5da8dSAndroid Build Coastguard Worker if ((msg is None or msg.match(text)) and 354*cda5da8dSAndroid Build Coastguard Worker issubclass(category, cat) and 355*cda5da8dSAndroid Build Coastguard Worker (mod is None or mod.match(module)) and 356*cda5da8dSAndroid Build Coastguard Worker (ln == 0 or lineno == ln)): 357*cda5da8dSAndroid Build Coastguard Worker break 358*cda5da8dSAndroid Build Coastguard Worker else: 359*cda5da8dSAndroid Build Coastguard Worker action = defaultaction 360*cda5da8dSAndroid Build Coastguard Worker # Early exit actions 361*cda5da8dSAndroid Build Coastguard Worker if action == "ignore": 362*cda5da8dSAndroid Build Coastguard Worker return 363*cda5da8dSAndroid Build Coastguard Worker 364*cda5da8dSAndroid Build Coastguard Worker # Prime the linecache for formatting, in case the 365*cda5da8dSAndroid Build Coastguard Worker # "file" is actually in a zipfile or something. 366*cda5da8dSAndroid Build Coastguard Worker import linecache 367*cda5da8dSAndroid Build Coastguard Worker linecache.getlines(filename, module_globals) 368*cda5da8dSAndroid Build Coastguard Worker 369*cda5da8dSAndroid Build Coastguard Worker if action == "error": 370*cda5da8dSAndroid Build Coastguard Worker raise message 371*cda5da8dSAndroid Build Coastguard Worker # Other actions 372*cda5da8dSAndroid Build Coastguard Worker if action == "once": 373*cda5da8dSAndroid Build Coastguard Worker registry[key] = 1 374*cda5da8dSAndroid Build Coastguard Worker oncekey = (text, category) 375*cda5da8dSAndroid Build Coastguard Worker if onceregistry.get(oncekey): 376*cda5da8dSAndroid Build Coastguard Worker return 377*cda5da8dSAndroid Build Coastguard Worker onceregistry[oncekey] = 1 378*cda5da8dSAndroid Build Coastguard Worker elif action == "always": 379*cda5da8dSAndroid Build Coastguard Worker pass 380*cda5da8dSAndroid Build Coastguard Worker elif action == "module": 381*cda5da8dSAndroid Build Coastguard Worker registry[key] = 1 382*cda5da8dSAndroid Build Coastguard Worker altkey = (text, category, 0) 383*cda5da8dSAndroid Build Coastguard Worker if registry.get(altkey): 384*cda5da8dSAndroid Build Coastguard Worker return 385*cda5da8dSAndroid Build Coastguard Worker registry[altkey] = 1 386*cda5da8dSAndroid Build Coastguard Worker elif action == "default": 387*cda5da8dSAndroid Build Coastguard Worker registry[key] = 1 388*cda5da8dSAndroid Build Coastguard Worker else: 389*cda5da8dSAndroid Build Coastguard Worker # Unrecognized actions are errors 390*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError( 391*cda5da8dSAndroid Build Coastguard Worker "Unrecognized action (%r) in warnings.filters:\n %s" % 392*cda5da8dSAndroid Build Coastguard Worker (action, item)) 393*cda5da8dSAndroid Build Coastguard Worker # Print message and context 394*cda5da8dSAndroid Build Coastguard Worker msg = WarningMessage(message, category, filename, lineno, source) 395*cda5da8dSAndroid Build Coastguard Worker _showwarnmsg(msg) 396*cda5da8dSAndroid Build Coastguard Worker 397*cda5da8dSAndroid Build Coastguard Worker 398*cda5da8dSAndroid Build Coastguard Workerclass WarningMessage(object): 399*cda5da8dSAndroid Build Coastguard Worker 400*cda5da8dSAndroid Build Coastguard Worker _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", 401*cda5da8dSAndroid Build Coastguard Worker "line", "source") 402*cda5da8dSAndroid Build Coastguard Worker 403*cda5da8dSAndroid Build Coastguard Worker def __init__(self, message, category, filename, lineno, file=None, 404*cda5da8dSAndroid Build Coastguard Worker line=None, source=None): 405*cda5da8dSAndroid Build Coastguard Worker self.message = message 406*cda5da8dSAndroid Build Coastguard Worker self.category = category 407*cda5da8dSAndroid Build Coastguard Worker self.filename = filename 408*cda5da8dSAndroid Build Coastguard Worker self.lineno = lineno 409*cda5da8dSAndroid Build Coastguard Worker self.file = file 410*cda5da8dSAndroid Build Coastguard Worker self.line = line 411*cda5da8dSAndroid Build Coastguard Worker self.source = source 412*cda5da8dSAndroid Build Coastguard Worker self._category_name = category.__name__ if category else None 413*cda5da8dSAndroid Build Coastguard Worker 414*cda5da8dSAndroid Build Coastguard Worker def __str__(self): 415*cda5da8dSAndroid Build Coastguard Worker return ("{message : %r, category : %r, filename : %r, lineno : %s, " 416*cda5da8dSAndroid Build Coastguard Worker "line : %r}" % (self.message, self._category_name, 417*cda5da8dSAndroid Build Coastguard Worker self.filename, self.lineno, self.line)) 418*cda5da8dSAndroid Build Coastguard Worker 419*cda5da8dSAndroid Build Coastguard Worker 420*cda5da8dSAndroid Build Coastguard Workerclass catch_warnings(object): 421*cda5da8dSAndroid Build Coastguard Worker 422*cda5da8dSAndroid Build Coastguard Worker """A context manager that copies and restores the warnings filter upon 423*cda5da8dSAndroid Build Coastguard Worker exiting the context. 424*cda5da8dSAndroid Build Coastguard Worker 425*cda5da8dSAndroid Build Coastguard Worker The 'record' argument specifies whether warnings should be captured by a 426*cda5da8dSAndroid Build Coastguard Worker custom implementation of warnings.showwarning() and be appended to a list 427*cda5da8dSAndroid Build Coastguard Worker returned by the context manager. Otherwise None is returned by the context 428*cda5da8dSAndroid Build Coastguard Worker manager. The objects appended to the list are arguments whose attributes 429*cda5da8dSAndroid Build Coastguard Worker mirror the arguments to showwarning(). 430*cda5da8dSAndroid Build Coastguard Worker 431*cda5da8dSAndroid Build Coastguard Worker The 'module' argument is to specify an alternative module to the module 432*cda5da8dSAndroid Build Coastguard Worker named 'warnings' and imported under that name. This argument is only useful 433*cda5da8dSAndroid Build Coastguard Worker when testing the warnings module itself. 434*cda5da8dSAndroid Build Coastguard Worker 435*cda5da8dSAndroid Build Coastguard Worker If the 'action' argument is not None, the remaining arguments are passed 436*cda5da8dSAndroid Build Coastguard Worker to warnings.simplefilter() as if it were called immediately on entering the 437*cda5da8dSAndroid Build Coastguard Worker context. 438*cda5da8dSAndroid Build Coastguard Worker """ 439*cda5da8dSAndroid Build Coastguard Worker 440*cda5da8dSAndroid Build Coastguard Worker def __init__(self, *, record=False, module=None, 441*cda5da8dSAndroid Build Coastguard Worker action=None, category=Warning, lineno=0, append=False): 442*cda5da8dSAndroid Build Coastguard Worker """Specify whether to record warnings and if an alternative module 443*cda5da8dSAndroid Build Coastguard Worker should be used other than sys.modules['warnings']. 444*cda5da8dSAndroid Build Coastguard Worker 445*cda5da8dSAndroid Build Coastguard Worker For compatibility with Python 3.0, please consider all arguments to be 446*cda5da8dSAndroid Build Coastguard Worker keyword-only. 447*cda5da8dSAndroid Build Coastguard Worker 448*cda5da8dSAndroid Build Coastguard Worker """ 449*cda5da8dSAndroid Build Coastguard Worker self._record = record 450*cda5da8dSAndroid Build Coastguard Worker self._module = sys.modules['warnings'] if module is None else module 451*cda5da8dSAndroid Build Coastguard Worker self._entered = False 452*cda5da8dSAndroid Build Coastguard Worker if action is None: 453*cda5da8dSAndroid Build Coastguard Worker self._filter = None 454*cda5da8dSAndroid Build Coastguard Worker else: 455*cda5da8dSAndroid Build Coastguard Worker self._filter = (action, category, lineno, append) 456*cda5da8dSAndroid Build Coastguard Worker 457*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 458*cda5da8dSAndroid Build Coastguard Worker args = [] 459*cda5da8dSAndroid Build Coastguard Worker if self._record: 460*cda5da8dSAndroid Build Coastguard Worker args.append("record=True") 461*cda5da8dSAndroid Build Coastguard Worker if self._module is not sys.modules['warnings']: 462*cda5da8dSAndroid Build Coastguard Worker args.append("module=%r" % self._module) 463*cda5da8dSAndroid Build Coastguard Worker name = type(self).__name__ 464*cda5da8dSAndroid Build Coastguard Worker return "%s(%s)" % (name, ", ".join(args)) 465*cda5da8dSAndroid Build Coastguard Worker 466*cda5da8dSAndroid Build Coastguard Worker def __enter__(self): 467*cda5da8dSAndroid Build Coastguard Worker if self._entered: 468*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("Cannot enter %r twice" % self) 469*cda5da8dSAndroid Build Coastguard Worker self._entered = True 470*cda5da8dSAndroid Build Coastguard Worker self._filters = self._module.filters 471*cda5da8dSAndroid Build Coastguard Worker self._module.filters = self._filters[:] 472*cda5da8dSAndroid Build Coastguard Worker self._module._filters_mutated() 473*cda5da8dSAndroid Build Coastguard Worker self._showwarning = self._module.showwarning 474*cda5da8dSAndroid Build Coastguard Worker self._showwarnmsg_impl = self._module._showwarnmsg_impl 475*cda5da8dSAndroid Build Coastguard Worker if self._filter is not None: 476*cda5da8dSAndroid Build Coastguard Worker simplefilter(*self._filter) 477*cda5da8dSAndroid Build Coastguard Worker if self._record: 478*cda5da8dSAndroid Build Coastguard Worker log = [] 479*cda5da8dSAndroid Build Coastguard Worker self._module._showwarnmsg_impl = log.append 480*cda5da8dSAndroid Build Coastguard Worker # Reset showwarning() to the default implementation to make sure 481*cda5da8dSAndroid Build Coastguard Worker # that _showwarnmsg() calls _showwarnmsg_impl() 482*cda5da8dSAndroid Build Coastguard Worker self._module.showwarning = self._module._showwarning_orig 483*cda5da8dSAndroid Build Coastguard Worker return log 484*cda5da8dSAndroid Build Coastguard Worker else: 485*cda5da8dSAndroid Build Coastguard Worker return None 486*cda5da8dSAndroid Build Coastguard Worker 487*cda5da8dSAndroid Build Coastguard Worker def __exit__(self, *exc_info): 488*cda5da8dSAndroid Build Coastguard Worker if not self._entered: 489*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError("Cannot exit %r without entering first" % self) 490*cda5da8dSAndroid Build Coastguard Worker self._module.filters = self._filters 491*cda5da8dSAndroid Build Coastguard Worker self._module._filters_mutated() 492*cda5da8dSAndroid Build Coastguard Worker self._module.showwarning = self._showwarning 493*cda5da8dSAndroid Build Coastguard Worker self._module._showwarnmsg_impl = self._showwarnmsg_impl 494*cda5da8dSAndroid Build Coastguard Worker 495*cda5da8dSAndroid Build Coastguard Worker 496*cda5da8dSAndroid Build Coastguard Worker_DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}" 497*cda5da8dSAndroid Build Coastguard Worker 498*cda5da8dSAndroid Build Coastguard Workerdef _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info): 499*cda5da8dSAndroid Build Coastguard Worker """Warn that *name* is deprecated or should be removed. 500*cda5da8dSAndroid Build Coastguard Worker 501*cda5da8dSAndroid Build Coastguard Worker RuntimeError is raised if *remove* specifies a major/minor tuple older than 502*cda5da8dSAndroid Build Coastguard Worker the current Python version or the same version but past the alpha. 503*cda5da8dSAndroid Build Coastguard Worker 504*cda5da8dSAndroid Build Coastguard Worker The *message* argument is formatted with *name* and *remove* as a Python 505*cda5da8dSAndroid Build Coastguard Worker version (e.g. "3.11"). 506*cda5da8dSAndroid Build Coastguard Worker 507*cda5da8dSAndroid Build Coastguard Worker """ 508*cda5da8dSAndroid Build Coastguard Worker remove_formatted = f"{remove[0]}.{remove[1]}" 509*cda5da8dSAndroid Build Coastguard Worker if (_version[:2] > remove) or (_version[:2] == remove and _version[3] != "alpha"): 510*cda5da8dSAndroid Build Coastguard Worker msg = f"{name!r} was slated for removal after Python {remove_formatted} alpha" 511*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError(msg) 512*cda5da8dSAndroid Build Coastguard Worker else: 513*cda5da8dSAndroid Build Coastguard Worker msg = message.format(name=name, remove=remove_formatted) 514*cda5da8dSAndroid Build Coastguard Worker warn(msg, DeprecationWarning, stacklevel=3) 515*cda5da8dSAndroid Build Coastguard Worker 516*cda5da8dSAndroid Build Coastguard Worker 517*cda5da8dSAndroid Build Coastguard Worker# Private utility function called by _PyErr_WarnUnawaitedCoroutine 518*cda5da8dSAndroid Build Coastguard Workerdef _warn_unawaited_coroutine(coro): 519*cda5da8dSAndroid Build Coastguard Worker msg_lines = [ 520*cda5da8dSAndroid Build Coastguard Worker f"coroutine '{coro.__qualname__}' was never awaited\n" 521*cda5da8dSAndroid Build Coastguard Worker ] 522*cda5da8dSAndroid Build Coastguard Worker if coro.cr_origin is not None: 523*cda5da8dSAndroid Build Coastguard Worker import linecache, traceback 524*cda5da8dSAndroid Build Coastguard Worker def extract(): 525*cda5da8dSAndroid Build Coastguard Worker for filename, lineno, funcname in reversed(coro.cr_origin): 526*cda5da8dSAndroid Build Coastguard Worker line = linecache.getline(filename, lineno) 527*cda5da8dSAndroid Build Coastguard Worker yield (filename, lineno, funcname, line) 528*cda5da8dSAndroid Build Coastguard Worker msg_lines.append("Coroutine created at (most recent call last)\n") 529*cda5da8dSAndroid Build Coastguard Worker msg_lines += traceback.format_list(list(extract())) 530*cda5da8dSAndroid Build Coastguard Worker msg = "".join(msg_lines).rstrip("\n") 531*cda5da8dSAndroid Build Coastguard Worker # Passing source= here means that if the user happens to have tracemalloc 532*cda5da8dSAndroid Build Coastguard Worker # enabled and tracking where the coroutine was created, the warning will 533*cda5da8dSAndroid Build Coastguard Worker # contain that traceback. This does mean that if they have *both* 534*cda5da8dSAndroid Build Coastguard Worker # coroutine origin tracking *and* tracemalloc enabled, they'll get two 535*cda5da8dSAndroid Build Coastguard Worker # partially-redundant tracebacks. If we wanted to be clever we could 536*cda5da8dSAndroid Build Coastguard Worker # probably detect this case and avoid it, but for now we don't bother. 537*cda5da8dSAndroid Build Coastguard Worker warn(msg, category=RuntimeWarning, stacklevel=2, source=coro) 538*cda5da8dSAndroid Build Coastguard Worker 539*cda5da8dSAndroid Build Coastguard Worker 540*cda5da8dSAndroid Build Coastguard Worker# filters contains a sequence of filter 5-tuples 541*cda5da8dSAndroid Build Coastguard Worker# The components of the 5-tuple are: 542*cda5da8dSAndroid Build Coastguard Worker# - an action: error, ignore, always, default, module, or once 543*cda5da8dSAndroid Build Coastguard Worker# - a compiled regex that must match the warning message 544*cda5da8dSAndroid Build Coastguard Worker# - a class representing the warning category 545*cda5da8dSAndroid Build Coastguard Worker# - a compiled regex that must match the module that is being warned 546*cda5da8dSAndroid Build Coastguard Worker# - a line number for the line being warning, or 0 to mean any line 547*cda5da8dSAndroid Build Coastguard Worker# If either if the compiled regexs are None, match anything. 548*cda5da8dSAndroid Build Coastguard Workertry: 549*cda5da8dSAndroid Build Coastguard Worker from _warnings import (filters, _defaultaction, _onceregistry, 550*cda5da8dSAndroid Build Coastguard Worker warn, warn_explicit, _filters_mutated) 551*cda5da8dSAndroid Build Coastguard Worker defaultaction = _defaultaction 552*cda5da8dSAndroid Build Coastguard Worker onceregistry = _onceregistry 553*cda5da8dSAndroid Build Coastguard Worker _warnings_defaults = True 554*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 555*cda5da8dSAndroid Build Coastguard Worker filters = [] 556*cda5da8dSAndroid Build Coastguard Worker defaultaction = "default" 557*cda5da8dSAndroid Build Coastguard Worker onceregistry = {} 558*cda5da8dSAndroid Build Coastguard Worker 559*cda5da8dSAndroid Build Coastguard Worker _filters_version = 1 560*cda5da8dSAndroid Build Coastguard Worker 561*cda5da8dSAndroid Build Coastguard Worker def _filters_mutated(): 562*cda5da8dSAndroid Build Coastguard Worker global _filters_version 563*cda5da8dSAndroid Build Coastguard Worker _filters_version += 1 564*cda5da8dSAndroid Build Coastguard Worker 565*cda5da8dSAndroid Build Coastguard Worker _warnings_defaults = False 566*cda5da8dSAndroid Build Coastguard Worker 567*cda5da8dSAndroid Build Coastguard Worker 568*cda5da8dSAndroid Build Coastguard Worker# Module initialization 569*cda5da8dSAndroid Build Coastguard Worker_processoptions(sys.warnoptions) 570*cda5da8dSAndroid Build Coastguard Workerif not _warnings_defaults: 571*cda5da8dSAndroid Build Coastguard Worker # Several warning categories are ignored by default in regular builds 572*cda5da8dSAndroid Build Coastguard Worker if not hasattr(sys, 'gettotalrefcount'): 573*cda5da8dSAndroid Build Coastguard Worker filterwarnings("default", category=DeprecationWarning, 574*cda5da8dSAndroid Build Coastguard Worker module="__main__", append=1) 575*cda5da8dSAndroid Build Coastguard Worker simplefilter("ignore", category=DeprecationWarning, append=1) 576*cda5da8dSAndroid Build Coastguard Worker simplefilter("ignore", category=PendingDeprecationWarning, append=1) 577*cda5da8dSAndroid Build Coastguard Worker simplefilter("ignore", category=ImportWarning, append=1) 578*cda5da8dSAndroid Build Coastguard Worker simplefilter("ignore", category=ResourceWarning, append=1) 579*cda5da8dSAndroid Build Coastguard Worker 580*cda5da8dSAndroid Build Coastguard Workerdel _warnings_defaults 581