From c69f124e0fa87866a403fb0a2c75b56b638ecbaa Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Mon, 19 Feb 2024 06:25:52 +0100 Subject: [PATCH 1/3] Use a protocol for shlex.instream et al. Add shlex.filestack --- stdlib/shlex.pyi | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/stdlib/shlex.pyi b/stdlib/shlex.pyi index 6d395971e9c6..d4a3271fa746 100644 --- a/stdlib/shlex.pyi +++ b/stdlib/shlex.pyi @@ -1,16 +1,24 @@ import sys +from collections import deque from collections.abc import Iterable -from typing import TextIO, overload +from io import TextIOWrapper +from typing import Literal, overload, type_check_only from typing_extensions import Self, deprecated __all__ = ["shlex", "split", "quote", "join"] +@type_check_only +class _ShlexInstream: + def read(self, size: Literal[1]) -> str: ... + def readline(self) -> object: ... + def close(self) -> object: ... + if sys.version_info >= (3, 12): - def split(s: str | TextIO, comments: bool = False, posix: bool = True) -> list[str]: ... + def split(s: str | _ShlexInstream, comments: bool = False, posix: bool = True) -> list[str]: ... else: @overload - def split(s: str | TextIO, comments: bool = False, posix: bool = True) -> list[str]: ... + def split(s: str | _ShlexInstream, comments: bool = False, posix: bool = True) -> list[str]: ... @overload @deprecated("Passing None for 's' to shlex.split() is deprecated and will raise an error in Python 3.12.") def split(s: None, comments: bool = False, posix: bool = True) -> list[str]: ... @@ -18,6 +26,7 @@ else: def join(split_command: Iterable[str]) -> str: ... def quote(s: str) -> str: ... +# TODO: Make generic over infile once PEP 696 is implemented. class shlex(Iterable[str]): commenters: str wordchars: str @@ -27,17 +36,18 @@ class shlex(Iterable[str]): escapedquotes: str whitespace_split: bool infile: str | None - instream: TextIO + instream: _ShlexInstream source: str debug: int lineno: int token: str + filestack: deque[tuple[str | None, _ShlexInstream, int]] eof: str | None @property def punctuation_chars(self) -> str: ... def __init__( self, - instream: str | TextIO | None = None, + instream: str | _ShlexInstream | None = None, infile: str | None = None, posix: bool = False, punctuation_chars: bool | str = False, @@ -45,8 +55,8 @@ class shlex(Iterable[str]): def get_token(self) -> str | None: ... def push_token(self, tok: str) -> None: ... def read_token(self) -> str | None: ... - def sourcehook(self, newfile: str) -> tuple[str, TextIO] | None: ... - def push_source(self, newstream: str | TextIO, newfile: str | None = None) -> None: ... + def sourcehook(self, newfile: str) -> tuple[str, TextIOWrapper] | None: ... + def push_source(self, newstream: str | _ShlexInstream, newfile: str | None = None) -> None: ... def pop_source(self) -> None: ... def error_leader(self, infile: str | None = None, lineno: int | None = None) -> str: ... def __iter__(self) -> Self: ... From bf06fd3883ada42a29f2c3f9de0de07804c0e3a8 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Mon, 19 Feb 2024 06:26:49 +0100 Subject: [PATCH 2/3] Use protocol ... --- stdlib/shlex.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/shlex.pyi b/stdlib/shlex.pyi index d4a3271fa746..b78eefd2bbe8 100644 --- a/stdlib/shlex.pyi +++ b/stdlib/shlex.pyi @@ -2,13 +2,13 @@ import sys from collections import deque from collections.abc import Iterable from io import TextIOWrapper -from typing import Literal, overload, type_check_only +from typing import Literal, Protocol, overload, type_check_only from typing_extensions import Self, deprecated __all__ = ["shlex", "split", "quote", "join"] @type_check_only -class _ShlexInstream: +class _ShlexInstream(Protocol): def read(self, size: Literal[1]) -> str: ... def readline(self) -> object: ... def close(self) -> object: ... From 8a8be1221016205e334c54cc5ac5f66dd8e071ce Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Mon, 19 Feb 2024 06:27:17 +0100 Subject: [PATCH 3/3] Positional only --- stdlib/shlex.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/shlex.pyi b/stdlib/shlex.pyi index b78eefd2bbe8..daa8df439b26 100644 --- a/stdlib/shlex.pyi +++ b/stdlib/shlex.pyi @@ -9,7 +9,7 @@ __all__ = ["shlex", "split", "quote", "join"] @type_check_only class _ShlexInstream(Protocol): - def read(self, size: Literal[1]) -> str: ... + def read(self, size: Literal[1], /) -> str: ... def readline(self) -> object: ... def close(self) -> object: ...