Skip to content

Commit 9fca76c

Browse files
[gdb] Complete stubs for gdb.dap (#14269)
1 parent 138a54b commit 9fca76c

24 files changed

+571
-34
lines changed

stubs/gdb/@tests/stubtest_allowlist.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,3 @@ gdb.Progspace.xmethods
7373

7474
# stubtest thinks this can't be sub-classed at runtime, but it is
7575
gdb.disassembler.DisassemblerPart
76-
77-
# incomplete modules
78-
gdb\.dap\.[a-z_]+\.[A-Za-z_]+

stubs/gdb/gdb/__init__.pyi

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import threading
77
from _typeshed import Incomplete
88
from collections.abc import Callable, Iterator, Mapping, Sequence
99
from contextlib import AbstractContextManager
10-
from typing import Any, Final, Generic, Literal, Protocol, TypeVar, final, overload, type_check_only
10+
from typing import Any, Final, Generic, Literal, Protocol, TypedDict, TypeVar, final, overload, type_check_only
1111
from typing_extensions import TypeAlias, deprecated
1212

1313
import gdb.FrameDecorator
@@ -860,10 +860,16 @@ class LazyString:
860860

861861
# Architectures
862862

863+
@type_check_only
864+
class _Instruction(TypedDict):
865+
addr: int
866+
asm: str
867+
length: int
868+
863869
@final
864870
class Architecture:
865871
def name(self) -> str: ...
866-
def disassemble(self, start_pc: int, end_pc: int = ..., count: int = ...) -> list[dict[str, object]]: ...
872+
def disassemble(self, start_pc: int, end_pc: int = ..., count: int = ...) -> list[_Instruction]: ...
867873
def integer_type(self, size: int, signed: bool = ...) -> Type: ...
868874
def registers(self, reggroup: str = ...) -> RegisterDescriptorIterator: ...
869875
def register_groups(self) -> RegisterGroupsIterator: ...

stubs/gdb/gdb/dap/__init__.pyi

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
from typing import Any
2-
3-
class Server:
4-
def __init__(self, in_stream, out_stream, child_stream) -> None: ...
5-
def main_loop(self) -> None: ...
6-
def send_event(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object
7-
def send_event_later(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object
8-
def shutdown(self) -> None: ...
1+
from . import (
2+
breakpoint as breakpoint,
3+
bt as bt,
4+
evaluate as evaluate,
5+
launch as launch,
6+
locations as locations,
7+
memory as memory,
8+
modules as modules,
9+
next as next,
10+
pause as pause,
11+
scopes as scopes,
12+
sources as sources,
13+
startup as startup,
14+
threads as threads,
15+
)
16+
from .server import Server as Server
917

1018
def pre_command_loop() -> None: ...
1119
def run() -> None: ...

stubs/gdb/gdb/dap/breakpoint.pyi

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,49 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
from _typeshed import Incomplete, Unused
2+
from collections.abc import Sequence
3+
from contextlib import AbstractContextManager
4+
from typing import TypedDict, type_check_only
5+
from typing_extensions import NotRequired
6+
7+
import gdb
8+
9+
from .sources import Source
10+
11+
@type_check_only
12+
class _SourceBreakpoint(TypedDict):
13+
source: str
14+
line: int
15+
condition: NotRequired[str | None]
16+
hitCondition: NotRequired[str | None]
17+
logMessage: NotRequired[str | None]
18+
19+
@type_check_only
20+
class _ExceptionFilterOptions(TypedDict):
21+
filderId: str
22+
condition: NotRequired[str | None]
23+
24+
@type_check_only
25+
class _BreakpointDescriptor(TypedDict):
26+
id: int
27+
verified: bool
28+
reason: NotRequired[str] # only present when verified is False. Possibly only literal "pending" or "failed"
29+
message: NotRequired[str] # only present when reason == "failed"
30+
source: NotRequired[Source]
31+
line: NotRequired[int]
32+
instructionReference: NotRequired[str]
33+
34+
@type_check_only
35+
class _SetBreakpointResult(TypedDict):
36+
breakpoints: list[_BreakpointDescriptor]
37+
38+
# frozenset entries are tuples from _SourceBreakpoint.items() or _ExceptionFilterOptions.items()
39+
breakpoint_map: dict[str, dict[frozenset[Incomplete], gdb.Breakpoint]]
40+
41+
def suppress_new_breakpoint_event() -> AbstractContextManager[None]: ...
42+
def set_breakpoint(*, source: Source, breakpoints: Sequence[_SourceBreakpoint] = (), **args: Unused) -> _SetBreakpointResult: ...
43+
def set_fn_breakpoint(*, breakpoints: Sequence[_SourceBreakpoint], **args: Unused) -> _SetBreakpointResult: ...
44+
def set_insn_breakpoints(
45+
*, breakpoints: Sequence[_SourceBreakpoint], offset: int | None = None, **args: Unused
46+
) -> _SetBreakpointResult: ...
47+
def set_exception_breakpoints(
48+
*, filters: Sequence[str], filterOptions: Sequence[_ExceptionFilterOptions] = (), **args: Unused
49+
) -> _SetBreakpointResult: ...

stubs/gdb/gdb/dap/bt.pyi

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,49 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
from _typeshed import Unused
2+
from typing import TypedDict, type_check_only
3+
from typing_extensions import NotRequired
4+
5+
from .sources import Source
6+
from .varref import _ValueFormat
7+
8+
@type_check_only
9+
class _StackFrameFormat(_ValueFormat, total=False):
10+
parameters: bool
11+
parameterTypes: bool
12+
parameterNames: bool
13+
parameterValues: bool
14+
line: bool
15+
module: bool
16+
includeAll: bool
17+
18+
@type_check_only
19+
class _StackFrame(TypedDict):
20+
id: int
21+
name: str
22+
line: int
23+
column: int
24+
instructionPointerReference: str
25+
moduleId: NotRequired[str | None]
26+
source: NotRequired[Source]
27+
28+
@type_check_only
29+
class _StackTraceResult(TypedDict):
30+
stackFrames: list[_StackFrame]
31+
32+
def check_stack_frame(
33+
*,
34+
# From source:
35+
# Note that StackFrameFormat extends ValueFormat, which is why
36+
# "hex" appears here.
37+
hex: bool = False,
38+
parameters: bool = False,
39+
parameterTypes: bool = False,
40+
parameterNames: bool = False,
41+
parameterValues: bool = False,
42+
line: bool = False,
43+
module: bool = False,
44+
includeAll: bool = False,
45+
**rest: Unused,
46+
) -> _StackFrameFormat: ...
47+
def stacktrace(
48+
*, levels: int = 0, startFrame: int = 0, threadId: int, format: _StackFrameFormat | None = None, **extra: Unused
49+
) -> _StackTraceResult: ...

stubs/gdb/gdb/dap/disassemble.pyi

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,22 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
from _typeshed import Unused
2+
from typing import TypedDict, type_check_only
3+
from typing_extensions import NotRequired
4+
5+
from .sources import Source
6+
7+
@type_check_only
8+
class _Instruction(TypedDict):
9+
address: str
10+
instruction: str
11+
instructionBytes: str
12+
symbol: NotRequired[str] # only set if there's a corresponding label
13+
line: NotRequired[int] # only set if source is available
14+
location: NotRequired[Source] # only set if source is available
15+
16+
@type_check_only
17+
class _DisassembleResult(TypedDict):
18+
instructions: list[_Instruction]
19+
20+
def disassemble(
21+
*, memoryReference: str, offset: int = 0, instructionOffset: int = 0, instructionCount: int, **extra: Unused
22+
) -> _DisassembleResult: ...

stubs/gdb/gdb/dap/evaluate.pyi

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,31 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
from _typeshed import Unused
2+
from typing import Literal, TypedDict, type_check_only
3+
4+
import gdb
5+
6+
from .varref import VariableReference, _ValueFormat, _VariableReferenceDescriptor
7+
8+
class EvaluateResult(VariableReference):
9+
def __init__(self, value: gdb.Value) -> None: ...
10+
11+
@type_check_only
12+
class _VariablesResult(TypedDict):
13+
variables: list[_VariableReferenceDescriptor]
14+
15+
def eval_request(
16+
*,
17+
expression: str,
18+
frameId: int | None = None,
19+
context: Literal["watch", "variables", "hover", "repl"] = "variables",
20+
format: _ValueFormat | None = None,
21+
**args: Unused,
22+
) -> _VariableReferenceDescriptor: ...
23+
def variables(
24+
*, variablesReference: int, start: int = 0, count: int = 0, format: _ValueFormat | None = None, **args: Unused
25+
) -> _VariablesResult: ...
26+
def set_expression(
27+
*, expression: str, value: str, frameId: int | None = None, format: _ValueFormat | None = None, **args: Unused
28+
) -> _VariableReferenceDescriptor: ...
29+
def set_variable(
30+
*, variablesReference: int, name: str, value: str, format: _ValueFormat | None = None, **args: Unused
31+
) -> _VariableReferenceDescriptor: ...

stubs/gdb/gdb/dap/events.pyi

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
import gdb
2+
3+
inferior_running: bool
4+
5+
def send_process_event_once() -> None: ...
6+
def expect_process(reason: str) -> None: ...
7+
def thread_event(event: gdb.ThreadEvent, reason: str) -> None: ...
8+
def expect_stop(reason: str) -> None: ...
9+
def exec_and_expect_stop(cmd: str, expected_pause: bool = False) -> None: ...
10+
11+
# Map from gdb stop reasons to DAP stop reasons.
12+
stop_reason_map: dict[str, str]

stubs/gdb/gdb/dap/frames.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
from collections.abc import Generator
2+
3+
import gdb
4+
5+
def frame_for_id(id: int) -> gdb.Frame: ...
6+
def select_frame(id: int) -> None: ...
7+
def dap_frame_generator(frame_low: int, levels: int, include_all: bool) -> Generator[tuple[int, gdb.Frame]]: ...

stubs/gdb/gdb/dap/io.pyi

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
1-
def __getattr__(name: str): ... # incomplete module
1+
from _typeshed import SupportsFlush, SupportsRead, SupportsReadline, SupportsWrite
2+
from typing import Any, type_check_only
3+
4+
import gdb
5+
6+
from .server import _JSONValue
7+
from .startup import DAPQueue
8+
9+
@type_check_only
10+
class _SupportsReadAndReadlineBytes(SupportsRead[bytes], SupportsReadline[bytes]): ...
11+
12+
@type_check_only
13+
class _SupportsWriteAndFlushBytes(SupportsWrite[bytes], SupportsFlush): ...
14+
15+
def read_json(stream: _SupportsReadAndReadlineBytes) -> Any: ... # returns result of json.loads
16+
def start_json_writer(stream: _SupportsWriteAndFlushBytes, queue: DAPQueue[_JSONValue]) -> gdb.Thread: ...

0 commit comments

Comments
 (0)