From 924ecc71f64e63f9e1d5044ef5016fafb730d4c2 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Thu, 8 Jun 2023 17:52:21 +0530 Subject: [PATCH] chore: vendor cgitb (#21288) To Avoid: ``` /home/ankush/benches/develop/apps/frappe/frappe/utils/error.py:4: DeprecationWarning: 'cgitb' is deprecated and slated for removal in Python 3.13 import cgitb ``` --- frappe/utils/error.py | 58 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/frappe/utils/error.py b/frappe/utils/error.py index 2c450750e1..47c5b055a8 100644 --- a/frappe/utils/error.py +++ b/frappe/utils/error.py @@ -1,7 +1,6 @@ # Copyright (c) 2015, Maxwell Morais and contributors # License: MIT. See LICENSE -import cgitb import datetime import functools import inspect @@ -103,7 +102,7 @@ def get_snapshot(exception, context=10): finally: lnum[0] += 1 - vars = cgitb.scanvars(reader, frame, locals) + vars = _scanvars(reader, frame, locals) # if it is a view, replace with generated code # if file.endswith('html'): @@ -123,7 +122,7 @@ def get_snapshot(exception, context=10): for name, where, value in vars: if name in f["dump"]: continue - if value is not cgitb.__UNDEF__: + if value is not __UNDEF__: if where == "global": name = f"global {name:s}" elif where != "local": @@ -257,3 +256,56 @@ def raise_error_on_no_output(error_message, error_type=None, keep_quiet=None): return wrapper_raise_error_on_no_output return decorator_raise_error_on_no_output + + +# Vendored from cgitb standard library reused under PSF License: +# https://github.com/python/cpython/blob/main/LICENSE + + +import keyword +import tokenize + +__UNDEF__ = [] # a special sentinel object + + +def _scanvars(reader, frame, locals): + """Scan one logical line of Python and look up values of variables used.""" + vars, lasttoken, parent, prefix, value = [], None, None, "", __UNDEF__ + for ttype, token, start, end, line in tokenize.generate_tokens(reader): + if ttype == tokenize.NEWLINE: + break + if ttype == tokenize.NAME and token not in keyword.kwlist: + if lasttoken == ".": + if parent is not __UNDEF__: + value = getattr(parent, token, __UNDEF__) + vars.append((prefix + token, prefix, value)) + else: + where, value = _lookup(token, frame, locals) + vars.append((token, where, value)) + elif token == ".": + prefix += lasttoken + "." + parent = value + else: + parent, prefix = None, "" + lasttoken = token + return vars + + +def _lookup(name, frame, locals): + """Find the value for a given name in the given environment.""" + if name in locals: + return "local", locals[name] + if name in frame.f_globals: + return "global", frame.f_globals[name] + if "__builtins__" in frame.f_globals: + builtins = frame.f_globals["__builtins__"] + if type(builtins) is type({}): # noqa + if name in builtins: + return "builtin", builtins[name] + else: + if hasattr(builtins, name): + return "builtin", getattr(builtins, name) + return None, __UNDEF__ + + +# end: vendored code