Skip to content

Commit 9519e36

Browse files
Add LiteralString support to string module (#8268)
Co-authored-by: Alex Waygood <[email protected]>
1 parent 89154bf commit 9519e36

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

stdlib/_typeshed/__init__.pyi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ class structseq(Generic[_T_co]):
266266
# Superset of typing.AnyStr that also inclues LiteralString
267267
AnyOrLiteralStr = TypeVar("AnyOrLiteralStr", str, bytes, LiteralString) # noqa: Y001
268268

269+
# Represents when str or LiteralStr is acceptable. Useful for string processing
270+
# APIs where literalness of return value depends on literalness of inputs
271+
StrOrLiteralStr = TypeVar("StrOrLiteralStr", LiteralString, str) # noqa: Y001
272+
269273
# Objects suitable to be passed to sys.setprofile, threading.setprofile, and similar
270274
ProfileFunction: TypeAlias = Callable[[FrameType, str, Any], object]
271275

stdlib/string.pyi

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import sys
2+
from _typeshed import StrOrLiteralStr
23
from collections.abc import Iterable, Mapping, Sequence
34
from re import Pattern, RegexFlag
4-
from typing import Any
5+
from typing import Any, overload
6+
from typing_extensions import LiteralString
57

68
__all__ = [
79
"ascii_letters",
@@ -18,17 +20,17 @@ __all__ = [
1820
"Template",
1921
]
2022

21-
ascii_letters: str
22-
ascii_lowercase: str
23-
ascii_uppercase: str
24-
digits: str
25-
hexdigits: str
26-
octdigits: str
27-
punctuation: str
28-
printable: str
29-
whitespace: str
23+
ascii_letters: LiteralString
24+
ascii_lowercase: LiteralString
25+
ascii_uppercase: LiteralString
26+
digits: LiteralString
27+
hexdigits: LiteralString
28+
octdigits: LiteralString
29+
punctuation: LiteralString
30+
printable: LiteralString
31+
whitespace: LiteralString
3032

31-
def capwords(s: str, sep: str | None = ...) -> str: ...
33+
def capwords(s: StrOrLiteralStr, sep: StrOrLiteralStr | None = ...) -> StrOrLiteralStr: ...
3234

3335
class Template:
3436
template: str
@@ -46,9 +48,19 @@ class Template:
4648

4749
# TODO(MichalPokorny): This is probably badly and/or loosely typed.
4850
class Formatter:
51+
@overload
52+
def format(self, __format_string: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ...
53+
@overload
4954
def format(self, __format_string: str, *args: Any, **kwargs: Any) -> str: ...
55+
@overload
56+
def vformat(
57+
self, format_string: LiteralString, args: Sequence[LiteralString], kwargs: Mapping[LiteralString, LiteralString]
58+
) -> LiteralString: ...
59+
@overload
5060
def vformat(self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> str: ...
51-
def parse(self, format_string: str) -> Iterable[tuple[str, str | None, str | None, str | None]]: ...
61+
def parse(
62+
self, format_string: StrOrLiteralStr
63+
) -> Iterable[tuple[StrOrLiteralStr, StrOrLiteralStr | None, StrOrLiteralStr | None, StrOrLiteralStr | None]]: ...
5264
def get_field(self, field_name: str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> Any: ...
5365
def get_value(self, key: int | str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> Any: ...
5466
def check_unused_args(self, used_args: Sequence[int | str], args: Sequence[Any], kwargs: Mapping[str, Any]) -> None: ...

0 commit comments

Comments
 (0)