From 947dd5d335cabc8dade53e1fed8e5f4097843c8d Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 8 Apr 2016 14:58:11 -0700 Subject: [PATCH 1/2] Add a sane set of method definitions to basestring. BEWARE! We need to think this through carefully. This is just a first stab. --- stdlib/2.7/__builtin__.pyi | 240 ++++++++++++++++++++++++------------- 1 file changed, 155 insertions(+), 85 deletions(-) diff --git a/stdlib/2.7/__builtin__.pyi b/stdlib/2.7/__builtin__.pyi index 1abfaf00f55c..33eae423d204 100644 --- a/stdlib/2.7/__builtin__.pyi +++ b/stdlib/2.7/__builtin__.pyi @@ -188,27 +188,22 @@ class complex(SupportsAbs[float]): def __abs__(self) -> float: ... def __hash__(self) -> int: ... -class basestring(metaclass=ABCMeta): ... - -class unicode(basestring, Sequence[unicode]): - @overload +class basestring(Sequence[basestring], metaclass=ABCMeta): + @abstractmethod def __init__(self) -> None: ... - @overload - def __init__(self, o: object) -> None: ... - @overload - def __init__(self, o: str, encoding: unicode = ..., errors: unicode = ...) -> None: ... - def capitalize(self) -> unicode: ... - def center(self, width: int, fillchar: unicode = u' ') -> unicode: ... - def count(self, x: unicode) -> int: ... - def decode(self, encoding: unicode = ..., errors: unicode = ...) -> unicode: ... - def encode(self, encoding: unicode = ..., errors: unicode = ...) -> str: ... - def endswith(self, suffix: Union[unicode, Tuple[unicode, ...]], start: int = 0, + + def capitalize(self) -> basestring: ... + def center(self, width: int, fillchar: basestring = ...) -> basestring: ... + def count(self, x: basestring) -> int: ... + def decode(self, encoding: basestring = ..., errors: basestring = ...) -> unicode: ... + def encode(self, encoding: basestring = ..., errors: basestring = ...) -> str: ... + def endswith(self, suffix: Union[basestring, Tuple[basestring, ...]], start: int = 0, end: int = ...) -> bool: ... - def expandtabs(self, tabsize: int = 8) -> unicode: ... - def find(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... - def format(self, *args: Any, **kwargs: Any) -> unicode: ... - def format_map(self, map: Mapping[unicode, Any]) -> unicode: ... - def index(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... + def expandtabs(self, tabsize: int = 8) -> basestring: ... + def find(self, sub: basestring, start: int = 0, end: int = 0) -> int: ... + def format(self, *args: Any, **kwargs: Any) -> basestring: ... + def format_map(self, map: Mapping[basestring, Any]) -> basestring: ... + def index(self, sub: basestring, start: int = 0, end: int = 0) -> int: ... def isalnum(self) -> bool: ... def isalpha(self) -> bool: ... def isdecimal(self) -> bool: ... @@ -220,26 +215,95 @@ class unicode(basestring, Sequence[unicode]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... - def join(self, iterable: Iterable[unicode]) -> unicode: ... - def ljust(self, width: int, fillchar: unicode = u' ') -> unicode: ... + def join(self, iterable: Iterable[basestring]) -> basestring: ... + def ljust(self, width: int, fillchar: basestring = ...) -> basestring: ... + def lower(self) -> basestring: ... + def lstrip(self, chars: basestring = ...) -> basestring: ... + def partition(self, sep: basestring) -> Tuple[basestring, basestring, basestring]: ... + def replace(self, old: basestring, new: basestring, count: int = ...) -> basestring: ... + def rfind(self, sub: basestring, start: int = 0, end: int = 0) -> int: ... + def rindex(self, sub: basestring, start: int = 0, end: int = 0) -> int: ... + def rjust(self, width: int, fillchar: basestring = ...) -> basestring: ... + def rpartition(self, sep: basestring) -> Tuple[basestring, basestring, basestring]: ... + # NOTE: rsplit() is too problematic due to returning a List. + def rstrip(self, chars: basestring = ...) -> basestring: ... + def startswith(self, prefix: Union[basestring, Tuple[basestring, ...]], start: int = 0, + end: int = ...) -> bool: ... + # NOTE: split() is too problematic due to returning a List. + # NOTE: splitlines() is too problematic due to returning a List. + def strip(self, chars: basestring = ...) -> basestring: ... + def swapcase(self) -> basestring: ... + def title(self) -> basestring: ... + # NOTE: translate() is too problematic; its signature is different for str vs. unicode. + def upper(self) -> basestring: ... + def zfill(self, width: int) -> basestring: ... + + @overload + def __getitem__(self, i: int) -> basestring: ... + @overload + def __getitem__(self, s: slice) -> basestring: ... + + def __getslice__(self, start: int, stop: int) -> basestring: ... + + @overload + def __add__(self, s: basestring) -> basestring: ... + @overload + def __add__(self, s: str) -> basestring: ... + @overload + def __add__(self, s: unicode) -> unicode: ... + + def __mul__(self, n: int) -> basestring: ... + def __mod__(self, x: Any) -> basestring: ... + def __eq__(self, x: object) -> bool: ... + def __ne__(self, x: object) -> bool: ... + def __lt__(self, x: basestring) -> bool: ... + def __le__(self, x: basestring) -> bool: ... + def __gt__(self, x: basestring) -> bool: ... + def __ge__(self, x: basestring) -> bool: ... + + def __len__(self) -> int: ... + def __contains__(self, s: object) -> bool: ... + def __iter__(self) -> Iterator[basestring]: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __hash__(self) -> int: ... + +class unicode(basestring, Sequence[unicode]): + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, o: object) -> None: ... + @overload + def __init__(self, o: str, encoding: unicode = ..., errors: unicode = ...) -> None: ... + + def capitalize(self) -> unicode: ... + def center(self, width: int, fillchar: basestring = ...) -> unicode: ... + def expandtabs(self, tabsize: int = 8) -> unicode: ... + def format(self, *args: Any, **kwargs: Any) -> unicode: ... + def format_map(self, map: Mapping[basestring, Any]) -> unicode: ... + def join(self, iterable: Iterable[basestring]) -> unicode: ... + def ljust(self, width: int, fillchar: basestring = ...) -> unicode: ... def lower(self) -> unicode: ... - def lstrip(self, chars: unicode = ...) -> unicode: ... - def partition(self, sep: unicode) -> Tuple[unicode, unicode, unicode]: ... - def replace(self, old: unicode, new: unicode, count: int = ...) -> unicode: ... - def rfind(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... - def rindex(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... - def rjust(self, width: int, fillchar: unicode = u' ') -> unicode: ... - def rpartition(self, sep: unicode) -> Tuple[unicode, unicode, unicode]: ... - def rsplit(self, sep: unicode = ..., maxsplit: int = ...) -> List[unicode]: ... - def rstrip(self, chars: unicode = ...) -> unicode: ... - def split(self, sep: unicode = ..., maxsplit: int = ...) -> List[unicode]: ... + def lstrip(self, chars: basestring = ...) -> unicode: ... + def partition(self, sep: basestring) -> Tuple[unicode, unicode, unicode]: ... + def replace(self, old: basestring, new: basestring, count: int = ...) -> unicode: ... + def rjust(self, width: int, fillchar: basestring = ...) -> unicode: ... + def rpartition(self, sep: basestring) -> Tuple[unicode, unicode, unicode]: ... + def rsplit(self, sep: basestring = ..., maxsplit: int = ...) -> List[unicode]: ... + def rstrip(self, chars: basestring = ...) -> unicode: ... + def split(self, sep: basestring = ..., maxsplit: int = ...) -> List[unicode]: ... def splitlines(self, keepends: bool = ...) -> List[unicode]: ... - def startswith(self, prefix: Union[unicode, Tuple[unicode, ...]], start: int = 0, - end: int = ...) -> bool: ... - def strip(self, chars: unicode = ...) -> unicode: ... + def strip(self, chars: basestring = ...) -> unicode: ... def swapcase(self) -> unicode: ... def title(self) -> unicode: ... - def translate(self, table: Union[Dict[int, Any], unicode]) -> unicode: ... + + @overload + def translate(self, table: Dict[int, Any]) -> unicode: ... + @overload + def translate(self, table: unicode) -> unicode: ... + def upper(self) -> unicode: ... def zfill(self, width: int) -> unicode: ... @@ -247,116 +311,122 @@ class unicode(basestring, Sequence[unicode]): def __getitem__(self, i: int) -> unicode: ... @overload def __getitem__(self, s: slice) -> unicode: ... + def __getslice__(self, start: int, stop: int) -> unicode: ... - def __add__(self, s: unicode) -> unicode: ... + def __add__(self, s: basestring) -> unicode: ... def __mul__(self, n: int) -> unicode: ... def __mod__(self, x: Any) -> unicode: ... - def __eq__(self, x: object) -> bool: ... - def __ne__(self, x: object) -> bool: ... - def __lt__(self, x: unicode) -> bool: ... - def __le__(self, x: unicode) -> bool: ... - def __gt__(self, x: unicode) -> bool: ... - def __ge__(self, x: unicode) -> bool: ... - def __len__(self) -> int: ... - def __contains__(self, s: object) -> bool: ... def __iter__(self) -> Iterator[unicode]: ... - def __str__(self) -> str: ... - def __repr__(self) -> str: ... - def __int__(self) -> int: ... - def __float__(self) -> float: ... - def __hash__(self) -> int: ... class str(basestring, Sequence[str]): - def __init__(self, object: object) -> None: ... + def __init__(self, object: object = None) -> None: ... + def capitalize(self) -> str: ... - def center(self, width: int, fillchar: str = ...) -> str: ... - def count(self, x: unicode) -> int: ... - def decode(self, encoding: unicode = ..., errors: unicode = ...) -> unicode: ... - def encode(self, encoding: unicode = ..., errors: unicode = ...) -> str: ... - def endswith(self, suffix: Union[unicode, Tuple[unicode, ...]]) -> bool: ... + def center(self, width: int, fillchar: basestring = ...) -> str: ... def expandtabs(self, tabsize: int = 8) -> str: ... - def find(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... def format(self, *args: Any, **kwargs: Any) -> str: ... - def index(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... - def isalnum(self) -> bool: ... - def isalpha(self) -> bool: ... - def isdigit(self) -> bool: ... - def islower(self) -> bool: ... - def isspace(self) -> bool: ... - def istitle(self) -> bool: ... - def isupper(self) -> bool: ... - def join(self, iterable: Iterable[AnyStr]) -> AnyStr: ... - def ljust(self, width: int, fillchar: str = ...) -> str: ... + + @overload + def join(self, iterable: Iterable[str]) -> str: ... + @overload + def join(self, iterable: Iterable[basestring]) -> basestring: ... + + def ljust(self, width: int, fillchar: basestring = ...) -> str: ... def lower(self) -> str: ... + + @overload + def lstrip(self, chars: basestring = ...) -> basestring: ... @overload def lstrip(self, chars: str = ...) -> str: ... @overload def lstrip(self, chars: unicode) -> unicode: ... + + @overload + def partition(self, sep: basestring) -> Tuple[basestring, basestring, basestring]: ... @overload def partition(self, sep: bytearray) -> Tuple[str, bytearray, str]: ... @overload def partition(self, sep: str) -> Tuple[str, str, str]: ... @overload def partition(self, sep: unicode) -> Tuple[unicode, unicode, unicode]: ... - def replace(self, old: AnyStr, new: AnyStr, count: int = ...) -> AnyStr: ... - def rfind(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... - def rindex(self, sub: unicode, start: int = 0, end: int = 0) -> int: ... - def rjust(self, width: int, fillchar: str = ...) -> str: ... + + @overload + def replace(self, old: str, new: str, count: int = ...) -> str: ... + @overload + def replace(self, old: basestring, new: basestring, count: int = ...) -> basestring: ... + @overload + def replace(self, old: unicode, new: basestring, count: int = ...) -> unicode: ... + @overload + def replace(self, old: basestring, new: unicode, count: int = ...) -> unicode: ... + + def rjust(self, width: int, fillchar: basestring = ...) -> str: ... + + @overload + def rpartition(self, sep: basestring) -> Tuple[basestring, basestring, basestring]: ... @overload def rpartition(self, sep: bytearray) -> Tuple[str, bytearray, str]: ... @overload def rpartition(self, sep: str) -> Tuple[str, str, str]: ... @overload def rpartition(self, sep: unicode) -> Tuple[unicode, unicode, unicode]: ... + @overload def rsplit(self, sep: str = ..., maxsplit: int = ...) -> List[str]: ... @overload def rsplit(self, sep: unicode, maxsplit: int = ...) -> List[unicode]: ... + + @overload + def rstrip(self, chars: basestring = ...) -> basestring: ... @overload def rstrip(self, chars: str = ...) -> str: ... @overload def rstrip(self, chars: unicode) -> unicode: ... + @overload def split(self, sep: str = ..., maxsplit: int = ...) -> List[str]: ... @overload def split(self, sep: unicode, maxsplit: int = ...) -> List[unicode]: ... + def splitlines(self, keepends: bool = ...) -> List[str]: ... - def startswith(self, prefix: Union[unicode, Tuple[unicode, ...]]) -> bool: ... + + @overload + def strip(self, chars: basestring = ...) -> basestring: ... @overload def strip(self, chars: str = ...) -> str: ... @overload def strip(self, chars: unicode) -> unicode: ... + def swapcase(self) -> str: ... def title(self) -> str: ... - def translate(self, table: AnyStr, deletechars: AnyStr = None) -> AnyStr: ... + def translate(self, table: str, deletechars: str = None) -> str: ... def upper(self) -> str: ... def zfill(self, width: int) -> str: ... - def __len__(self) -> int: ... def __iter__(self) -> Iterator[str]: ... def __str__(self) -> str: ... def __repr__(self) -> str: ... - def __int__(self) -> int: ... - def __float__(self) -> float: ... - def __hash__(self) -> int: ... + @overload def __getitem__(self, i: int) -> str: ... @overload def __getitem__(self, s: slice) -> str: ... + def __getslice__(self, start: int, stop: int) -> str: ... - def __add__(self, s: AnyStr) -> AnyStr: ... + + @overload + def __add__(self, s: basestring) -> basestring: ... + @overload + def __add__(self, s: str) -> str: ... + @overload + def __add__(self, s: unicode) -> unicode: ... + def __mul__(self, n: int) -> str: ... def __rmul__(self, n: int) -> str: ... - def __contains__(self, o: object) -> bool: ... - def __eq__(self, x: object) -> bool: ... - def __ne__(self, x: object) -> bool: ... - def __lt__(self, x: unicode) -> bool: ... - def __le__(self, x: unicode) -> bool: ... - def __gt__(self, x: unicode) -> bool: ... - def __ge__(self, x: unicode) -> bool: ... def __mod__(self, x: Any) -> str: ... +# NOTE: Currently mypy treats bytearray as a subclass of str; +# when this changes there might be some surprises here... class bytearray(Sequence[int]): @overload def __init__(self) -> None: ... @@ -701,7 +771,7 @@ def open(file: unicode, mode: str = 'r', buffering: int = ...) -> BinaryIO: ... def open(file: int, mode: str = 'r', buffering: int = ...) -> BinaryIO: ... def ord(c: unicode) -> int: ... # This is only available after from __future__ import print_function. -def print(*values: Any, sep: unicode = u' ', end: unicode = u'\n', +def print(*values: Any, sep: unicode = ..., end: unicode = u'\n', file: IO[Any] = ...) -> None: ... @overload def pow(x: int, y: int) -> Any: ... # The return type can be int or float, depending on y. From baf2f3ca3dcf9073fe14b2fc38fade975be46141 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 9 Apr 2016 13:23:20 -0700 Subject: [PATCH 2/2] Figured out how to do [r]split(), splitlines(). --- stdlib/2.7/__builtin__.pyi | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/stdlib/2.7/__builtin__.pyi b/stdlib/2.7/__builtin__.pyi index 33eae423d204..e4278955bb7a 100644 --- a/stdlib/2.7/__builtin__.pyi +++ b/stdlib/2.7/__builtin__.pyi @@ -225,12 +225,12 @@ class basestring(Sequence[basestring], metaclass=ABCMeta): def rindex(self, sub: basestring, start: int = 0, end: int = 0) -> int: ... def rjust(self, width: int, fillchar: basestring = ...) -> basestring: ... def rpartition(self, sep: basestring) -> Tuple[basestring, basestring, basestring]: ... - # NOTE: rsplit() is too problematic due to returning a List. + def rsplit(self, sep: basestring = ..., maxsplit: int = ...) -> Sequence[basestring]: ... def rstrip(self, chars: basestring = ...) -> basestring: ... def startswith(self, prefix: Union[basestring, Tuple[basestring, ...]], start: int = 0, end: int = ...) -> bool: ... - # NOTE: split() is too problematic due to returning a List. - # NOTE: splitlines() is too problematic due to returning a List. + def split(self, sep: basestring = ..., maxsplit: int = ...) -> Sequence[basestring]: ... + def splitlines(self, keepends: bool = ...) -> Sequence[basestring]: ... def strip(self, chars: basestring = ...) -> basestring: ... def swapcase(self) -> basestring: ... def title(self) -> basestring: ... @@ -371,6 +371,8 @@ class str(basestring, Sequence[str]): @overload def rpartition(self, sep: unicode) -> Tuple[unicode, unicode, unicode]: ... + @overload + def rsplit(self, sep: basestring = ..., maxsplit: int = ...) -> List[basestring]: ... @overload def rsplit(self, sep: str = ..., maxsplit: int = ...) -> List[str]: ... @overload @@ -383,6 +385,8 @@ class str(basestring, Sequence[str]): @overload def rstrip(self, chars: unicode) -> unicode: ... + @overload + def split(self, sep: basestring = ..., maxsplit: int = ...) -> List[basestring]: ... @overload def split(self, sep: str = ..., maxsplit: int = ...) -> List[str]: ... @overload