mirror of
https://github.com/davidhalter/typeshed.git
synced 2025-12-07 20:54:28 +08:00
Run gdb stubtests (#11644)
The gdb package is only available inside gdb and cannot be installed externally through e.g. pip. Run the stubtest inside gdb.
This commit is contained in:
119
stubs/gdb/@tests/stubtest_allowlist.txt
Normal file
119
stubs/gdb/@tests/stubtest_allowlist.txt
Normal file
@@ -0,0 +1,119 @@
|
||||
# TODO: Update types in stub
|
||||
# This list includes everything to allow initial stubtests to run in gdb's environment
|
||||
gdb.BP_NONE
|
||||
gdb.Breakpoint.stop
|
||||
gdb.BreakpointEvent
|
||||
gdb.ClearObjFilesEvent
|
||||
gdb.Command.complete
|
||||
gdb.Command.invoke
|
||||
gdb.ConnectionEvent
|
||||
gdb.ContinueEvent
|
||||
gdb.DUMMY_FRAME
|
||||
gdb.Event
|
||||
gdb.EventRegistry
|
||||
gdb.ExitedEvent
|
||||
gdb.FRAME_UNWIND_FIRST_ERROR
|
||||
gdb.FinishBreakpoint.out_of_scope
|
||||
gdb.Function.invoke
|
||||
gdb.GdbExitingEvent
|
||||
gdb.GdbSetPythonDirectory
|
||||
gdb.HOST_CONFIG
|
||||
gdb.Inferior.connection
|
||||
gdb.Inferior.thread_from_thread_handle
|
||||
gdb.InferiorCallPostEvent
|
||||
gdb.InferiorCallPreEvent
|
||||
gdb.InferiorDeletedEvent
|
||||
gdb.InferiorThread.details
|
||||
gdb.Instruction
|
||||
gdb.LazyString
|
||||
gdb.LineTable.__next__
|
||||
gdb.LineTable.is_valid
|
||||
gdb.LineTable.source_lines
|
||||
gdb.LineTable.source_lnes
|
||||
gdb.LineTableIterator
|
||||
gdb.MICommand.invoke
|
||||
gdb.Membuf
|
||||
gdb.MemoryChangedEvent
|
||||
gdb.NewInferiorEvent
|
||||
gdb.NewObjFileEvent
|
||||
gdb.NewThreadEvent
|
||||
gdb.Objfile.frame_unwinders
|
||||
gdb.Objfile.lookup_static_method
|
||||
gdb.Objfile.lookup_static_symbol
|
||||
gdb.Objfile.xmethods
|
||||
gdb.Parameter.get_set_string
|
||||
gdb.Parameter.get_show_string
|
||||
gdb.Progspace.frame_unwinders
|
||||
gdb.Progspace.xmethods
|
||||
gdb.Record
|
||||
gdb.RecordFunctionSegment
|
||||
gdb.RecordGap
|
||||
gdb.RecordInstruction
|
||||
gdb.RegisterChangedEvent
|
||||
gdb.RegisterDescriptor
|
||||
gdb.RegisterDescriptorIterator
|
||||
gdb.RegisterGroup
|
||||
gdb.RegisterGroupsIterator
|
||||
gdb.RemoteTargetConnection
|
||||
gdb.SYMBOL_FUNCTIONS_DOMAIN
|
||||
gdb.SYMBOL_TYPES_DOMAIN
|
||||
gdb.SYMBOL_VARIABLES_DOMAIN
|
||||
gdb.SignalEvent
|
||||
gdb.StopEvent
|
||||
gdb.TARGET_CONFIG
|
||||
gdb.ThreadEvent
|
||||
gdb.TuiWindow
|
||||
gdb.Type.__contains__
|
||||
gdb.Type.get
|
||||
gdb.Type.has_key
|
||||
gdb.Type.is_scalar
|
||||
gdb.Type.is_signed
|
||||
gdb.Type.items
|
||||
gdb.Type.iteritems
|
||||
gdb.Type.iterkeys
|
||||
gdb.Type.itervalues
|
||||
gdb.Type.keys
|
||||
gdb.Type.values
|
||||
gdb.TypeIterator
|
||||
gdb.Unwinder
|
||||
gdb.Value.rvalue_reference_value
|
||||
gdb.frame_filters
|
||||
gdb.frame_unwinders
|
||||
gdb.packages
|
||||
gdb.prompt_hook
|
||||
gdb.type_printers
|
||||
gdb.xmethods
|
||||
gdb.events
|
||||
gdb.printing.RegexpCollectionPrettyPrinter.RegexpSubprinter
|
||||
gdb.printing.add_builtin_pretty_printer
|
||||
gdb.prompt.prompt_help
|
||||
gdb.prompt.prompt_substitutions
|
||||
gdb.types.TypePrinter.instantiate
|
||||
gdb.unwinder.Unwinder
|
||||
gdb.xmethod.SimpleXMethodMatcher
|
||||
gdb.xmethod.XMethodMatcher.match
|
||||
gdb.xmethod.XMethodWorker.__call__
|
||||
gdb.xmethod.XMethodWorker.get_arg_types
|
||||
gdb.xmethod.XMethodWorker.get_result_type
|
||||
gdb.FrameDecorator
|
||||
gdb.FrameIterator
|
||||
gdb.command
|
||||
gdb.command.explore
|
||||
gdb.command.frame_filters
|
||||
gdb.command.pretty_printers
|
||||
gdb.command.prompt
|
||||
gdb.command.type_printers
|
||||
gdb.command.unwinders
|
||||
gdb.command.xmethods
|
||||
gdb.frames
|
||||
gdb.function
|
||||
gdb.function.as_string
|
||||
gdb.function.caller_is
|
||||
gdb.function.strfns
|
||||
gdb.printer
|
||||
gdb.printer.bound_registers
|
||||
gdb.printing.basestring
|
||||
gdb.printing.long
|
||||
gdb.xmethod.basestring
|
||||
gdb.xmethod.long
|
||||
gdb.styling
|
||||
@@ -11,6 +11,5 @@ extra_description = """\
|
||||
"""
|
||||
|
||||
[tool.stubtest]
|
||||
# Since the "gdb" Python package is available only inside GDB, it is not
|
||||
# possible to install it through pip, so stub tests cannot install it.
|
||||
skip = true
|
||||
platforms = ["linux"]
|
||||
apt_dependencies = ["gdb"]
|
||||
|
||||
@@ -73,6 +73,12 @@ def run_stubtest(
|
||||
# TODO: Maybe find a way to cache these in CI
|
||||
dists_to_install = [dist_req, get_mypy_req()]
|
||||
dists_to_install.extend(requirements.external_pkgs) # Internal requirements are added to MYPYPATH
|
||||
|
||||
# Since the "gdb" Python package is available only inside GDB, it is not
|
||||
# possible to install it through pip, so stub tests cannot install it.
|
||||
if dist_name == "gdb":
|
||||
dists_to_install[:] = dists_to_install[1:]
|
||||
|
||||
pip_cmd = [pip_exe, "install", *dists_to_install]
|
||||
try:
|
||||
subprocess.run(pip_cmd, check=True, capture_output=True)
|
||||
@@ -118,6 +124,10 @@ def run_stubtest(
|
||||
if not setup_uwsgi_stubtest_command(dist, venv_dir, stubtest_cmd):
|
||||
return False
|
||||
|
||||
if dist_name == "gdb":
|
||||
if not setup_gdb_stubtest_command(venv_dir, stubtest_cmd):
|
||||
return False
|
||||
|
||||
try:
|
||||
subprocess.run(stubtest_cmd, env=stubtest_env, check=True, capture_output=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
@@ -153,6 +163,88 @@ def run_stubtest(
|
||||
return True
|
||||
|
||||
|
||||
def setup_gdb_stubtest_command(venv_dir: Path, stubtest_cmd: list[str]) -> bool:
|
||||
"""
|
||||
Use wrapper scripts to run stubtest inside gdb.
|
||||
The wrapper script is used to pass the arguments to the gdb script.
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
print_error("gdb is not supported on Windows")
|
||||
return False
|
||||
|
||||
try:
|
||||
gdb_version = subprocess.check_output(["gdb", "--version"], text=True, stderr=subprocess.STDOUT)
|
||||
except FileNotFoundError:
|
||||
print_error("gdb is not installed")
|
||||
return False
|
||||
if "Python scripting is not supported in this copy of GDB" in gdb_version:
|
||||
print_error("Python scripting is not supported in this copy of GDB")
|
||||
return False
|
||||
|
||||
gdb_script = venv_dir / "gdb_stubtest.py"
|
||||
wrapper_script = venv_dir / "gdb_wrapper.py"
|
||||
gdb_script_contents = dedent(
|
||||
f"""
|
||||
import json
|
||||
import os
|
||||
import site
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from glob import glob
|
||||
|
||||
# Add the venv site-packages to sys.path. gdb doesn't use the virtual environment.
|
||||
# Taken from https://github.com/pwndbg/pwndbg/blob/83d8d95b576b749e888f533ce927ad5a77fb957b/gdbinit.py#L37
|
||||
site_pkgs_path = glob(os.path.join({str(venv_dir)!r}, "lib/*/site-packages"))[0]
|
||||
site.addsitedir(site_pkgs_path)
|
||||
|
||||
exit_code = 1
|
||||
try:
|
||||
# gdb wraps stdout and stderr without a .fileno
|
||||
# colored output in mypy tries to access .fileno()
|
||||
sys.stdout.fileno = sys.__stdout__.fileno
|
||||
sys.stderr.fileno = sys.__stderr__.fileno
|
||||
|
||||
from mypy.stubtest import main
|
||||
|
||||
sys.argv = json.loads(os.environ.get("STUBTEST_ARGS"))
|
||||
exit_code = main()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
gdb.execute(f"quit {{exit_code}}")
|
||||
"""
|
||||
)
|
||||
gdb_script.write_text(gdb_script_contents)
|
||||
|
||||
wrapper_script_contents = dedent(
|
||||
f"""
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
stubtest_env = os.environ | {{"STUBTEST_ARGS": json.dumps(sys.argv)}}
|
||||
gdb_cmd = [
|
||||
"gdb",
|
||||
"--quiet",
|
||||
"--nx",
|
||||
"--batch",
|
||||
"--command",
|
||||
{str(gdb_script)!r},
|
||||
]
|
||||
r = subprocess.run(gdb_cmd, env=stubtest_env)
|
||||
sys.exit(r.returncode)
|
||||
"""
|
||||
)
|
||||
wrapper_script.write_text(wrapper_script_contents)
|
||||
|
||||
# replace "-m mypy.stubtest" in stubtest_cmd with the path to our wrapper script
|
||||
assert stubtest_cmd[1:3] == ["-m", "mypy.stubtest"]
|
||||
stubtest_cmd[1:3] = [str(wrapper_script)]
|
||||
return True
|
||||
|
||||
|
||||
def setup_uwsgi_stubtest_command(dist: Path, venv_dir: Path, stubtest_cmd: list[str]) -> bool:
|
||||
"""Perform some black magic in order to run stubtest inside uWSGI.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user