import signal
import sys
from _typeshed import ReadableBuffer
from bdb import Bdb, _Backend
from cmd import Cmd
from collections.abc import Callable, Iterable, Mapping, Sequence
from linecache import _ModuleGlobals
from rlcompleter import Completer
from types import CodeType, FrameType, TracebackType
from typing import IO, Any, ClassVar, Final, Literal, ParamSpec, TypeAlias, TypeVar
from typing_extensions import Self, deprecated

__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", "post_mortem", "help"]
if sys.version_info >= (3, 14):
    __all__ += ["set_default_backend", "get_default_backend"]

_T = TypeVar("_T")
_P = ParamSpec("_P")
_Mode: TypeAlias = Literal["inline", "cli"]

line_prefix: Final[str]  # undocumented

class Restart(Exception): ...

def run(  # matches `builtins.exec`
    statement: str | ReadableBuffer | CodeType, globals: dict[str, Any] | None = None, locals: Mapping[str, object] | None = None
) -> None: ...
def runctx(  # matches `builtins.exec`
    statement: str | ReadableBuffer | CodeType, globals: dict[str, Any], locals: Mapping[str, object]
) -> None: ...
def runeval(  # matches `builtins.eval`
    expression: str | ReadableBuffer | CodeType, globals: dict[str, Any] | None = None, locals: Mapping[str, object] | None = None
) -> Any: ...
def runcall(func: Callable[_P, _T], *args: _P.args, **kwds: _P.kwargs) -> _T | None: ...

if sys.version_info >= (3, 14):
    def set_default_backend(backend: _Backend) -> None: ...
    def get_default_backend() -> _Backend: ...
    def set_trace(*, header: str | None = None, commands: Iterable[str] | None = None) -> None: ...
    async def set_trace_async(*, header: str | None = None, commands: Iterable[str] | None = None) -> None: ...

else:
    def set_trace(*, header: str | None = None) -> None: ...

def post_mortem(t: TracebackType | None = None) -> None: ...
def pm() -> None: ...

class Pdb(Bdb, Cmd):
    # Everything here is undocumented, except for __init__

    commands_resuming: ClassVar[list[str]]

    if sys.version_info >= (3, 13):
        MAX_CHAINED_EXCEPTION_DEPTH: Final = 999

    aliases: dict[str, str]
    mainpyfile: str
    _wait_for_mainpyfile: bool
    rcLines: list[str]
    commands: dict[int, list[str]]
    commands_doprompt: dict[int, bool]
    commands_silent: dict[int, bool]
    commands_defining: bool
    commands_bnum: int | None
    lineno: int | None
    stack: list[tuple[FrameType, int]]
    curindex: int
    curframe: FrameType | None
    if sys.version_info >= (3, 13):
        @property
        @deprecated("The frame locals reference is no longer cached. Use 'curframe.f_locals' instead.")
        def curframe_locals(self) -> Mapping[str, Any]: ...
        @curframe_locals.setter
        @deprecated(
            "Setting 'curframe_locals' no longer has any effect as of 3.14. Update the contents of 'curframe.f_locals' instead."
        )
        def curframe_locals(self, value: Mapping[str, Any]) -> None: ...
    else:
        curframe_locals: Mapping[str, Any]
    if sys.version_info >= (3, 14):
        mode: _Mode | None
        colorize: bool
        def __init__(
            self,
            completekey: str = "tab",
            stdin: IO[str] | None = None,
            stdout: IO[str] | None = None,
            skip: Iterable[str] | None = None,
            nosigint: bool = False,
            readrc: bool = True,
            mode: _Mode | None = None,
            backend: _Backend | None = None,
            colorize: bool = False,
        ) -> None: ...
    else:
        def __init__(
            self,
            completekey: str = "tab",
            stdin: IO[str] | None = None,
            stdout: IO[str] | None = None,
            skip: Iterable[str] | None = None,
            nosigint: bool = False,
            readrc: bool = True,
        ) -> None: ...
    if sys.version_info >= (3, 14):
        def set_trace(self, frame: FrameType | None = None, *, commands: Iterable[str] | None = None) -> None: ...
        async def set_trace_async(self, frame: FrameType | None = None, *, commands: Iterable[str] | None = None) -> None: ...

    def forget(self) -> None: ...
    def setup(self, f: FrameType | None, tb: TracebackType | None) -> None: ...
    if sys.version_info < (3, 11):
        def execRcLines(self) -> None: ...

    if sys.version_info >= (3, 13):
        user_opcode = Bdb.user_line

    def bp_commands(self, frame: FrameType) -> bool: ...

    if sys.version_info >= (3, 13):
        def interaction(self, frame: FrameType | None, tb_or_exc: TracebackType | BaseException | None) -> None: ...
    else:
        def interaction(self, frame: FrameType | None, traceback: TracebackType | None) -> None: ...

    def displayhook(self, obj: object) -> None: ...
    def handle_command_def(self, line: str) -> bool: ...
    def defaultFile(self) -> str: ...
    def lineinfo(self, identifier: str) -> tuple[None, None, None] | tuple[str, str, int]: ...
    if sys.version_info >= (3, 14):
        def checkline(self, filename: str, lineno: int, module_globals: _ModuleGlobals | None = None) -> int: ...
    else:
        def checkline(self, filename: str, lineno: int) -> int: ...

    def _getval(self, arg: str) -> object: ...
    if sys.version_info >= (3, 14):
        def print_stack_trace(self, count: int | None = None) -> None: ...
    else:
        def print_stack_trace(self) -> None: ...

    if sys.version_info >= (3, 15):
        def print_stack_entry(self, frame_lineno: tuple[FrameType, int], prompt_prefix: str | None = None) -> None: ...
    else:
        def print_stack_entry(self, frame_lineno: tuple[FrameType, int], prompt_prefix: str = "\n-> ") -> None: ...

    def lookupmodule(self, filename: str) -> str | None: ...
    if sys.version_info < (3, 11):
        def _runscript(self, filename: str) -> None: ...

    if sys.version_info >= (3, 14):
        def complete_multiline_names(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...

    if sys.version_info >= (3, 13):
        def completedefault(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...

    def do_commands(self, arg: str) -> bool | None: ...
    if sys.version_info >= (3, 14):
        def do_break(self, arg: str, temporary: bool = False) -> bool | None: ...
    else:
        def do_break(self, arg: str, temporary: bool | Literal[0, 1] = 0) -> bool | None: ...

    def do_tbreak(self, arg: str) -> bool | None: ...
    def do_enable(self, arg: str) -> bool | None: ...
    def do_disable(self, arg: str) -> bool | None: ...
    def do_condition(self, arg: str) -> bool | None: ...
    def do_ignore(self, arg: str) -> bool | None: ...
    def do_clear(self, arg: str) -> bool | None: ...
    def do_where(self, arg: str) -> bool | None: ...
    if sys.version_info >= (3, 13):
        def do_exceptions(self, arg: str) -> bool | None: ...

    def do_up(self, arg: str) -> bool | None: ...
    def do_down(self, arg: str) -> bool | None: ...
    def do_until(self, arg: str) -> bool | None: ...
    def do_step(self, arg: str) -> bool | None: ...
    def do_next(self, arg: str) -> bool | None: ...
    def do_run(self, arg: str) -> bool | None: ...
    def do_return(self, arg: str) -> bool | None: ...
    def do_continue(self, arg: str) -> bool | None: ...
    def do_jump(self, arg: str) -> bool | None: ...
    def do_debug(self, arg: str) -> bool | None: ...
    def do_quit(self, arg: str) -> bool | None: ...
    def do_EOF(self, arg: str) -> bool | None: ...
    def do_args(self, arg: str) -> bool | None: ...
    def do_retval(self, arg: str) -> bool | None: ...
    def do_p(self, arg: str) -> bool | None: ...
    def do_pp(self, arg: str) -> bool | None: ...
    def do_list(self, arg: str) -> bool | None: ...
    def do_whatis(self, arg: str) -> bool | None: ...
    def do_alias(self, arg: str) -> bool | None: ...
    def do_unalias(self, arg: str) -> bool | None: ...
    def do_help(self, arg: str) -> bool | None: ...
    do_b = do_break
    do_cl = do_clear
    do_w = do_where
    do_bt = do_where
    do_u = do_up
    do_d = do_down
    do_unt = do_until
    do_s = do_step
    do_n = do_next
    do_restart = do_run
    do_r = do_return
    do_c = do_continue
    do_cont = do_continue
    do_j = do_jump
    do_q = do_quit
    do_exit = do_quit
    do_a = do_args
    do_rv = do_retval
    do_l = do_list
    do_h = do_help
    def help_exec(self) -> None: ...
    def help_pdb(self) -> None: ...
    def sigint_handler(self, signum: signal.Signals, frame: FrameType) -> None: ...
    if sys.version_info >= (3, 13):
        def message(self, msg: str, end: str = "\n") -> None: ...
    else:
        def message(self, msg: str) -> None: ...

    def error(self, msg: str) -> None: ...
    if sys.version_info >= (3, 13):
        def completenames(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...  # type: ignore[override]
    if sys.version_info >= (3, 12):
        def set_convenience_variable(self, frame: FrameType, name: str, value: Any) -> None: ...
    if sys.version_info >= (3, 13):
        # Added in 3.13.8 and 3.14.1
        @property
        def rlcompleter(self) -> type[Completer]: ...

    def _select_frame(self, number: int) -> None: ...
    def _getval_except(self, arg: str, frame: FrameType | None = None) -> object: ...
    def _print_lines(
        self, lines: Sequence[str], start: int, breaks: Sequence[int] = (), frame: FrameType | None = None
    ) -> None: ...
    def _cmdloop(self) -> None: ...
    def do_display(self, arg: str) -> bool | None: ...
    def do_interact(self, arg: str) -> bool | None: ...
    def do_longlist(self, arg: str) -> bool | None: ...
    def do_source(self, arg: str) -> bool | None: ...
    def do_undisplay(self, arg: str) -> bool | None: ...
    do_ll = do_longlist
    def _complete_location(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...
    def _complete_bpnumber(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...
    def _complete_expression(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...
    def complete_undisplay(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...
    def complete_unalias(self, text: str, line: str, begidx: int, endidx: int) -> list[str]: ...
    complete_commands = _complete_bpnumber
    complete_break = _complete_location
    complete_b = _complete_location
    complete_tbreak = _complete_location
    complete_enable = _complete_bpnumber
    complete_disable = _complete_bpnumber
    complete_condition = _complete_bpnumber
    complete_ignore = _complete_bpnumber
    complete_clear = _complete_location
    complete_cl = _complete_location
    complete_debug = _complete_expression
    complete_print = _complete_expression
    complete_p = _complete_expression
    complete_pp = _complete_expression
    complete_source = _complete_expression
    complete_whatis = _complete_expression
    complete_display = _complete_expression

    if sys.version_info < (3, 11):
        def _runmodule(self, module_name: str) -> None: ...

# undocumented

def find_function(funcname: str, filename: str) -> tuple[str, str, int] | None: ...
def main() -> None: ...
def help() -> None: ...
def lasti2lineno(code: CodeType, lasti: int) -> int: ...

class _rstr(str):
    def __repr__(self) -> Self: ...
