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..9c9c1931ee7e 100644 --- a/stubs/gdb/gdb/dap/__init__.pyi +++ b/stubs/gdb/gdb/dap/__init__.pyi @@ -1,11 +1,19 @@ -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, + startup as startup, + 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..6e96978e2f43 100644 --- a/stubs/gdb/gdb/dap/breakpoint.pyi +++ b/stubs/gdb/gdb/dap/breakpoint.pyi @@ -1 +1,49 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Incomplete, Unused +from collections.abc import Sequence +from contextlib import AbstractContextManager +from typing import TypedDict, type_check_only +from typing_extensions import NotRequired + +import gdb + +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] # 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] + +@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], gdb.Breakpoint]] + +def suppress_new_breakpoint_event() -> AbstractContextManager[None]: ... +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: Unused +) -> _SetBreakpointResult: ... +def set_exception_breakpoints( + *, 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 5b0f74feb261..b4e561213171 100644 --- a/stubs/gdb/gdb/dap/bt.pyi +++ b/stubs/gdb/gdb/dap/bt.pyi @@ -1 +1,48 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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(ValueFormat, total=False): + 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( + *, + # From source: + # Note that StackFrameFormat extends ValueFormat, which is why + # "hex" appears here. + 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: Unused, +) -> _StackFrameFormat: ... +def stacktrace( + *, 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 5b0f74feb261..387dbaf4b9bc 100644 --- a/stubs/gdb/gdb/dap/disassemble.pyi +++ b/stubs/gdb/gdb/dap/disassemble.pyi @@ -1 +1,22 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: list[_Instruction] + +def disassemble( + *, 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 5b0f74feb261..75ce6981c0fc 100644 --- a/stubs/gdb/gdb/dap/evaluate.pyi +++ b/stubs/gdb/gdb/dap/evaluate.pyi @@ -1 +1,31 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +from typing import Literal, TypedDict, type_check_only + +import gdb + +from .varref import ValueFormat, VariableReference, VariableReferenceDescriptor + +class EvaluateResult(VariableReference): + def __init__(self, value: gdb.Value) -> None: ... + +@type_check_only +class _VariablesResult(TypedDict): + variables: list[VariableReferenceDescriptor] + +def eval_request( + *, + expression: str, + frameId: int | None = None, + context: Literal["watch", "variables", "hover", "repl"] = "variables", + format: ValueFormat | None = None, + **args: Unused, +) -> VariableReferenceDescriptor: ... +def variables( + *, 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: ... +def set_variable( + *, variablesReference: int, name: str, value: str, format: ValueFormat | None = None, **args: Unused +) -> VariableReferenceDescriptor: ... 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..abbf5a22a2fa 100644 --- a/stubs/gdb/gdb/dap/io.pyi +++ b/stubs/gdb/gdb/dap/io.pyi @@ -1 +1,9 @@ -def __getattr__(name: str): ... # incomplete module +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 +def start_json_writer(stream: BinaryIO, queue: DAPQueue[_JSONValue]) -> gdb.Thread: ... diff --git a/stubs/gdb/gdb/dap/launch.pyi b/stubs/gdb/gdb/dap/launch.pyi index 5b0f74feb261..5d573114df88 100644 --- a/stubs/gdb/gdb/dap/launch.pyi +++ b/stubs/gdb/gdb/dap/launch.pyi @@ -1 +1,14 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: 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 5b0f74feb261..da63e65c83ea 100644 --- a/stubs/gdb/gdb/dap/locations.pyi +++ b/stubs/gdb/gdb/dap/locations.pyi @@ -1 +1,16 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: Unused +) -> _BreakpointLocationsResult: ... diff --git a/stubs/gdb/gdb/dap/memory.pyi b/stubs/gdb/gdb/dap/memory.pyi index 5b0f74feb261..b6a33a3d1262 100644 --- a/stubs/gdb/gdb/dap/memory.pyi +++ b/stubs/gdb/gdb/dap/memory.pyi @@ -1 +1,10 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: 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 5b0f74feb261..eae61cfb47da 100644 --- a/stubs/gdb/gdb/dap/modules.pyi +++ b/stubs/gdb/gdb/dap/modules.pyi @@ -1 +1,21 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: Unused) -> _ModulesResult: ... diff --git a/stubs/gdb/gdb/dap/next.pyi b/stubs/gdb/gdb/dap/next.pyi index 5b0f74feb261..c23e4260b950 100644 --- a/stubs/gdb/gdb/dap/next.pyi +++ b/stubs/gdb/gdb/dap/next.pyi @@ -1 +1,14 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: _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 5b0f74feb261..6343b7b03156 100644 --- a/stubs/gdb/gdb/dap/pause.pyi +++ b/stubs/gdb/gdb/dap/pause.pyi @@ -1 +1,3 @@ -def __getattr__(name: str): ... # incomplete module +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 5b0f74feb261..b78c99655f4d 100644 --- a/stubs/gdb/gdb/dap/scopes.pyi +++ b/stubs/gdb/gdb/dap/scopes.pyi @@ -1 +1,47 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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, ReferenceDescriptor + +frame_to_scope: dict[int, _ScopeReference] + +@type_check_only +class _ScopeReferenceDescriptor(ReferenceDescriptor): + presentationHint: str + expensive: bool + namedVariables: int + line: NotRequired[int] + +@type_check_only +class _ScopesResult(TypedDict): + scopes: list[_ScopeReferenceDescriptor] + +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]: ... + +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) -> _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): ... + +class _RegisterReference(_ScopeReference): + def __init__(self, name: str, frame: FrameDecorator) -> None: ... + +def scopes(*, frameId: int, **extra: Unused) -> _ScopesResult: ... diff --git a/stubs/gdb/gdb/dap/server.pyi b/stubs/gdb/gdb/dap/server.pyi index 5b0f74feb261..bb8b7d0430d4 100644 --- a/stubs/gdb/gdb/dap/server.pyi +++ b/stubs/gdb/gdb/dap/server.pyi @@ -1 +1,71 @@ -def __getattr__(name: str): ... # incomplete module +import threading +from _typeshed import Incomplete, Unused +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[_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, _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 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: ... + def shutdown(self) -> None: ... + +def send_event(event: str, body: _EventBody | None = None) -> None: ... +@type_check_only +class _Wrapper: + 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: ... +def client_bool_capability(name: str) -> bool: ... +def initialize(**args) -> dict[str, bool]: ... # args is arbitrary values for Server.config +def terminate(**args: Unused) -> None: ... +def disconnect(*, terminateDebuggee: bool = False, **args: Unused): ... +def cancel(**args: Unused) -> None: ... + +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: ... + +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..f12bcb3c9ab9 100644 --- a/stubs/gdb/gdb/dap/sources.pyi +++ b/stubs/gdb/gdb/dap/sources.pyi @@ -1 +1,24 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: Unused) -> _LoadSourcesResult: ... +def source(*, source: Source | None = None, sourceReference: _SourceReferenceID, **extra: Unused) -> _SourceResult: ... 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..3de0ccff3b13 100644 --- a/stubs/gdb/gdb/dap/threads.pyi +++ b/stubs/gdb/gdb/dap/threads.pyi @@ -1 +1,14 @@ -def __getattr__(name: str): ... # incomplete module +from _typeshed import Unused +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: Unused) -> _ThreadsResult: ... diff --git a/stubs/gdb/gdb/dap/typecheck.pyi b/stubs/gdb/gdb/dap/typecheck.pyi index 5b0f74feb261..37993cca7a34 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 + +_F = TypeVar("_F", bound=Callable[..., Any]) + +def type_check(func: _F) -> _F: ... diff --git a/stubs/gdb/gdb/dap/varref.pyi b/stubs/gdb/gdb/dap/varref.pyi index 5b0f74feb261..b5114fb50e5a 100644 --- a/stubs/gdb/gdb/dap/varref.pyi +++ b/stubs/gdb/gdb/dap/varref.pyi @@ -1 +1,70 @@ -def __getattr__(name: str): ... # incomplete module +import abc +from _typeshed import Unused +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 ReferenceDescriptor(TypedDict): + # Result of BaseReference.to_object() + variableReference: int + name: NotRequired[str] + +@type_check_only +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] + +def clear_vars(event: Unused) -> None: ... +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) -> ReferenceDescriptor: ... + @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) -> 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: ...