Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 62 additions & 10 deletions stdlib/2and3/codecs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# https://docs.python.org/2/library/codecs.html and https://docs.python.org/3/library/codecs.html

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly the attribution comment does not belong here, nor does the value judgment.

import sys
from typing import (
Any,
BinaryIO,
Callable,
Generator,
Expand Down Expand Up @@ -33,8 +34,8 @@ _encoded = bytes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's really too bad that this file uses all-lowercase names to indicate various type aliases. But maybe now's not the right time to fix that.

# TODO: It is not possible to specify these signatures correctly, because
# they have an optional positional or keyword argument for errors=.
_encode_type = Callable[[_decoded], _encoded] # signature of Codec().encode
_decode_type = Callable[[_encoded], _decoded] # signature of Codec().decode
_encode_type = Callable[[_decoded], Tuple[_encoded, int]] # signature of Codec().encode
_decode_type = Callable[[_encoded], Tuple[_decoded, int]] # signature of Codec().decode
_stream_reader_type = Callable[[IO[_encoded]], 'StreamReader'] # signature of StreamReader __init__
_stream_writer_type = Callable[[IO[_encoded]], 'StreamWriter'] # signature of StreamWriter __init__
_incremental_encoder_type = Callable[[], 'IncrementalEncoder'] # signature of IncrementalEncoder __init__
Expand All @@ -49,13 +50,19 @@ def decode(obj: _encoded, encoding: str = ..., errors: str = ...) -> _decoded:
def lookup(encoding: str) -> 'CodecInfo':
...
class CodecInfo(Tuple[_encode_type, _decode_type, _stream_reader_type, _stream_writer_type]):
encode = ... # type: _encode_type
decode = ... # type: _decode_type
streamreader = ... # type: _stream_reader_type
streamwriter = ... # type: _stream_writer_type
incrementalencoder = ... # type: _incremental_encoder_type
incrementaldecoder = ... # type: _incremental_decoder_type
name = ... # type: str
@property
def encode(self) -> _encode_type: ...
@property
def decode(self) -> _decode_type: ...
@property
def streamreader(self) -> _stream_reader_type: ...
@property
def streamwriter(self) -> _stream_writer_type: ...
@property
def incrementalencoder(self) -> _incremental_encoder_type: ...
@property
def incrementaldecoder(self) -> _incremental_decoder_type: ...
name: str
def __init__(self, encode: _encode_type, decode: _decode_type, streamreader: _stream_reader_type = ..., streamwriter: _stream_writer_type = ..., incrementalencoder: _incremental_encoder_type = ..., incrementaldecoder: _incremental_decoder_type = ..., name: str = ...) -> None: ...

def getencoder(encoding: str) -> _encode_type:
Expand Down Expand Up @@ -207,7 +214,10 @@ class StreamReaderWriter(TextIO):
def read(self, size: int= ...) -> _decoded: ...
def readline(self, size: Optional[int] = ...) -> _decoded: ...
def readlines(self, sizehint: Optional[int] = ...) -> List[_decoded]: ...
def __next__(self) -> _decoded: ...
if sys.version_info >= (3,):
def __next__(self) -> Text: ...
else:
def next(self) -> Text: ...
def __iter__(self: _T) -> _T: ...
# This actually returns None, but that's incompatible with the supertype
def write(self, data: _decoded) -> int: ...
Expand All @@ -217,7 +227,49 @@ class StreamReaderWriter(TextIO):
def seek(self, offset: int, whence: int = ...) -> int: ...
def __enter__(self: _T) -> _T: ...
def __exit__(self, typ: Optional[Type[BaseException]], exc: Optional[BaseException], tb: Optional[types.TracebackType]) -> bool: ...
def __getattr__(self, name: str) -> Any: ...

# These methods don't actually exist directly, but they are needed to satisfy the TextIO

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to introduce these through inheritance?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're abstract on the base classes, so we need to have them here to make these classes non-abstract. Maybe there's some class in io that we could inherit from, but that wouldn't be accurate either since this class doesn't inherit from those classes at runtime.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, let's keep this (verbose) approach then.

# interface. At runtime, they are delegated through __getattr__.
def close(self) -> None: ...
def fileno(self) -> int: ...
def flush(self) -> None: ...
def isatty(self) -> bool: ...
def readable(self) -> bool: ...
def truncate(self, size: Optional[int] = ...) -> int: ...
def seekable(self) -> bool: ...
def tell(self) -> int: ...
def writable(self) -> bool: ...

_SRT = TypeVar('_SRT', bound=StreamRecoder)

class StreamRecoder(BinaryIO):
def __init__(self, stream: IO[_encoded], encode: _encode_type, decode: _decode_type, Reader: _stream_reader_type, Writer: _stream_writer_type, errors: str = ...) -> None:
...
def read(self, size: int = ...) -> bytes: ...
def readline(self, size: Optional[int] = ...) -> bytes: ...
def readlines(self, sizehint: Optional[int] = ...) -> List[bytes]: ...
if sys.version_info >= (3,):
def __next__(self) -> bytes: ...
else:
def next(self) -> bytes: ...
def __iter__(self: _SRT) -> _SRT: ...
def write(self, data: bytes) -> int: ...
def writelines(self, list: Iterable[bytes]) -> int: ... # type: ignore # it's supposed to return None
def reset(self) -> None: ...
def __getattr__(self, name: str) -> Any: ...
def __enter__(self: _SRT) -> _SRT: ...
def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], tb: Optional[types.TracebackType]) -> bool: ...

# These methods don't actually exist directly, but they are needed to satisfy the BinaryIO
# interface. At runtime, they are delegated through __getattr__.
def seek(self, offset: int, whence: int = ...) -> int: ...
def close(self) -> None: ...
def fileno(self) -> int: ...
def flush(self) -> None: ...
def isatty(self) -> bool: ...
def readable(self) -> bool: ...
def truncate(self, size: Optional[int] = ...) -> int: ...
def seekable(self) -> bool: ...
def tell(self) -> int: ...
def writable(self) -> bool: ...