gdb libpython.py: Remove compatibility code (#105739)

Remove compatibility code for Python 2 and early Python 3 versions.

* Remove os_fsencode() reimplementation: use os.fsencode() directly.
  os.fsencode() was added to Python 3.2.
* Remove references to Python 2 and "Python 3": just say "Python".
* Remove outdated u'' string format: use '' instead.
This commit is contained in:
Victor Stinner 2023-06-14 12:30:22 +02:00 committed by GitHub
parent e5d45b7444
commit 0316063031
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -111,26 +111,6 @@ def safe_range(val):
# threshold in case the data was corrupted
return range(safety_limit(int(val)))
try:
os_fsencode = os.fsencode
except AttributeError:
def os_fsencode(filename):
if not isinstance(filename, unicode):
return filename
encoding = sys.getfilesystemencoding()
if encoding == 'mbcs':
# mbcs doesn't support surrogateescape
return filename.encode(encoding)
encoded = []
for char in filename:
# surrogateescape error handler
if 0xDC80 <= ord(char) <= 0xDCFF:
byte = chr(ord(char) - 0xDC00)
else:
byte = char.encode(encoding)
encoded.append(byte)
return ''.join(encoded)
class StringTruncated(RuntimeError):
pass
@ -174,16 +154,12 @@ def __init__(self, gdbval, cast_to=None):
def field(self, name):
'''
Get the gdb.Value for the given field within the PyObject, coping with
some python 2 versus python 3 differences.
Get the gdb.Value for the given field within the PyObject.
Various libpython types are defined using the "PyObject_HEAD" and
"PyObject_VAR_HEAD" macros.
In Python 2, this these are defined so that "ob_type" and (for a var
object) "ob_size" are fields of the type in question.
In Python 3, this is defined as an embedded PyVarObject type thus:
In Python, this is defined as an embedded PyVarObject type thus:
PyVarObject ob_base;
so that the "ob_size" field is located insize the "ob_base" field, and
the "ob_type" is most easily accessed by casting back to a (PyObject*).
@ -204,8 +180,7 @@ def field(self, name):
def pyop_field(self, name):
'''
Get a PyObjectPtr for the given PyObject* field within this PyObject,
coping with some python 2 versus python 3 differences.
Get a PyObjectPtr for the given PyObject* field within this PyObject.
'''
return PyObjectPtr.from_pyobject_ptr(self.field(name))
@ -924,7 +899,7 @@ def proxyval(self, visited):
return result
def write_repr(self, out, visited):
# Write this out as a Python 3 int literal, i.e. without the "L" suffix
# Write this out as a Python int literal
proxy = self.proxyval(visited)
out.write("%s" % proxy)
@ -1170,7 +1145,7 @@ def current_line(self):
filename = self.filename()
try:
with open(os_fsencode(filename), 'r', encoding="utf-8") as fp:
with open(os.fsencode(filename), 'r', encoding="utf-8") as fp:
lines = fp.readlines()
except IOError:
return None
@ -1263,7 +1238,7 @@ def proxyval(self, visited):
return set(members)
def write_repr(self, out, visited):
# Emulate Python 3's set_repr
# Emulate Python's set_repr
tp_name = self.safe_tp_name()
# Guard against infinite loops:
@ -1272,13 +1247,13 @@ def write_repr(self, out, visited):
return
visited.add(self.as_address())
# Python 3's set_repr special-cases the empty set:
# Python's set_repr special-cases the empty set:
if not self.field('used'):
out.write(tp_name)
out.write('()')
return
# Python 3 uses {} for set literals:
# Python uses {} for set literals:
if tp_name != 'set':
out.write(tp_name)
out.write('(')
@ -1309,13 +1284,13 @@ def proxyval(self, visited):
return str(self)
def write_repr(self, out, visited):
# Write this out as a Python 3 bytes literal, i.e. with a "b" prefix
# Write this out as a Python bytes literal, i.e. with a "b" prefix
# Get a PyStringObject* within the Python 2 gdb process:
# Get a PyStringObject* within the Python gdb process:
proxy = self.proxyval(visited)
# Transliteration of Python 3's Objects/bytesobject.c:PyBytes_Repr
# to Python 2 code:
# Transliteration of Python's Objects/bytesobject.c:PyBytes_Repr
# to Python code:
quote = "'"
if "'" in proxy and not '"' in proxy:
quote = '"'
@ -1380,7 +1355,7 @@ class PyTypeObjectPtr(PyObjectPtr):
def _unichr_is_printable(char):
# Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
# Logic adapted from Python's Tools/unicode/makeunicodedata.py
if char == u" ":
return True
import unicodedata
@ -1416,17 +1391,17 @@ def proxyval(self, visited):
# Convert the int code points to unicode characters, and generate a
# local unicode instance.
result = u''.join(map(chr, code_points))
result = ''.join(map(chr, code_points))
return result
def write_repr(self, out, visited):
# Write this out as a Python 3 str literal, i.e. without a "u" prefix
# Write this out as a Python str literal
# Get a PyUnicodeObject* within the Python 2 gdb process:
# Get a PyUnicodeObject* within the Python gdb process:
proxy = self.proxyval(visited)
# Transliteration of Python 3's Object/unicodeobject.c:unicode_repr
# to Python 2:
# Transliteration of Python's Object/unicodeobject.c:unicode_repr
# to Python:
if "'" in proxy and '"' not in proxy:
quote = '"'
else:
@ -1477,7 +1452,7 @@ def write_repr(self, out, visited):
# (categories Z* and C* except ASCII space)
if not printable:
if ch2 is not None:
# Match Python 3's representation of non-printable
# Match Python's representation of non-printable
# wide characters.
code = (ord(ch) & 0x03FF) << 10
code |= ord(ch2) & 0x03FF
@ -1608,8 +1583,8 @@ def pretty_printer_lookup(gdbval):
if the code is autoloaded by gdb when visiting libpython.so, provided
that this python file is installed to the same path as the library (or its
.debug file) plus a "-gdb.py" suffix, e.g:
/usr/lib/libpython2.6.so.1.0-gdb.py
/usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
/usr/lib/libpython3.12.so.1.0-gdb.py
/usr/lib/debug/usr/lib/libpython3.12.so.1.0.debug-gdb.py
"""
def register (obj):
if obj is None:
@ -1928,7 +1903,7 @@ def invoke(self, args, from_tty):
start = 1
try:
f = open(os_fsencode(filename), 'r', encoding="utf-8")
f = open(os.fsencode(filename), 'r', encoding="utf-8")
except IOError as err:
sys.stdout.write('Unable to open %s: %s\n'
% (filename, err))