ai-content-maker/.venv/Lib/site-packages/numba/misc/numba_gdbinfo.py

162 lines
5.8 KiB
Python
Raw Normal View History

2024-05-03 04:18:51 +03:00
"""Module for displaying information about Numba's gdb set up"""
from collections import namedtuple
import os
import re
import subprocess
from textwrap import dedent
from numba import config
# Container for the output of the gdb info data collection
_fields = ('binary_loc, extension_loc, py_ver, np_ver, supported')
_gdb_info = namedtuple('_gdb_info', _fields)
class _GDBTestWrapper():
"""Wraps the gdb binary and has methods for checking what the gdb binary
has support for (Python and NumPy)."""
def __init__(self,):
gdb_binary = config.GDB_BINARY
if gdb_binary is None:
msg = ("No valid binary could be found for gdb named: "
f"{config.GDB_BINARY}")
raise ValueError(msg)
self._gdb_binary = gdb_binary
def _run_cmd(self, cmd=()):
gdb_call = [self.gdb_binary, '-q',]
for x in cmd:
gdb_call.append('-ex')
gdb_call.append(x)
gdb_call.extend(['-ex', 'q'])
return subprocess.run(gdb_call, capture_output=True, timeout=10,
text=True)
@property
def gdb_binary(self):
return self._gdb_binary
@classmethod
def success(cls, status):
return status.returncode == 0
def check_launch(self):
"""Checks that gdb will launch ok"""
return self._run_cmd()
def check_python(self):
cmd = ("python from __future__ import print_function; "
"import sys; print(sys.version_info[:2])")
return self._run_cmd((cmd,))
def check_numpy(self):
cmd = ("python from __future__ import print_function; "
"import types; import numpy; "
"print(isinstance(numpy, types.ModuleType))")
return self._run_cmd((cmd,))
def check_numpy_version(self):
cmd = ("python from __future__ import print_function; "
"import types; import numpy;"
"print(numpy.__version__)")
return self._run_cmd((cmd,))
def collect_gdbinfo():
"""Prints information to stdout about the gdb setup that Numba has found"""
# State flags:
gdb_state = None
gdb_has_python = False
gdb_has_numpy = False
gdb_python_version = 'No Python support'
gdb_python_numpy_version = "No NumPy support"
# There are so many ways for gdb to not be working as expected. Surround
# the "is it working" tests with try/except and if there's an exception
# store it for processing later.
try:
# Check gdb exists
gdb_wrapper = _GDBTestWrapper()
# Check gdb works
status = gdb_wrapper.check_launch()
if not gdb_wrapper.success(status):
msg = (f"gdb at '{gdb_wrapper.gdb_binary}' does not appear to work."
f"\nstdout: {status.stdout}\nstderr: {status.stderr}")
raise ValueError(msg)
gdb_state = gdb_wrapper.gdb_binary
except Exception as e:
gdb_state = f"Testing gdb binary failed. Reported Error: {e}"
else:
# Got this far, so gdb works, start checking what it supports
status = gdb_wrapper.check_python()
if gdb_wrapper.success(status):
version_match = re.match(r'\((\d+),\s+(\d+)\)',
status.stdout.strip())
if version_match is not None:
pymajor, pyminor = version_match.groups()
gdb_python_version = f"{pymajor}.{pyminor}"
gdb_has_python = True
status = gdb_wrapper.check_numpy()
if gdb_wrapper.success(status):
if "Traceback" not in status.stderr.strip():
if status.stdout.strip() == 'True':
gdb_has_numpy = True
gdb_python_numpy_version = "Unknown"
# NumPy is present find the version
status = gdb_wrapper.check_numpy_version()
if gdb_wrapper.success(status):
if "Traceback" not in status.stderr.strip():
gdb_python_numpy_version = \
status.stdout.strip()
# Work out what level of print-extension support is present in this gdb
if gdb_has_python:
if gdb_has_numpy:
print_ext_supported = "Full (Python and NumPy supported)"
else:
print_ext_supported = "Partial (Python only, no NumPy support)"
else:
print_ext_supported = "None"
# Work out print ext location
print_ext_file = "gdb_print_extension.py"
print_ext_path = os.path.join(os.path.dirname(__file__), print_ext_file)
# return!
return _gdb_info(gdb_state, print_ext_path, gdb_python_version,
gdb_python_numpy_version, print_ext_supported)
def display_gdbinfo(sep_pos=45):
"""Displays the information collected by collect_gdbinfo.
"""
gdb_info = collect_gdbinfo()
print('-' * 80)
fmt = f'%-{sep_pos}s : %-s'
# Display the information
print(fmt % ("Binary location", gdb_info.binary_loc))
print(fmt % ("Print extension location", gdb_info.extension_loc))
print(fmt % ("Python version", gdb_info.py_ver))
print(fmt % ("NumPy version", gdb_info.np_ver))
print(fmt % ("Numba printing extension support", gdb_info.supported))
print("")
print("To load the Numba gdb printing extension, execute the following "
"from the gdb prompt:")
print(f"\nsource {gdb_info.extension_loc}\n")
print('-' * 80)
warn = """
=============================================================
IMPORTANT: Before sharing you should remove any information
in the above that you wish to keep private e.g. paths.
=============================================================
"""
print(dedent(warn))
if __name__ == '__main__':
display_gdbinfo()