From f9e1a12487ae96e42ccbaaef6c14ae9807ada822 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Wed, 11 Jun 2025 10:24:32 -0400 Subject: [PATCH 1/5] [gdb] Complete `gdb.dap` stubs --- stubs/gdb/@tests/stubtest_allowlist.txt | 3 -- stubs/gdb/gdb/__init__.pyi | 10 +++- stubs/gdb/gdb/dap/__init__.pyi | 23 ++++++--- stubs/gdb/gdb/dap/breakpoint.pyi | 51 ++++++++++++++++++- stubs/gdb/gdb/dap/bt.pyi | 45 ++++++++++++++++- stubs/gdb/gdb/dap/disassemble.pyi | 16 +++++- stubs/gdb/gdb/dap/evaluate.pyi | 31 +++++++++++- stubs/gdb/gdb/dap/events.pyi | 13 ++++- stubs/gdb/gdb/dap/frames.pyi | 8 ++- stubs/gdb/gdb/dap/io.pyi | 11 ++++- stubs/gdb/gdb/dap/launch.pyi | 16 +++++- stubs/gdb/gdb/dap/locations.pyi | 16 +++++- stubs/gdb/gdb/dap/memory.pyi | 12 ++++- stubs/gdb/gdb/dap/modules.pyi | 21 +++++++- stubs/gdb/gdb/dap/next.pyi | 17 ++++++- stubs/gdb/gdb/dap/pause.pyi | 2 +- stubs/gdb/gdb/dap/scopes.pyi | 46 ++++++++++++++++- stubs/gdb/gdb/dap/server.pyi | 61 ++++++++++++++++++++++- stubs/gdb/gdb/dap/sources.pyi | 24 ++++++++- stubs/gdb/gdb/dap/startup.pyi | 45 ++++++++++++++++- stubs/gdb/gdb/dap/state.pyi | 2 +- stubs/gdb/gdb/dap/threads.pyi | 14 +++++- stubs/gdb/gdb/dap/typecheck.pyi | 7 ++- stubs/gdb/gdb/dap/varref.pyi | 65 ++++++++++++++++++++++++- 24 files changed, 525 insertions(+), 34 deletions(-) diff --git a/stubs/gdb/@tests/stubtest_allowlist.txt b/stubs/gdb/@tests/stubtest_allowlist.txt index 22017ab0580c..45f7643f08c2 100644 --- a/stubs/gdb/@tests/stubtest_allowlist.txt +++ b/stubs/gdb/@tests/stubtest_allowlist.txt @@ -73,6 +73,3 @@ gdb.Progspace.xmethods # stubtest thinks this can't be sub-classed at runtime, but it is gdb.disassembler.DisassemblerPart - -# incomplete modules -gdb\.dap\.[a-z_]+\.[A-Za-z_]+ diff --git a/stubs/gdb/gdb/__init__.pyi b/stubs/gdb/gdb/__init__.pyi index 12e35708e867..45980500debc 100644 --- a/stubs/gdb/gdb/__init__.pyi +++ b/stubs/gdb/gdb/__init__.pyi @@ -7,7 +7,7 @@ import threading from _typeshed import Incomplete from collections.abc import Callable, Iterator, Mapping, Sequence from contextlib import AbstractContextManager -from typing import Any, Final, Generic, Literal, Protocol, TypeVar, final, overload, type_check_only +from typing import Any, Final, Generic, Literal, Protocol, TypedDict, TypeVar, final, overload, type_check_only from typing_extensions import TypeAlias, deprecated import gdb.FrameDecorator @@ -860,10 +860,16 @@ class LazyString: # Architectures +@type_check_only +class _Instruction(TypedDict): + addr: int + asm: str + length: int + @final class Architecture: def name(self) -> str: ... - def disassemble(self, start_pc: int, end_pc: int = ..., count: int = ...) -> list[dict[str, object]]: ... + def disassemble(self, start_pc: int, end_pc: int = ..., count: int = ...) -> list[_Instruction]: ... def integer_type(self, size: int, signed: bool = ...) -> Type: ... def registers(self, reggroup: str = ...) -> RegisterDescriptorIterator: ... def register_groups(self) -> RegisterGroupsIterator: ... diff --git a/stubs/gdb/gdb/dap/__init__.pyi b/stubs/gdb/gdb/dap/__init__.pyi index 2eb66f91e63a..30c6318d0228 100644 --- a/stubs/gdb/gdb/dap/__init__.pyi +++ b/stubs/gdb/gdb/dap/__init__.pyi @@ -1,11 +1,18 @@ -from typing import Any - -class Server: - def __init__(self, in_stream, out_stream, child_stream) -> None: ... - def main_loop(self) -> None: ... - def send_event(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object - def send_event_later(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object - def shutdown(self) -> None: ... +from . import ( + breakpoint as breakpoint, + bt as bt, + evaluate as evaluate, + launch as launch, + locations as locations, + memory as memory, + modules as modules, + next as next, + pause as pause, + scopes as scopes, + sources as sources, + threads as threads, +) +from .server import Server as Server def pre_command_loop() -> None: ... def run() -> None: ... diff --git a/stubs/gdb/gdb/dap/breakpoint.pyi b/stubs/gdb/gdb/dap/breakpoint.pyi index 5b0f74feb261..dc2958798597 100644 --- a/stubs/gdb/gdb/dap/breakpoint.pyi +++ b/stubs/gdb/gdb/dap/breakpoint.pyi @@ -1 +1,50 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Incomplete +from collections.abc import Generator, Sequence +from contextlib import contextmanager +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +from .. import Breakpoint +from .sources import Source + +@type_check_only +class _SourceBreakpoint(TypedDict): + source: str + line: int + condition: NotRequired[str | None] + hitCondition: NotRequired[str | None] + logMessage: NotRequired[str | None] + +@type_check_only +class _ExceptionFilterOptions(TypedDict): + filderId: str + condition: NotRequired[str | None] + +@type_check_only +class _BreakpointDescriptor(TypedDict): + id: int + verified: bool + reason: NotRequired[str] + source: NotRequired[Source] + line: NotRequired[int] + instructionReference: NotRequired[str] + +@type_check_only +class _SetBreakpointResult(TypedDict): + breakpoints: list[_BreakpointDescriptor] + +# frozenset entries are tuples from _SourceBreakpoint.items() or _ExceptionFilterOptions.items() +breakpoint_map: dict[str, dict[frozenset[Incomplete], Breakpoint]] + +@contextmanager +def suppress_new_breakpoint_event() -> Generator[None]: ... +def set_breakpoint( + *, source: Source, breakpoints: Sequence[_SourceBreakpoint] = (), **args +) -> _SetBreakpointResult: ... # args argument is unused +def set_fn_breakpoint(*, breakpoints: Sequence[_SourceBreakpoint], **args) -> _SetBreakpointResult: ... # args argument is unused +def set_insn_breakpoints( + *, breakpoints: Sequence[_SourceBreakpoint], offset: int | None = None, **args +) -> _SetBreakpointResult: ... # args argument is unused +def set_exception_breakpoints( + *, filters: Sequence[str], filterOptions: Sequence[_ExceptionFilterOptions] = (), **args +) -> _SetBreakpointResult: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/bt.pyi b/stubs/gdb/gdb/dap/bt.pyi index 5b0f74feb261..e78e4b969952 100644 --- a/stubs/gdb/gdb/dap/bt.pyi +++ b/stubs/gdb/gdb/dap/bt.pyi @@ -1 +1,44 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +from .sources import Source + +@type_check_only +class _StackFrameFormat(TypedDict, total=False): + hex: bool + parameters: bool + parameterTypes: bool + parameterNames: bool + parameterValues: bool + line: bool + module: bool + includeAll: bool + +@type_check_only +class _StackFrame(TypedDict): + id: int + name: str + line: int + column: int + instructionPointerReference: str + moduleId: NotRequired[str | None] + source: NotRequired[Source] + +class _StaceTraceResult(TypedDict): + stackFrames: list[_StackFrame] + +def check_stack_frame( + *, + hex: bool = False, + parameters: bool = False, + parameterTypes: bool = False, + parameterNames: bool = False, + parameterValues: bool = False, + line: bool = False, + module: bool = False, + includeAll: bool = False, + **rest, +) -> _StackFrameFormat: ... # rest argument is unused +def stacktrace( + *, levels: int = 0, startFrame: int = 0, threadId: int, format: _StackFrameFormat | None = None, **extra +) -> _StaceTraceResult: ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/disassemble.pyi b/stubs/gdb/gdb/dap/disassemble.pyi index 5b0f74feb261..849d071e6e14 100644 --- a/stubs/gdb/gdb/dap/disassemble.pyi +++ b/stubs/gdb/gdb/dap/disassemble.pyi @@ -1 +1,15 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only + +@type_check_only +class _Instruction(TypedDict): + address: str + instruction: str + instructionBytes: str + +@type_check_only +class _DisassembleResult(TypedDict): + instructions: _Instruction + +def disassemble( + *, memoryReference: str, offset: int = 0, instructionOffset: int = 0, instructionCount: int, **extra +) -> _DisassembleResult: ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/evaluate.pyi b/stubs/gdb/gdb/dap/evaluate.pyi index 5b0f74feb261..e6122233d454 100644 --- a/stubs/gdb/gdb/dap/evaluate.pyi +++ b/stubs/gdb/gdb/dap/evaluate.pyi @@ -1 +1,30 @@ -def __getattr__(name: str): ... # incomplete module +from typing import Literal, TypedDict, type_check_only + +import gdb + +from .varref import ExportedVariableReference, ValueFormat, VariableReference + +class EvaluateResult(VariableReference): + def __init__(self, value: gdb.Value) -> None: ... + +@type_check_only +class _VariablesResult(TypedDict): + variables: ExportedVariableReference + +def eval_request( + *, + expression: str, + frameId: int | None = None, + context: Literal["watch", "variables", "hover", "repl"] = "variables", + format: ValueFormat | None = None, + **args, +) -> ExportedVariableReference: ... # args argument is unused +def variables( + *, variablesReference: int, start: int = 0, count: int = 0, format: ValueFormat | None = None, **args +) -> _VariablesResult: ... # args argument is unused +def set_expression( + *, expression: str, value: str, frameId: int | None = None, format: ValueFormat | None = None, **args +) -> ExportedVariableReference: ... # args argument is unused +def set_variable( + *, variablesReference: int, name: str, value: str, format: ValueFormat | None = None, **args +) -> ExportedVariableReference: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/events.pyi b/stubs/gdb/gdb/dap/events.pyi index 5b0f74feb261..7cd269266eff 100644 --- a/stubs/gdb/gdb/dap/events.pyi +++ b/stubs/gdb/gdb/dap/events.pyi @@ -1 +1,12 @@ -def __getattr__(name: str): ... # incomplete module +import gdb + +inferior_running: bool + +def send_process_event_once() -> None: ... +def expect_process(reason: str) -> None: ... +def thread_event(event: gdb.ThreadEvent, reason: str) -> None: ... +def expect_stop(reason: str) -> None: ... +def exec_and_expect_stop(cmd: str, expected_pause: bool = False) -> None: ... + +# Map from gdb stop reasons to DAP stop reasons. +stop_reason_map: dict[str, str] diff --git a/stubs/gdb/gdb/dap/frames.pyi b/stubs/gdb/gdb/dap/frames.pyi index 5b0f74feb261..3c7d516e36c6 100644 --- a/stubs/gdb/gdb/dap/frames.pyi +++ b/stubs/gdb/gdb/dap/frames.pyi @@ -1 +1,7 @@ -def __getattr__(name: str): ... # incomplete module +from collections.abc import Generator + +import gdb + +def frame_for_id(id: int) -> gdb.Frame: ... +def select_frame(id: int) -> None: ... +def dap_frame_generator(frame_low: int, levels: int, include_all: bool) -> Generator[tuple[int, gdb.Frame]]: ... diff --git a/stubs/gdb/gdb/dap/io.pyi b/stubs/gdb/gdb/dap/io.pyi index 5b0f74feb261..2f5712dcb9fe 100644 --- a/stubs/gdb/gdb/dap/io.pyi +++ b/stubs/gdb/gdb/dap/io.pyi @@ -1 +1,10 @@ -def __getattr__(name: str): ... # incomplete module +from typing import Any, BinaryIO + +import gdb + +from .startup import DAPQueue + +def read_json(stream: BinaryIO) -> Any: ... # returns result of json.loads + +# objects from queue are passed to json.dumps +def start_json_writer(stream: BinaryIO, queue: DAPQueue[Any]) -> gdb.Thread: ... diff --git a/stubs/gdb/gdb/dap/launch.pyi b/stubs/gdb/gdb/dap/launch.pyi index 5b0f74feb261..52a1ab297934 100644 --- a/stubs/gdb/gdb/dap/launch.pyi +++ b/stubs/gdb/gdb/dap/launch.pyi @@ -1 +1,15 @@ -def __getattr__(name: str): ... # incomplete module +from collections.abc import Mapping, Sequence + +def launch( + *, + program: str | None = None, + cwd: str | None = None, + args: Sequence[str] = (), + env: Mapping[str, str] | None = None, + stopAtBeginningOfMainSubprogram: bool = False, + **extra, +): ... # extra argument is unused +def attach( + *, program: str | None = None, pid: int | None = None, target: str | None = None, **args +) -> None: ... # args argument is unused +def config_done(**args) -> None: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/locations.pyi b/stubs/gdb/gdb/dap/locations.pyi index 5b0f74feb261..2a5fe6da674e 100644 --- a/stubs/gdb/gdb/dap/locations.pyi +++ b/stubs/gdb/gdb/dap/locations.pyi @@ -1 +1,15 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only + +from .sources import Source + +@type_check_only +class _Line(TypedDict): + line: int + +@type_check_only +class _BreakpointLocationsResult(TypedDict): + breakpoints: list[_Line] + +def breakpoint_locations( + *, source: Source, line: int, endLine: int | None = None, **extra +) -> _BreakpointLocationsResult: ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/memory.pyi b/stubs/gdb/gdb/dap/memory.pyi index 5b0f74feb261..7ec2c5499185 100644 --- a/stubs/gdb/gdb/dap/memory.pyi +++ b/stubs/gdb/gdb/dap/memory.pyi @@ -1 +1,11 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only + +@type_check_only +class _ReadMemoryResult(TypedDict): + address: str + data: str + +def read_memory( + *, memoryReference: str, offset: int = 0, count: int, **extra +) -> _ReadMemoryResult: ... # extra argument is unused +def write_memory(*, memoryReference: str, offset: int = 0, data: str, **extra): ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/modules.pyi b/stubs/gdb/gdb/dap/modules.pyi index 5b0f74feb261..260f4ba1826a 100644 --- a/stubs/gdb/gdb/dap/modules.pyi +++ b/stubs/gdb/gdb/dap/modules.pyi @@ -1 +1,20 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +import gdb + +@type_check_only +class _Module(TypedDict): + id: str | None + name: str | None + path: NotRequired[str | None] + +@type_check_only +class _ModulesResult(TypedDict): + modules: list[_Module] + totalModules: int + +def module_id(objfile: gdb.Objfile) -> str | None: ... +def is_module(objfile: gdb.Objfile) -> bool: ... +def make_module(objf: gdb.Objfile) -> _Module: ... +def modules(*, startModule: int = 0, moduleCount: int = 0, **args) -> _ModulesResult: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/next.pyi b/stubs/gdb/gdb/dap/next.pyi index 5b0f74feb261..dbfa4820ecec 100644 --- a/stubs/gdb/gdb/dap/next.pyi +++ b/stubs/gdb/gdb/dap/next.pyi @@ -1 +1,16 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only + +@type_check_only +class _ContinueRequestResult(TypedDict): + allThreadsContinued: bool + +def next( + *, threadId: int, singleThread: bool = False, granularity: str = "statement", **args +) -> None: ... # args argument is unused +def step_in( + *, threadId: int, singleThread: bool = False, granularity: str = "statement", **args +) -> None: ... # args argument is unused +def step_out(*, threadId: int, singleThread: bool = False, **args): ... # args argument is unused +def continue_request( + *, threadId: int, singleThread: bool = False, **args +) -> _ContinueRequestResult: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/pause.pyi b/stubs/gdb/gdb/dap/pause.pyi index 5b0f74feb261..20d85eaac633 100644 --- a/stubs/gdb/gdb/dap/pause.pyi +++ b/stubs/gdb/gdb/dap/pause.pyi @@ -1 +1 @@ -def __getattr__(name: str): ... # incomplete module +def pause(**args) -> None: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/scopes.pyi b/stubs/gdb/gdb/dap/scopes.pyi index 5b0f74feb261..872b84186a44 100644 --- a/stubs/gdb/gdb/dap/scopes.pyi +++ b/stubs/gdb/gdb/dap/scopes.pyi @@ -1 +1,45 @@ -def __getattr__(name: str): ... # incomplete module +from collections.abc import Iterable +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +import gdb + +from ..FrameDecorator import FrameDecorator, SymValueWrapper +from .varref import BaseReference, ExportedReference + +frame_to_scope: dict[int, _ScopeReference] + +@type_check_only +class _ExportedScopeReference(ExportedReference): + presentationHint: str + expensive: bool + namedVariables: int + line: NotRequired[int] + +@type_check_only +class _ScopesResult(TypedDict): + scopes: list[_ExportedScopeReference] + +def clear_scopes(event) -> None: ... # event argument is unused +def set_finish_value(val: object) -> None: ... +def symbol_value(sym: SymValueWrapper, frame: FrameDecorator) -> tuple[str, gdb.Value]: ... + +class _ScopeReference(BaseReference): + hint: str + frame: FrameDecorator + inf_frame: gdb.Frame + function: str | None + line: int | None + var_list: tuple[SymValueWrapper, ...] + def __init__(self, name: str, hint: str, frame: FrameDecorator, var_list: Iterable[SymValueWrapper]) -> None: ... + def to_object(self) -> _ExportedScopeReference: ... + def has_children(self) -> bool: ... + def child_count(self) -> int: ... + def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ... + +class _FinishScopeReference(_ScopeReference): ... + +class _RegisterReference(_ScopeReference): + def __init__(self, name: str, frame: FrameDecorator) -> None: ... + +def scopes(*, frameId: int, **extra) -> _ScopesResult: ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/server.pyi b/stubs/gdb/gdb/dap/server.pyi index 5b0f74feb261..32efdf3b6eb7 100644 --- a/stubs/gdb/gdb/dap/server.pyi +++ b/stubs/gdb/gdb/dap/server.pyi @@ -1 +1,60 @@ -def __getattr__(name: str): ... # incomplete module +import threading +from _typeshed import Incomplete +from collections.abc import Callable +from contextlib import AbstractContextManager +from typing import Any, BinaryIO, Generic, TypeVar, type_check_only + +from .startup import DAPQueue + +_T = TypeVar("_T") + +class NotStoppedException(Exception): ... + +class CancellationHandler: + lock: threading.Lock + reqs: list[int] + in_flight_dap_thread: int | None + def starting(self, req: int) -> None: ... + def done(self, req: int) -> None: ... # req argument is not used + def cancel(self, req: int) -> None: ... + def interruptable_region(self, req: int) -> AbstractContextManager[None]: ... + +class Server: + in_stream: BinaryIO + out_stream: BinaryIO + child_stream: BinaryIO + delay_events: list[tuple[str, Any]] # second tuple item is an arbitrary object + write_queue: DAPQueue[Any | None] # objects in queue must be passable to json.dumps + read_queue: DAPQueue[Any | None] # objects in queue are returned from json.loads + done: bool + canceller: CancellationHandler + config: dict[str, Incomplete] + def __init__(self, in_stream, out_stream, child_stream) -> None: ... + def main_loop(self) -> None: ... + def send_event(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object + def send_event_later(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object + def shutdown(self) -> None: ... + +def send_event(event: str, body: Any | None = None) -> None: ... # body is an arbitrary object +@type_check_only +class _Wrapper: + def __call__(self, func: _T) -> _T: ... + +def request(name: str, *, response: bool = True, on_dap_thread: bool = False, expect_stopped: bool = True) -> _Wrapper: ... +def capability(name: str, value: bool = True) -> _Wrapper: ... +def client_bool_capability(name: str) -> bool: ... +def initialize(**args) -> dict[str, bool]: ... # args is arbitrary values for Server.config +def terminate(**args) -> None: ... # args argument is unused +def disconnect(*, terminateDebuggee: bool = False, **args): ... # args argument is unused +def cancel(**args) -> None: ... # args argument is unused + +class Invoker: + def __init__(self, cmd: str) -> None: ... + def __call__(self) -> None: ... + +class Cancellable(Generic[_T]): + def __init__(self, fn: Callable[[], _T], result_q: DAPQueue[_T] | None = None) -> None: ... + def __call__(self) -> None: ... + +def send_gdb(cmd: str | Callable[[], object]) -> None: ... +def send_gdb_with_response(fn: str | Callable[[], _T]) -> _T: ... diff --git a/stubs/gdb/gdb/dap/sources.pyi b/stubs/gdb/gdb/dap/sources.pyi index 5b0f74feb261..029b52e9443d 100644 --- a/stubs/gdb/gdb/dap/sources.pyi +++ b/stubs/gdb/gdb/dap/sources.pyi @@ -1 +1,23 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only +from typing_extensions import TypeAlias + +_SourceReferenceID: TypeAlias = int + +@type_check_only +class Source(TypedDict, total=False): + name: str + path: str + sourceReference: _SourceReferenceID + +@type_check_only +class _LoadSourcesResult(TypedDict): + sources: list[Source] + +@type_check_only +class _SourceResult(TypedDict): + content: str + +def make_source(fullname: str, filename: str | None) -> Source: ... +def decode_source(source: Source) -> _SourceReferenceID: ... +def loaded_sources(**extra) -> _LoadSourcesResult: ... # extra argument is unused +def source(*, source: Source | None = None, sourceReference: int, **extra) -> _SourceResult: ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/startup.pyi b/stubs/gdb/gdb/dap/startup.pyi index 5b0f74feb261..702f2d8bf77b 100644 --- a/stubs/gdb/gdb/dap/startup.pyi +++ b/stubs/gdb/gdb/dap/startup.pyi @@ -1 +1,44 @@ -def __getattr__(name: str): ... # incomplete module +import enum +import io +import queue +import threading +from collections.abc import Callable, Iterable +from typing import Any, ClassVar, TypeVar +from typing_extensions import TypeAlias + +import gdb + +_T = TypeVar("_T") +_F = TypeVar("_F", bound=Callable[..., Any]) + +DAPQueue: TypeAlias = queue.SimpleQueue[_T] + +class DAPException(Exception): ... + +def parse_and_eval(expression: str, global_context: bool = False) -> gdb.Value: ... + +# target and args are passed to gdb.Thread +def start_thread(name: str, target: Callable[..., object], args: Iterable[Any] = ()) -> gdb.Thread: ... +def start_dap(target: Callable[..., object]) -> None: ... +def in_gdb_thread(func: _F) -> _F: ... +def in_dap_thread(func: _F) -> _F: ... + +class LogLevel(enum.IntEnum): + DEFAULT = 1 + FULL = 2 + +class LogLevelParam(gdb.Parameter): + def __init__(self) -> None: ... + +class LoggingParam(gdb.Parameter): + lock: ClassVar[threading.Lock] + log_file: io.TextIOWrapper | None + def __init__(self) -> None: ... + def get_set_string(self) -> str: ... + +dap_log: LoggingParam + +def log(something: object, level: LogLevel = LogLevel.DEFAULT) -> None: ... +def thread_log(something: object, level: LogLevel = LogLevel.DEFAULT) -> None: ... +def log_stack(level: LogLevel = LogLevel.DEFAULT) -> None: ... +def exec_and_log(cmd: str) -> None: ... diff --git a/stubs/gdb/gdb/dap/state.pyi b/stubs/gdb/gdb/dap/state.pyi index 5b0f74feb261..1d80080e1531 100644 --- a/stubs/gdb/gdb/dap/state.pyi +++ b/stubs/gdb/gdb/dap/state.pyi @@ -1 +1 @@ -def __getattr__(name: str): ... # incomplete module +def set_thread(thread_id: int) -> None: ... diff --git a/stubs/gdb/gdb/dap/threads.pyi b/stubs/gdb/gdb/dap/threads.pyi index 5b0f74feb261..c93c4fd3384b 100644 --- a/stubs/gdb/gdb/dap/threads.pyi +++ b/stubs/gdb/gdb/dap/threads.pyi @@ -1 +1,13 @@ -def __getattr__(name: str): ... # incomplete module +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +@type_check_only +class _Thread(TypedDict): + id: int + name: NotRequired[str] + +@type_check_only +class _ThreadsResult(TypedDict): + threads: list[_Thread] + +def threads(**args) -> _ThreadsResult: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/typecheck.pyi b/stubs/gdb/gdb/dap/typecheck.pyi index 5b0f74feb261..dd3922958fc9 100644 --- a/stubs/gdb/gdb/dap/typecheck.pyi +++ b/stubs/gdb/gdb/dap/typecheck.pyi @@ -1 +1,6 @@ -def __getattr__(name: str): ... # incomplete module +from collections.abc import Callable +from typing import Any, TypeVar + +_T = TypeVar("_T", bound=Callable[..., Any]) + +def type_check(func: _T) -> _T: ... diff --git a/stubs/gdb/gdb/dap/varref.pyi b/stubs/gdb/gdb/dap/varref.pyi index 5b0f74feb261..eba5be16d3b6 100644 --- a/stubs/gdb/gdb/dap/varref.pyi +++ b/stubs/gdb/gdb/dap/varref.pyi @@ -1 +1,64 @@ -def __getattr__(name: str): ... # incomplete module +import abc +from collections import defaultdict +from collections.abc import Generator +from contextlib import AbstractContextManager +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +import gdb + +@type_check_only +class ValueFormat(TypedDict, total=False): + hex: bool + +@type_check_only +class ExportedReference(TypedDict): + variableReference: int + name: NotRequired[str] + +@type_check_only +class ExportedVariableReference(ExportedReference): + indexedVariables: NotRequired[int] + namedVariables: NotRequired[int] + memoryReference: NotRequired[str] + type: NotRequired[str] + value: NotRequired[str] + +all_variables: list[BaseReference] + +def clear_vars(event: object) -> None: ... # event argument is unused +def apply_format(value_format: ValueFormat | None) -> AbstractContextManager[None]: ... + +class BaseReference(abc.ABC): + ref: int + name: str + children: list[VariableReference | None] | None + by_name: dict[str, VariableReference] + name_counts: defaultdict[str, int] + def __init__(self, name: str) -> None: ... + def to_object(self) -> ExportedReference: ... + @abc.abstractmethod + def has_children(self) -> bool: ... + def reset_children(self): ... + @abc.abstractmethod + def fetch_one_child(self, index: int) -> tuple[str, gdb.Value]: ... + @abc.abstractmethod + def child_count(self) -> int: ... + def fetch_children(self, start: int, count: int) -> Generator[VariableReference]: ... + def find_child_by_name(self, name: str) -> VariableReference: ... + +class VariableReference(BaseReference): + result_name: str + value: gdb.Value + child_cache: list[tuple[int | str, gdb.Value]] | None + count: int | None + printer: gdb._PrettyPrinter + def __init__(self, name: str, value: gdb.Value, result_name: str = "value") -> None: ... + def assign(self, value: gdb.Value) -> None: ... + def has_children(self) -> bool: ... + def cache_children(self) -> list[tuple[int | str, gdb.Value]]: ... + def child_count(self) -> int: ... + def to_object(self) -> ExportedVariableReference: ... + def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ... + +def find_variable(ref: int) -> BaseReference: ... From 193c00f12c9bee51816d3757ce8e848243d9e573 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Thu, 12 Jun 2025 09:49:42 -0400 Subject: [PATCH 2/5] Misc fixes and improvements --- stubs/gdb/gdb/dap/__init__.pyi | 1 + stubs/gdb/gdb/dap/breakpoint.pyi | 15 ++++++------ stubs/gdb/gdb/dap/bt.pyi | 7 ++++-- stubs/gdb/gdb/dap/disassemble.pyi | 8 ++++++- stubs/gdb/gdb/dap/evaluate.pyi | 10 ++++---- stubs/gdb/gdb/dap/io.pyi | 5 ++-- stubs/gdb/gdb/dap/next.pyi | 9 ++++--- stubs/gdb/gdb/dap/scopes.pyi | 11 +++++---- stubs/gdb/gdb/dap/server.pyi | 39 ++++++++++++++++++++----------- stubs/gdb/gdb/dap/sources.pyi | 4 +++- stubs/gdb/gdb/dap/typecheck.pyi | 4 ++-- stubs/gdb/gdb/dap/varref.pyi | 13 +++++++---- 12 files changed, 79 insertions(+), 47 deletions(-) diff --git a/stubs/gdb/gdb/dap/__init__.pyi b/stubs/gdb/gdb/dap/__init__.pyi index 30c6318d0228..9c9c1931ee7e 100644 --- a/stubs/gdb/gdb/dap/__init__.pyi +++ b/stubs/gdb/gdb/dap/__init__.pyi @@ -10,6 +10,7 @@ from . import ( pause as pause, scopes as scopes, sources as sources, + startup as startup, threads as threads, ) from .server import Server as Server diff --git a/stubs/gdb/gdb/dap/breakpoint.pyi b/stubs/gdb/gdb/dap/breakpoint.pyi index dc2958798597..a861b6ecc760 100644 --- a/stubs/gdb/gdb/dap/breakpoint.pyi +++ b/stubs/gdb/gdb/dap/breakpoint.pyi @@ -1,10 +1,11 @@ from _typeshed import Incomplete -from collections.abc import Generator, Sequence -from contextlib import contextmanager +from collections.abc import Sequence +from contextlib import AbstractContextManager from typing import TypedDict, type_check_only from typing_extensions import NotRequired -from .. import Breakpoint +import gdb + from .sources import Source @type_check_only @@ -24,7 +25,8 @@ class _ExceptionFilterOptions(TypedDict): class _BreakpointDescriptor(TypedDict): id: int verified: bool - reason: NotRequired[str] + reason: NotRequired[str] # only present when verified is False. Possibly only literal "pending" or "failed" + message: NotRequired[str] # only present when reason == "failed" source: NotRequired[Source] line: NotRequired[int] instructionReference: NotRequired[str] @@ -34,10 +36,9 @@ class _SetBreakpointResult(TypedDict): breakpoints: list[_BreakpointDescriptor] # frozenset entries are tuples from _SourceBreakpoint.items() or _ExceptionFilterOptions.items() -breakpoint_map: dict[str, dict[frozenset[Incomplete], Breakpoint]] +breakpoint_map: dict[str, dict[frozenset[Incomplete], gdb.Breakpoint]] -@contextmanager -def suppress_new_breakpoint_event() -> Generator[None]: ... +def suppress_new_breakpoint_event() -> AbstractContextManager[None]: ... def set_breakpoint( *, source: Source, breakpoints: Sequence[_SourceBreakpoint] = (), **args ) -> _SetBreakpointResult: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/bt.pyi b/stubs/gdb/gdb/dap/bt.pyi index e78e4b969952..907cdc8d4f06 100644 --- a/stubs/gdb/gdb/dap/bt.pyi +++ b/stubs/gdb/gdb/dap/bt.pyi @@ -2,10 +2,10 @@ from typing import TypedDict, type_check_only from typing_extensions import NotRequired from .sources import Source +from .varref import ValueFormat @type_check_only -class _StackFrameFormat(TypedDict, total=False): - hex: bool +class _StackFrameFormat(ValueFormat, total=False): parameters: bool parameterTypes: bool parameterNames: bool @@ -29,6 +29,9 @@ class _StaceTraceResult(TypedDict): def check_stack_frame( *, + # From source: + # Note that StackFrameFormat extends ValueFormat, which is why + # "hex" appears here. hex: bool = False, parameters: bool = False, parameterTypes: bool = False, diff --git a/stubs/gdb/gdb/dap/disassemble.pyi b/stubs/gdb/gdb/dap/disassemble.pyi index 849d071e6e14..5754fd13454f 100644 --- a/stubs/gdb/gdb/dap/disassemble.pyi +++ b/stubs/gdb/gdb/dap/disassemble.pyi @@ -1,14 +1,20 @@ from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +from .sources import Source @type_check_only class _Instruction(TypedDict): address: str instruction: str instructionBytes: str + symbol: NotRequired[str] # only set if there's a corresponding label + line: NotRequired[int] # only set if source is available + location: NotRequired[Source] # only set if source is available @type_check_only class _DisassembleResult(TypedDict): - instructions: _Instruction + instructions: list[_Instruction] def disassemble( *, memoryReference: str, offset: int = 0, instructionOffset: int = 0, instructionCount: int, **extra diff --git a/stubs/gdb/gdb/dap/evaluate.pyi b/stubs/gdb/gdb/dap/evaluate.pyi index e6122233d454..bea0ce679e84 100644 --- a/stubs/gdb/gdb/dap/evaluate.pyi +++ b/stubs/gdb/gdb/dap/evaluate.pyi @@ -2,14 +2,14 @@ from typing import Literal, TypedDict, type_check_only import gdb -from .varref import ExportedVariableReference, ValueFormat, VariableReference +from .varref import ValueFormat, VariableReference, VariableReferenceDescriptor class EvaluateResult(VariableReference): def __init__(self, value: gdb.Value) -> None: ... @type_check_only class _VariablesResult(TypedDict): - variables: ExportedVariableReference + variables: list[VariableReferenceDescriptor] def eval_request( *, @@ -18,13 +18,13 @@ def eval_request( context: Literal["watch", "variables", "hover", "repl"] = "variables", format: ValueFormat | None = None, **args, -) -> ExportedVariableReference: ... # args argument is unused +) -> VariableReferenceDescriptor: ... # args argument is unused def variables( *, variablesReference: int, start: int = 0, count: int = 0, format: ValueFormat | None = None, **args ) -> _VariablesResult: ... # args argument is unused def set_expression( *, expression: str, value: str, frameId: int | None = None, format: ValueFormat | None = None, **args -) -> ExportedVariableReference: ... # args argument is unused +) -> VariableReferenceDescriptor: ... # args argument is unused def set_variable( *, variablesReference: int, name: str, value: str, format: ValueFormat | None = None, **args -) -> ExportedVariableReference: ... # args argument is unused +) -> VariableReferenceDescriptor: ... # args argument is unused diff --git a/stubs/gdb/gdb/dap/io.pyi b/stubs/gdb/gdb/dap/io.pyi index 2f5712dcb9fe..abbf5a22a2fa 100644 --- a/stubs/gdb/gdb/dap/io.pyi +++ b/stubs/gdb/gdb/dap/io.pyi @@ -2,9 +2,8 @@ from typing import Any, BinaryIO import gdb +from .server import _JSONValue from .startup import DAPQueue def read_json(stream: BinaryIO) -> Any: ... # returns result of json.loads - -# objects from queue are passed to json.dumps -def start_json_writer(stream: BinaryIO, queue: DAPQueue[Any]) -> gdb.Thread: ... +def start_json_writer(stream: BinaryIO, queue: DAPQueue[_JSONValue]) -> gdb.Thread: ... diff --git a/stubs/gdb/gdb/dap/next.pyi b/stubs/gdb/gdb/dap/next.pyi index dbfa4820ecec..09c2a59ba145 100644 --- a/stubs/gdb/gdb/dap/next.pyi +++ b/stubs/gdb/gdb/dap/next.pyi @@ -1,14 +1,17 @@ -from typing import TypedDict, type_check_only +from typing import Literal, TypedDict, type_check_only +from typing_extensions import TypeAlias @type_check_only class _ContinueRequestResult(TypedDict): allThreadsContinued: bool +_Granularity: TypeAlias = Literal["statement", "instruction"] + def next( - *, threadId: int, singleThread: bool = False, granularity: str = "statement", **args + *, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args ) -> None: ... # args argument is unused def step_in( - *, threadId: int, singleThread: bool = False, granularity: str = "statement", **args + *, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args ) -> None: ... # args argument is unused def step_out(*, threadId: int, singleThread: bool = False, **args): ... # args argument is unused def continue_request( diff --git a/stubs/gdb/gdb/dap/scopes.pyi b/stubs/gdb/gdb/dap/scopes.pyi index 872b84186a44..ade6e78c448d 100644 --- a/stubs/gdb/gdb/dap/scopes.pyi +++ b/stubs/gdb/gdb/dap/scopes.pyi @@ -5,12 +5,12 @@ from typing_extensions import NotRequired import gdb from ..FrameDecorator import FrameDecorator, SymValueWrapper -from .varref import BaseReference, ExportedReference +from .varref import BaseReference, ReferenceDescriptor frame_to_scope: dict[int, _ScopeReference] @type_check_only -class _ExportedScopeReference(ExportedReference): +class _ScopeReferenceDescriptor(ReferenceDescriptor): presentationHint: str expensive: bool namedVariables: int @@ -18,10 +18,10 @@ class _ExportedScopeReference(ExportedReference): @type_check_only class _ScopesResult(TypedDict): - scopes: list[_ExportedScopeReference] + scopes: list[_ScopeReferenceDescriptor] def clear_scopes(event) -> None: ... # event argument is unused -def set_finish_value(val: object) -> None: ... +def set_finish_value(val: gdb.Value) -> None: ... def symbol_value(sym: SymValueWrapper, frame: FrameDecorator) -> tuple[str, gdb.Value]: ... class _ScopeReference(BaseReference): @@ -32,9 +32,10 @@ class _ScopeReference(BaseReference): line: int | None var_list: tuple[SymValueWrapper, ...] def __init__(self, name: str, hint: str, frame: FrameDecorator, var_list: Iterable[SymValueWrapper]) -> None: ... - def to_object(self) -> _ExportedScopeReference: ... + def to_object(self) -> _ScopeReferenceDescriptor: ... def has_children(self) -> bool: ... def child_count(self) -> int: ... + # note: parameter named changed from 'index' to 'idx' def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ... class _FinishScopeReference(_ScopeReference): ... diff --git a/stubs/gdb/gdb/dap/server.pyi b/stubs/gdb/gdb/dap/server.pyi index 32efdf3b6eb7..2636fb2b87c9 100644 --- a/stubs/gdb/gdb/dap/server.pyi +++ b/stubs/gdb/gdb/dap/server.pyi @@ -3,42 +3,49 @@ from _typeshed import Incomplete from collections.abc import Callable from contextlib import AbstractContextManager from typing import Any, BinaryIO, Generic, TypeVar, type_check_only +from typing_extensions import TypeAlias from .startup import DAPQueue _T = TypeVar("_T") +_F = TypeVar("_F", bound=Callable[..., Any]) + +_RequestID: TypeAlias = int +_EventBody: TypeAlias = Any # arbitrary object, implicitly constrained by the event being sent +_JSONValue: TypeAlias = Any # any object that can be handled by json.dumps/json.loads class NotStoppedException(Exception): ... class CancellationHandler: lock: threading.Lock - reqs: list[int] - in_flight_dap_thread: int | None - def starting(self, req: int) -> None: ... - def done(self, req: int) -> None: ... # req argument is not used - def cancel(self, req: int) -> None: ... - def interruptable_region(self, req: int) -> AbstractContextManager[None]: ... + reqs: list[_RequestID] + in_flight_dap_thread: _RequestID | None + in_flight_gdb_thread: _RequestID | None + def starting(self, req: _RequestID) -> None: ... + def done(self, req: _RequestID) -> None: ... # req argument is not used + def cancel(self, req: _RequestID) -> None: ... + def interruptable_region(self, req: _RequestID | None) -> AbstractContextManager[None]: ... class Server: in_stream: BinaryIO out_stream: BinaryIO child_stream: BinaryIO - delay_events: list[tuple[str, Any]] # second tuple item is an arbitrary object - write_queue: DAPQueue[Any | None] # objects in queue must be passable to json.dumps - read_queue: DAPQueue[Any | None] # objects in queue are returned from json.loads + delay_events: list[tuple[str, _EventBody]] + write_queue: DAPQueue[_JSONValue | None] + read_queue: DAPQueue[_JSONValue | None] done: bool canceller: CancellationHandler config: dict[str, Incomplete] - def __init__(self, in_stream, out_stream, child_stream) -> None: ... + def __init__(self, in_stream: BinaryIO, out_stream: BinaryIO, child_stream: BinaryIO) -> None: ... def main_loop(self) -> None: ... - def send_event(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object - def send_event_later(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object + def send_event(self, event: str, body: _EventBody | None = None) -> None: ... + def send_event_later(self, event: str, body: _EventBody | None = None) -> None: ... def shutdown(self) -> None: ... -def send_event(event: str, body: Any | None = None) -> None: ... # body is an arbitrary object +def send_event(event: str, body: _EventBody | None = None) -> None: ... @type_check_only class _Wrapper: - def __call__(self, func: _T) -> _T: ... + def __call__(self, func: _F) -> _F: ... def request(name: str, *, response: bool = True, on_dap_thread: bool = False, expect_stopped: bool = True) -> _Wrapper: ... def capability(name: str, value: bool = True) -> _Wrapper: ... @@ -49,10 +56,14 @@ def disconnect(*, terminateDebuggee: bool = False, **args): ... # args argument def cancel(**args) -> None: ... # args argument is unused class Invoker: + cmd: str def __init__(self, cmd: str) -> None: ... def __call__(self) -> None: ... class Cancellable(Generic[_T]): + fn: Callable[[], _T] + result_q: DAPQueue[_T] | None + req: _RequestID def __init__(self, fn: Callable[[], _T], result_q: DAPQueue[_T] | None = None) -> None: ... def __call__(self) -> None: ... diff --git a/stubs/gdb/gdb/dap/sources.pyi b/stubs/gdb/gdb/dap/sources.pyi index 029b52e9443d..0f146a3919ad 100644 --- a/stubs/gdb/gdb/dap/sources.pyi +++ b/stubs/gdb/gdb/dap/sources.pyi @@ -20,4 +20,6 @@ class _SourceResult(TypedDict): def make_source(fullname: str, filename: str | None) -> Source: ... def decode_source(source: Source) -> _SourceReferenceID: ... def loaded_sources(**extra) -> _LoadSourcesResult: ... # extra argument is unused -def source(*, source: Source | None = None, sourceReference: int, **extra) -> _SourceResult: ... # extra argument is unused +def source( + *, source: Source | None = None, sourceReference: _SourceReferenceID, **extra +) -> _SourceResult: ... # extra argument is unused diff --git a/stubs/gdb/gdb/dap/typecheck.pyi b/stubs/gdb/gdb/dap/typecheck.pyi index dd3922958fc9..37993cca7a34 100644 --- a/stubs/gdb/gdb/dap/typecheck.pyi +++ b/stubs/gdb/gdb/dap/typecheck.pyi @@ -1,6 +1,6 @@ from collections.abc import Callable from typing import Any, TypeVar -_T = TypeVar("_T", bound=Callable[..., Any]) +_F = TypeVar("_F", bound=Callable[..., Any]) -def type_check(func: _T) -> _T: ... +def type_check(func: _F) -> _F: ... diff --git a/stubs/gdb/gdb/dap/varref.pyi b/stubs/gdb/gdb/dap/varref.pyi index eba5be16d3b6..e9b8415b93ac 100644 --- a/stubs/gdb/gdb/dap/varref.pyi +++ b/stubs/gdb/gdb/dap/varref.pyi @@ -12,16 +12,20 @@ class ValueFormat(TypedDict, total=False): hex: bool @type_check_only -class ExportedReference(TypedDict): +class ReferenceDescriptor(TypedDict): + # Result of BaseReference.to_object() variableReference: int name: NotRequired[str] @type_check_only -class ExportedVariableReference(ExportedReference): +class VariableReferenceDescriptor(ReferenceDescriptor): + # Result of VariableReference.to_object() indexedVariables: NotRequired[int] namedVariables: NotRequired[int] memoryReference: NotRequired[str] type: NotRequired[str] + # Below key name set by VariableReference.result_name + # Could be modelled with extra_items=str if PEP 728 is accepted. value: NotRequired[str] all_variables: list[BaseReference] @@ -36,7 +40,7 @@ class BaseReference(abc.ABC): by_name: dict[str, VariableReference] name_counts: defaultdict[str, int] def __init__(self, name: str) -> None: ... - def to_object(self) -> ExportedReference: ... + def to_object(self) -> ReferenceDescriptor: ... @abc.abstractmethod def has_children(self) -> bool: ... def reset_children(self): ... @@ -58,7 +62,8 @@ class VariableReference(BaseReference): def has_children(self) -> bool: ... def cache_children(self) -> list[tuple[int | str, gdb.Value]]: ... def child_count(self) -> int: ... - def to_object(self) -> ExportedVariableReference: ... + def to_object(self) -> VariableReferenceDescriptor: ... + # note: parameter named changed from 'index' to 'idx' def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ... def find_variable(ref: int) -> BaseReference: ... From 52207e7b102f6a7b8be93625e788cb1742791b80 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Thu, 12 Jun 2025 11:41:52 -0400 Subject: [PATCH 3/5] Use _typeshed.Unused for unused arguments --- stubs/gdb/gdb/dap/breakpoint.pyi | 16 +++++++--------- stubs/gdb/gdb/dap/bt.pyi | 9 +++++---- stubs/gdb/gdb/dap/disassemble.pyi | 5 +++-- stubs/gdb/gdb/dap/evaluate.pyi | 17 +++++++++-------- stubs/gdb/gdb/dap/launch.pyi | 11 +++++------ stubs/gdb/gdb/dap/locations.pyi | 5 +++-- stubs/gdb/gdb/dap/memory.pyi | 7 +++---- stubs/gdb/gdb/dap/modules.pyi | 3 ++- stubs/gdb/gdb/dap/next.pyi | 15 +++++---------- stubs/gdb/gdb/dap/pause.pyi | 4 +++- stubs/gdb/gdb/dap/scopes.pyi | 5 +++-- stubs/gdb/gdb/dap/server.pyi | 8 ++++---- stubs/gdb/gdb/dap/sources.pyi | 7 +++---- stubs/gdb/gdb/dap/threads.pyi | 3 ++- stubs/gdb/gdb/dap/varref.pyi | 3 ++- 15 files changed, 59 insertions(+), 59 deletions(-) diff --git a/stubs/gdb/gdb/dap/breakpoint.pyi b/stubs/gdb/gdb/dap/breakpoint.pyi index a861b6ecc760..6e96978e2f43 100644 --- a/stubs/gdb/gdb/dap/breakpoint.pyi +++ b/stubs/gdb/gdb/dap/breakpoint.pyi @@ -1,4 +1,4 @@ -from _typeshed import Incomplete +from _typeshed import Incomplete, Unused from collections.abc import Sequence from contextlib import AbstractContextManager from typing import TypedDict, type_check_only @@ -39,13 +39,11 @@ class _SetBreakpointResult(TypedDict): breakpoint_map: dict[str, dict[frozenset[Incomplete], gdb.Breakpoint]] def suppress_new_breakpoint_event() -> AbstractContextManager[None]: ... -def set_breakpoint( - *, source: Source, breakpoints: Sequence[_SourceBreakpoint] = (), **args -) -> _SetBreakpointResult: ... # args argument is unused -def set_fn_breakpoint(*, breakpoints: Sequence[_SourceBreakpoint], **args) -> _SetBreakpointResult: ... # args argument is unused +def set_breakpoint(*, source: Source, breakpoints: Sequence[_SourceBreakpoint] = (), **args: Unused) -> _SetBreakpointResult: ... +def set_fn_breakpoint(*, breakpoints: Sequence[_SourceBreakpoint], **args: Unused) -> _SetBreakpointResult: ... def set_insn_breakpoints( - *, breakpoints: Sequence[_SourceBreakpoint], offset: int | None = None, **args -) -> _SetBreakpointResult: ... # args argument is unused + *, breakpoints: Sequence[_SourceBreakpoint], offset: int | None = None, **args: Unused +) -> _SetBreakpointResult: ... def set_exception_breakpoints( - *, filters: Sequence[str], filterOptions: Sequence[_ExceptionFilterOptions] = (), **args -) -> _SetBreakpointResult: ... # args argument is unused + *, filters: Sequence[str], filterOptions: Sequence[_ExceptionFilterOptions] = (), **args: Unused +) -> _SetBreakpointResult: ... diff --git a/stubs/gdb/gdb/dap/bt.pyi b/stubs/gdb/gdb/dap/bt.pyi index 907cdc8d4f06..b4e561213171 100644 --- a/stubs/gdb/gdb/dap/bt.pyi +++ b/stubs/gdb/gdb/dap/bt.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only from typing_extensions import NotRequired @@ -40,8 +41,8 @@ def check_stack_frame( line: bool = False, module: bool = False, includeAll: bool = False, - **rest, -) -> _StackFrameFormat: ... # rest argument is unused + **rest: Unused, +) -> _StackFrameFormat: ... def stacktrace( - *, levels: int = 0, startFrame: int = 0, threadId: int, format: _StackFrameFormat | None = None, **extra -) -> _StaceTraceResult: ... # extra argument is unused + *, levels: int = 0, startFrame: int = 0, threadId: int, format: _StackFrameFormat | None = None, **extra: Unused +) -> _StaceTraceResult: ... diff --git a/stubs/gdb/gdb/dap/disassemble.pyi b/stubs/gdb/gdb/dap/disassemble.pyi index 5754fd13454f..387dbaf4b9bc 100644 --- a/stubs/gdb/gdb/dap/disassemble.pyi +++ b/stubs/gdb/gdb/dap/disassemble.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only from typing_extensions import NotRequired @@ -17,5 +18,5 @@ class _DisassembleResult(TypedDict): instructions: list[_Instruction] def disassemble( - *, memoryReference: str, offset: int = 0, instructionOffset: int = 0, instructionCount: int, **extra -) -> _DisassembleResult: ... # extra argument is unused + *, memoryReference: str, offset: int = 0, instructionOffset: int = 0, instructionCount: int, **extra: Unused +) -> _DisassembleResult: ... diff --git a/stubs/gdb/gdb/dap/evaluate.pyi b/stubs/gdb/gdb/dap/evaluate.pyi index bea0ce679e84..75ce6981c0fc 100644 --- a/stubs/gdb/gdb/dap/evaluate.pyi +++ b/stubs/gdb/gdb/dap/evaluate.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import Literal, TypedDict, type_check_only import gdb @@ -17,14 +18,14 @@ def eval_request( frameId: int | None = None, context: Literal["watch", "variables", "hover", "repl"] = "variables", format: ValueFormat | None = None, - **args, -) -> VariableReferenceDescriptor: ... # args argument is unused + **args: Unused, +) -> VariableReferenceDescriptor: ... def variables( - *, variablesReference: int, start: int = 0, count: int = 0, format: ValueFormat | None = None, **args -) -> _VariablesResult: ... # args argument is unused + *, variablesReference: int, start: int = 0, count: int = 0, format: ValueFormat | None = None, **args: Unused +) -> _VariablesResult: ... def set_expression( - *, expression: str, value: str, frameId: int | None = None, format: ValueFormat | None = None, **args -) -> VariableReferenceDescriptor: ... # args argument is unused + *, expression: str, value: str, frameId: int | None = None, format: ValueFormat | None = None, **args: Unused +) -> VariableReferenceDescriptor: ... def set_variable( - *, variablesReference: int, name: str, value: str, format: ValueFormat | None = None, **args -) -> VariableReferenceDescriptor: ... # args argument is unused + *, variablesReference: int, name: str, value: str, format: ValueFormat | None = None, **args: Unused +) -> VariableReferenceDescriptor: ... diff --git a/stubs/gdb/gdb/dap/launch.pyi b/stubs/gdb/gdb/dap/launch.pyi index 52a1ab297934..5d573114df88 100644 --- a/stubs/gdb/gdb/dap/launch.pyi +++ b/stubs/gdb/gdb/dap/launch.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from collections.abc import Mapping, Sequence def launch( @@ -7,9 +8,7 @@ def launch( args: Sequence[str] = (), env: Mapping[str, str] | None = None, stopAtBeginningOfMainSubprogram: bool = False, - **extra, -): ... # extra argument is unused -def attach( - *, program: str | None = None, pid: int | None = None, target: str | None = None, **args -) -> None: ... # args argument is unused -def config_done(**args) -> None: ... # args argument is unused + **extra: Unused, +): ... +def attach(*, program: str | None = None, pid: int | None = None, target: str | None = None, **args: Unused) -> None: ... +def config_done(**args: Unused) -> None: ... diff --git a/stubs/gdb/gdb/dap/locations.pyi b/stubs/gdb/gdb/dap/locations.pyi index 2a5fe6da674e..da63e65c83ea 100644 --- a/stubs/gdb/gdb/dap/locations.pyi +++ b/stubs/gdb/gdb/dap/locations.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only from .sources import Source @@ -11,5 +12,5 @@ class _BreakpointLocationsResult(TypedDict): breakpoints: list[_Line] def breakpoint_locations( - *, source: Source, line: int, endLine: int | None = None, **extra -) -> _BreakpointLocationsResult: ... # extra argument is unused + *, source: Source, line: int, endLine: int | None = None, **extra: Unused +) -> _BreakpointLocationsResult: ... diff --git a/stubs/gdb/gdb/dap/memory.pyi b/stubs/gdb/gdb/dap/memory.pyi index 7ec2c5499185..b6a33a3d1262 100644 --- a/stubs/gdb/gdb/dap/memory.pyi +++ b/stubs/gdb/gdb/dap/memory.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only @type_check_only @@ -5,7 +6,5 @@ class _ReadMemoryResult(TypedDict): address: str data: str -def read_memory( - *, memoryReference: str, offset: int = 0, count: int, **extra -) -> _ReadMemoryResult: ... # extra argument is unused -def write_memory(*, memoryReference: str, offset: int = 0, data: str, **extra): ... # extra argument is unused +def read_memory(*, memoryReference: str, offset: int = 0, count: int, **extra: Unused) -> _ReadMemoryResult: ... +def write_memory(*, memoryReference: str, offset: int = 0, data: str, **extra: Unused): ... diff --git a/stubs/gdb/gdb/dap/modules.pyi b/stubs/gdb/gdb/dap/modules.pyi index 260f4ba1826a..eae61cfb47da 100644 --- a/stubs/gdb/gdb/dap/modules.pyi +++ b/stubs/gdb/gdb/dap/modules.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only from typing_extensions import NotRequired @@ -17,4 +18,4 @@ class _ModulesResult(TypedDict): def module_id(objfile: gdb.Objfile) -> str | None: ... def is_module(objfile: gdb.Objfile) -> bool: ... def make_module(objf: gdb.Objfile) -> _Module: ... -def modules(*, startModule: int = 0, moduleCount: int = 0, **args) -> _ModulesResult: ... # args argument is unused +def modules(*, startModule: int = 0, moduleCount: int = 0, **args: Unused) -> _ModulesResult: ... diff --git a/stubs/gdb/gdb/dap/next.pyi b/stubs/gdb/gdb/dap/next.pyi index 09c2a59ba145..c23e4260b950 100644 --- a/stubs/gdb/gdb/dap/next.pyi +++ b/stubs/gdb/gdb/dap/next.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import Literal, TypedDict, type_check_only from typing_extensions import TypeAlias @@ -7,13 +8,7 @@ class _ContinueRequestResult(TypedDict): _Granularity: TypeAlias = Literal["statement", "instruction"] -def next( - *, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args -) -> None: ... # args argument is unused -def step_in( - *, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args -) -> None: ... # args argument is unused -def step_out(*, threadId: int, singleThread: bool = False, **args): ... # args argument is unused -def continue_request( - *, threadId: int, singleThread: bool = False, **args -) -> _ContinueRequestResult: ... # args argument is unused +def next(*, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args: Unused) -> None: ... +def step_in(*, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args: Unused) -> None: ... +def step_out(*, threadId: int, singleThread: bool = False, **args: Unused): ... +def continue_request(*, threadId: int, singleThread: bool = False, **args: Unused) -> _ContinueRequestResult: ... diff --git a/stubs/gdb/gdb/dap/pause.pyi b/stubs/gdb/gdb/dap/pause.pyi index 20d85eaac633..6343b7b03156 100644 --- a/stubs/gdb/gdb/dap/pause.pyi +++ b/stubs/gdb/gdb/dap/pause.pyi @@ -1 +1,3 @@ -def pause(**args) -> None: ... # args argument is unused +from _typeshed import Unused + +def pause(**args: Unused) -> None: ... diff --git a/stubs/gdb/gdb/dap/scopes.pyi b/stubs/gdb/gdb/dap/scopes.pyi index ade6e78c448d..b78c99655f4d 100644 --- a/stubs/gdb/gdb/dap/scopes.pyi +++ b/stubs/gdb/gdb/dap/scopes.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from collections.abc import Iterable from typing import TypedDict, type_check_only from typing_extensions import NotRequired @@ -20,7 +21,7 @@ class _ScopeReferenceDescriptor(ReferenceDescriptor): class _ScopesResult(TypedDict): scopes: list[_ScopeReferenceDescriptor] -def clear_scopes(event) -> None: ... # event argument is unused +def clear_scopes(event: Unused) -> None: ... def set_finish_value(val: gdb.Value) -> None: ... def symbol_value(sym: SymValueWrapper, frame: FrameDecorator) -> tuple[str, gdb.Value]: ... @@ -43,4 +44,4 @@ class _FinishScopeReference(_ScopeReference): ... class _RegisterReference(_ScopeReference): def __init__(self, name: str, frame: FrameDecorator) -> None: ... -def scopes(*, frameId: int, **extra) -> _ScopesResult: ... # extra argument is unused +def scopes(*, frameId: int, **extra: Unused) -> _ScopesResult: ... diff --git a/stubs/gdb/gdb/dap/server.pyi b/stubs/gdb/gdb/dap/server.pyi index 2636fb2b87c9..bb8b7d0430d4 100644 --- a/stubs/gdb/gdb/dap/server.pyi +++ b/stubs/gdb/gdb/dap/server.pyi @@ -1,5 +1,5 @@ import threading -from _typeshed import Incomplete +from _typeshed import Incomplete, Unused from collections.abc import Callable from contextlib import AbstractContextManager from typing import Any, BinaryIO, Generic, TypeVar, type_check_only @@ -51,9 +51,9 @@ def request(name: str, *, response: bool = True, on_dap_thread: bool = False, ex def capability(name: str, value: bool = True) -> _Wrapper: ... def client_bool_capability(name: str) -> bool: ... def initialize(**args) -> dict[str, bool]: ... # args is arbitrary values for Server.config -def terminate(**args) -> None: ... # args argument is unused -def disconnect(*, terminateDebuggee: bool = False, **args): ... # args argument is unused -def cancel(**args) -> None: ... # args argument is unused +def terminate(**args: Unused) -> None: ... +def disconnect(*, terminateDebuggee: bool = False, **args: Unused): ... +def cancel(**args: Unused) -> None: ... class Invoker: cmd: str diff --git a/stubs/gdb/gdb/dap/sources.pyi b/stubs/gdb/gdb/dap/sources.pyi index 0f146a3919ad..f12bcb3c9ab9 100644 --- a/stubs/gdb/gdb/dap/sources.pyi +++ b/stubs/gdb/gdb/dap/sources.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only from typing_extensions import TypeAlias @@ -19,7 +20,5 @@ class _SourceResult(TypedDict): def make_source(fullname: str, filename: str | None) -> Source: ... def decode_source(source: Source) -> _SourceReferenceID: ... -def loaded_sources(**extra) -> _LoadSourcesResult: ... # extra argument is unused -def source( - *, source: Source | None = None, sourceReference: _SourceReferenceID, **extra -) -> _SourceResult: ... # extra argument is unused +def loaded_sources(**extra: Unused) -> _LoadSourcesResult: ... +def source(*, source: Source | None = None, sourceReference: _SourceReferenceID, **extra: Unused) -> _SourceResult: ... diff --git a/stubs/gdb/gdb/dap/threads.pyi b/stubs/gdb/gdb/dap/threads.pyi index c93c4fd3384b..3de0ccff3b13 100644 --- a/stubs/gdb/gdb/dap/threads.pyi +++ b/stubs/gdb/gdb/dap/threads.pyi @@ -1,3 +1,4 @@ +from _typeshed import Unused from typing import TypedDict, type_check_only from typing_extensions import NotRequired @@ -10,4 +11,4 @@ class _Thread(TypedDict): class _ThreadsResult(TypedDict): threads: list[_Thread] -def threads(**args) -> _ThreadsResult: ... # args argument is unused +def threads(**args: Unused) -> _ThreadsResult: ... diff --git a/stubs/gdb/gdb/dap/varref.pyi b/stubs/gdb/gdb/dap/varref.pyi index e9b8415b93ac..b5114fb50e5a 100644 --- a/stubs/gdb/gdb/dap/varref.pyi +++ b/stubs/gdb/gdb/dap/varref.pyi @@ -1,4 +1,5 @@ import abc +from _typeshed import Unused from collections import defaultdict from collections.abc import Generator from contextlib import AbstractContextManager @@ -30,7 +31,7 @@ class VariableReferenceDescriptor(ReferenceDescriptor): all_variables: list[BaseReference] -def clear_vars(event: object) -> None: ... # event argument is unused +def clear_vars(event: Unused) -> None: ... def apply_format(value_format: ValueFormat | None) -> AbstractContextManager[None]: ... class BaseReference(abc.ABC): From 0875b9d7162bfdd81c0a172124c9715321c29589 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Sat, 12 Jul 2025 10:07:28 -0400 Subject: [PATCH 4/5] Address review comments --- stubs/gdb/gdb/dap/bt.pyi | 9 +++++---- stubs/gdb/gdb/dap/evaluate.pyi | 18 +++++++++--------- stubs/gdb/gdb/dap/io.pyi | 13 ++++++++++--- stubs/gdb/gdb/dap/scopes.pyi | 4 ++-- stubs/gdb/gdb/dap/varref.pyi | 12 ++++++------ 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/stubs/gdb/gdb/dap/bt.pyi b/stubs/gdb/gdb/dap/bt.pyi index b4e561213171..0127cfbbaa0a 100644 --- a/stubs/gdb/gdb/dap/bt.pyi +++ b/stubs/gdb/gdb/dap/bt.pyi @@ -3,10 +3,10 @@ from typing import TypedDict, type_check_only from typing_extensions import NotRequired from .sources import Source -from .varref import ValueFormat +from .varref import _ValueFormat @type_check_only -class _StackFrameFormat(ValueFormat, total=False): +class _StackFrameFormat(_ValueFormat, total=False): parameters: bool parameterTypes: bool parameterNames: bool @@ -25,7 +25,8 @@ class _StackFrame(TypedDict): moduleId: NotRequired[str | None] source: NotRequired[Source] -class _StaceTraceResult(TypedDict): +@type_check_only +class _StackTraceResult(TypedDict): stackFrames: list[_StackFrame] def check_stack_frame( @@ -45,4 +46,4 @@ def check_stack_frame( ) -> _StackFrameFormat: ... def stacktrace( *, levels: int = 0, startFrame: int = 0, threadId: int, format: _StackFrameFormat | None = None, **extra: Unused -) -> _StaceTraceResult: ... +) -> _StackTraceResult: ... diff --git a/stubs/gdb/gdb/dap/evaluate.pyi b/stubs/gdb/gdb/dap/evaluate.pyi index 75ce6981c0fc..04cd64085758 100644 --- a/stubs/gdb/gdb/dap/evaluate.pyi +++ b/stubs/gdb/gdb/dap/evaluate.pyi @@ -3,29 +3,29 @@ from typing import Literal, TypedDict, type_check_only import gdb -from .varref import ValueFormat, VariableReference, VariableReferenceDescriptor +from .varref import VariableReference, _ValueFormat, _VariableReferenceDescriptor class EvaluateResult(VariableReference): def __init__(self, value: gdb.Value) -> None: ... @type_check_only class _VariablesResult(TypedDict): - variables: list[VariableReferenceDescriptor] + variables: list[_VariableReferenceDescriptor] def eval_request( *, expression: str, frameId: int | None = None, context: Literal["watch", "variables", "hover", "repl"] = "variables", - format: ValueFormat | None = None, + format: _ValueFormat | None = None, **args: Unused, -) -> VariableReferenceDescriptor: ... +) -> _VariableReferenceDescriptor: ... def variables( - *, variablesReference: int, start: int = 0, count: int = 0, format: ValueFormat | None = None, **args: Unused + *, variablesReference: int, start: int = 0, count: int = 0, format: _ValueFormat | None = None, **args: Unused ) -> _VariablesResult: ... def set_expression( - *, expression: str, value: str, frameId: int | None = None, format: ValueFormat | None = None, **args: Unused -) -> VariableReferenceDescriptor: ... + *, expression: str, value: str, frameId: int | None = None, format: _ValueFormat | None = None, **args: Unused +) -> _VariableReferenceDescriptor: ... def set_variable( - *, variablesReference: int, name: str, value: str, format: ValueFormat | None = None, **args: Unused -) -> VariableReferenceDescriptor: ... + *, variablesReference: int, name: str, value: str, format: _ValueFormat | None = None, **args: Unused +) -> _VariableReferenceDescriptor: ... diff --git a/stubs/gdb/gdb/dap/io.pyi b/stubs/gdb/gdb/dap/io.pyi index abbf5a22a2fa..2cf4f182f395 100644 --- a/stubs/gdb/gdb/dap/io.pyi +++ b/stubs/gdb/gdb/dap/io.pyi @@ -1,9 +1,16 @@ -from typing import Any, BinaryIO +from _typeshed import SupportsFlush, SupportsRead, SupportsReadline, SupportsWrite +from typing import Any, type_check_only import gdb from .server import _JSONValue from .startup import DAPQueue -def read_json(stream: BinaryIO) -> Any: ... # returns result of json.loads -def start_json_writer(stream: BinaryIO, queue: DAPQueue[_JSONValue]) -> gdb.Thread: ... +@type_check_only +class _SupportsReadAndReadlineBytes(SupportsRead[bytes], SupportsReadline[bytes]): ... + +@type_check_only +class _SupportsWriteAndFlushBytes(SupportsWrite[bytes], SupportsFlush): ... + +def read_json(stream: _SupportsReadAndReadlineBytes) -> Any: ... # returns result of json.loads +def start_json_writer(stream: _SupportsWriteAndFlushBytes, queue: DAPQueue[_JSONValue]) -> gdb.Thread: ... diff --git a/stubs/gdb/gdb/dap/scopes.pyi b/stubs/gdb/gdb/dap/scopes.pyi index b78c99655f4d..c5421b6f747f 100644 --- a/stubs/gdb/gdb/dap/scopes.pyi +++ b/stubs/gdb/gdb/dap/scopes.pyi @@ -6,12 +6,12 @@ from typing_extensions import NotRequired import gdb from ..FrameDecorator import FrameDecorator, SymValueWrapper -from .varref import BaseReference, ReferenceDescriptor +from .varref import BaseReference, _ReferenceDescriptor frame_to_scope: dict[int, _ScopeReference] @type_check_only -class _ScopeReferenceDescriptor(ReferenceDescriptor): +class _ScopeReferenceDescriptor(_ReferenceDescriptor): presentationHint: str expensive: bool namedVariables: int diff --git a/stubs/gdb/gdb/dap/varref.pyi b/stubs/gdb/gdb/dap/varref.pyi index b5114fb50e5a..83d700607585 100644 --- a/stubs/gdb/gdb/dap/varref.pyi +++ b/stubs/gdb/gdb/dap/varref.pyi @@ -9,17 +9,17 @@ from typing_extensions import NotRequired import gdb @type_check_only -class ValueFormat(TypedDict, total=False): +class _ValueFormat(TypedDict, total=False): hex: bool @type_check_only -class ReferenceDescriptor(TypedDict): +class _ReferenceDescriptor(TypedDict): # Result of BaseReference.to_object() variableReference: int name: NotRequired[str] @type_check_only -class VariableReferenceDescriptor(ReferenceDescriptor): +class _VariableReferenceDescriptor(_ReferenceDescriptor): # Result of VariableReference.to_object() indexedVariables: NotRequired[int] namedVariables: NotRequired[int] @@ -32,7 +32,7 @@ class VariableReferenceDescriptor(ReferenceDescriptor): all_variables: list[BaseReference] def clear_vars(event: Unused) -> None: ... -def apply_format(value_format: ValueFormat | None) -> AbstractContextManager[None]: ... +def apply_format(value_format: _ValueFormat | None) -> AbstractContextManager[None]: ... class BaseReference(abc.ABC): ref: int @@ -41,7 +41,7 @@ class BaseReference(abc.ABC): by_name: dict[str, VariableReference] name_counts: defaultdict[str, int] def __init__(self, name: str) -> None: ... - def to_object(self) -> ReferenceDescriptor: ... + def to_object(self) -> _ReferenceDescriptor: ... @abc.abstractmethod def has_children(self) -> bool: ... def reset_children(self): ... @@ -63,7 +63,7 @@ class VariableReference(BaseReference): def has_children(self) -> bool: ... def cache_children(self) -> list[tuple[int | str, gdb.Value]]: ... def child_count(self) -> int: ... - def to_object(self) -> VariableReferenceDescriptor: ... + def to_object(self) -> _VariableReferenceDescriptor: ... # note: parameter named changed from 'index' to 'idx' def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ... From 02cbd98a98ef1da5f401d3cec51e1c294a8ff1a6 Mon Sep 17 00:00:00 2001 From: Brian Schubert Date: Sat, 12 Jul 2025 10:16:58 -0400 Subject: [PATCH 5/5] Update protocols for Server streams --- stubs/gdb/gdb/dap/server.pyi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/stubs/gdb/gdb/dap/server.pyi b/stubs/gdb/gdb/dap/server.pyi index bb8b7d0430d4..22b8231f7d54 100644 --- a/stubs/gdb/gdb/dap/server.pyi +++ b/stubs/gdb/gdb/dap/server.pyi @@ -1,10 +1,11 @@ import threading -from _typeshed import Incomplete, Unused +from _typeshed import Incomplete, SupportsReadline, Unused from collections.abc import Callable from contextlib import AbstractContextManager -from typing import Any, BinaryIO, Generic, TypeVar, type_check_only +from typing import Any, Generic, TypeVar, type_check_only from typing_extensions import TypeAlias +from .io import _SupportsReadAndReadlineBytes, _SupportsWriteAndFlushBytes from .startup import DAPQueue _T = TypeVar("_T") @@ -27,16 +28,21 @@ class CancellationHandler: def interruptable_region(self, req: _RequestID | None) -> AbstractContextManager[None]: ... class Server: - in_stream: BinaryIO - out_stream: BinaryIO - child_stream: BinaryIO + in_stream: _SupportsReadAndReadlineBytes + out_stream: _SupportsWriteAndFlushBytes + child_stream: SupportsReadline[str] delay_events: list[tuple[str, _EventBody]] write_queue: DAPQueue[_JSONValue | None] read_queue: DAPQueue[_JSONValue | None] done: bool canceller: CancellationHandler config: dict[str, Incomplete] - def __init__(self, in_stream: BinaryIO, out_stream: BinaryIO, child_stream: BinaryIO) -> None: ... + def __init__( + self, + in_stream: _SupportsReadAndReadlineBytes, + out_stream: _SupportsWriteAndFlushBytes, + child_stream: SupportsReadline[str], + ) -> None: ... def main_loop(self) -> None: ... def send_event(self, event: str, body: _EventBody | None = None) -> None: ... def send_event_later(self, event: str, body: _EventBody | None = None) -> None: ... pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy