Skip to content

Commit fb398b1

Browse files
authored
Use the ReadableBuffer type in more places (#4245)
This is a follow-up on #4232. memoryview, hashlib, and hmac are updated to use ReadableBuffer type instead of their own home-spun unions of bytes, bytearray and whatever else each use case used. mmap is being handled in #4244, and I'll leave BinaryIO for another day (or possibly another person) because it's going to require some messy code duplication because the relevant methods are defined in IO[AnyStr]. There's one corner case I'm not quite sure how best to handle: the documentation for hmac.digest claim that the parmaeters have the same meanings as in hmac.new, but in CPython the latter has an explicit check that `key` is bytes or bytearray while the former works with a memory-view. For now I've matched the documentation. Also, the documentation for HMAC.update says that `msg` can be any type supported by hashlib from Python 3.4; but I can't see anything in the Python 2.7 implementation that would prevent it also taking bytes-like objects, so I've not tried to treat Python 2 any different to Python 3.
1 parent e1d89e5 commit fb398b1

File tree

5 files changed

+58
-46
lines changed

5 files changed

+58
-46
lines changed

stdlib/2/__builtin__.pyi

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ from io import (
1515
TextIOWrapper, FileIO, BufferedRandom, BufferedReader, BufferedWriter
1616
)
1717
from types import TracebackType, CodeType
18-
from _typeshed import AnyPath, OpenBinaryMode, OpenTextMode, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenBinaryModeReading, SupportsWrite
18+
from _typeshed import (
19+
AnyPath, OpenBinaryMode, OpenTextMode,
20+
OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenBinaryModeReading,
21+
SupportsWrite, ReadableBuffer,
22+
)
1923
from typing_extensions import Literal
2024
import sys
2125

@@ -821,12 +825,12 @@ class memoryview(Sized, Container[_mv_container_type]):
821825
f_contiguous: bool
822826
contiguous: bool
823827
nbytes: int
824-
def __init__(self, obj: Union[bytes, bytearray, memoryview]) -> None: ...
828+
def __init__(self, obj: ReadableBuffer) -> None: ...
825829
def __enter__(self) -> memoryview: ...
826830
def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None: ...
827831
def cast(self, format: str, shape: Union[List[int], Tuple[int]] = ...) -> memoryview: ...
828832
else:
829-
def __init__(self, obj: Union[bytes, bytearray, buffer, memoryview]) -> None: ...
833+
def __init__(self, obj: ReadableBuffer) -> None: ...
830834

831835
@overload
832836
def __getitem__(self, i: int) -> _mv_container_type: ...

stdlib/2and3/_typeshed/__init__.pyi

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,9 @@ class SupportsReadline(Protocol[_T_co]):
7070
class SupportsWrite(Protocol[_T_contra]):
7171
def write(self, __s: _T_contra) -> int: ...
7272

73-
ReadableBuffer = Union[bytes, bytearray, memoryview, array.array, mmap.mmap]
74-
WriteableBuffer = Union[bytearray, memoryview, array.array, mmap.mmap]
73+
if sys.version_info >= (3,):
74+
ReadableBuffer = Union[bytes, bytearray, memoryview, array.array, mmap.mmap]
75+
WriteableBuffer = Union[bytearray, memoryview, array.array, mmap.mmap]
76+
else:
77+
ReadableBuffer = Union[bytes, bytearray, memoryview, array.array, mmap.mmap, buffer]
78+
WriteableBuffer = Union[bytearray, memoryview, array.array, mmap.mmap, buffer]

stdlib/2and3/builtins.pyi

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ from io import (
1515
TextIOWrapper, FileIO, BufferedRandom, BufferedReader, BufferedWriter
1616
)
1717
from types import TracebackType, CodeType
18-
from _typeshed import AnyPath, OpenBinaryMode, OpenTextMode, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenBinaryModeReading, SupportsWrite
18+
from _typeshed import (
19+
AnyPath, OpenBinaryMode, OpenTextMode,
20+
OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenBinaryModeReading,
21+
SupportsWrite, ReadableBuffer,
22+
)
1923
from typing_extensions import Literal
2024
import sys
2125

@@ -821,12 +825,12 @@ class memoryview(Sized, Container[_mv_container_type]):
821825
f_contiguous: bool
822826
contiguous: bool
823827
nbytes: int
824-
def __init__(self, obj: Union[bytes, bytearray, memoryview]) -> None: ...
828+
def __init__(self, obj: ReadableBuffer) -> None: ...
825829
def __enter__(self) -> memoryview: ...
826830
def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None: ...
827831
def cast(self, format: str, shape: Union[List[int], Tuple[int]] = ...) -> memoryview: ...
828832
else:
829-
def __init__(self, obj: Union[bytes, bytearray, buffer, memoryview]) -> None: ...
833+
def __init__(self, obj: ReadableBuffer) -> None: ...
830834

831835
@overload
832836
def __getitem__(self, i: int) -> _mv_container_type: ...

stdlib/2and3/hmac.pyi

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,45 @@
33
from typing import Any, AnyStr, Callable, Optional, Union, overload
44
from types import ModuleType
55
import sys
6+
from _typeshed import ReadableBuffer
67

78
_B = Union[bytes, bytearray]
89

910
# TODO more precise type for object of hashlib
1011
_Hash = Any
12+
_DigestMod = Union[str, Callable[[], _Hash], ModuleType]
1113

1214
digest_size: None
1315

1416
if sys.version_info >= (3, 8):
15-
_DigestMod = Union[str, Callable[[], _Hash], ModuleType]
1617
# In reality digestmod has a default value, but the function always throws an error
1718
# if the argument is not given, so we pretend it is a required argument.
1819
@overload
19-
def new(key: _B, msg: Optional[_B], digestmod: _DigestMod) -> HMAC: ...
20+
def new(key: _B, msg: Optional[ReadableBuffer], digestmod: _DigestMod) -> HMAC: ...
2021
@overload
2122
def new(key: _B, *, digestmod: _DigestMod) -> HMAC: ...
2223
elif sys.version_info >= (3, 4):
23-
def new(key: _B, msg: Optional[_B] = ...,
24-
digestmod: Optional[Union[str, Callable[[], _Hash], ModuleType]] = ...) -> HMAC: ...
24+
def new(key: _B, msg: Optional[ReadableBuffer] = ...,
25+
digestmod: Optional[_DigestMod] = ...) -> HMAC: ...
2526
else:
26-
def new(key: _B, msg: Optional[_B] = ...,
27-
digestmod: Optional[Union[Callable[[], _Hash], ModuleType]] = ...) -> HMAC: ...
27+
def new(key: _B, msg: Optional[ReadableBuffer] = ...,
28+
digestmod: Optional[_DigestMod] = ...) -> HMAC: ...
2829

2930
class HMAC:
3031
if sys.version_info >= (3,):
3132
digest_size: int
3233
if sys.version_info >= (3, 4):
3334
block_size: int
3435
name: str
35-
def update(self, msg: _B) -> None: ...
36+
def update(self, msg: ReadableBuffer) -> None: ...
3637
def digest(self) -> bytes: ...
3738
def hexdigest(self) -> str: ...
3839
def copy(self) -> HMAC: ...
3940

4041
@overload
41-
def compare_digest(a: bytearray, b: bytearray) -> bool: ...
42+
def compare_digest(a: ReadableBuffer, b: ReadableBuffer) -> bool: ...
4243
@overload
4344
def compare_digest(a: AnyStr, b: AnyStr) -> bool: ...
4445

4546
if sys.version_info >= (3, 7):
46-
def digest(key: _B, msg: _B, digest: str) -> bytes: ...
47+
def digest(key: _B, msg: ReadableBuffer, digest: str) -> bytes: ...

stdlib/3/hashlib.pyi

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
import sys
44
from typing import AbstractSet, Optional, Union
5-
6-
_DataType = Union[bytes, bytearray, memoryview]
5+
from _typeshed import ReadableBuffer
76

87
class _Hash(object):
98
digest_size: int
@@ -14,54 +13,54 @@ class _Hash(object):
1413
# formally specified, so may not exist on some platforms
1514
name: str
1615

17-
def __init__(self, data: _DataType = ...) -> None: ...
16+
def __init__(self, data: ReadableBuffer = ...) -> None: ...
1817

1918
def copy(self) -> _Hash: ...
2019
def digest(self) -> bytes: ...
2120
def hexdigest(self) -> str: ...
22-
def update(self, __data: _DataType) -> None: ...
21+
def update(self, __data: ReadableBuffer) -> None: ...
2322

2423
if sys.version_info >= (3, 9):
25-
def md5(string: _DataType = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
26-
def sha1(string: _DataType = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
27-
def sha224(string: _DataType = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
28-
def sha256(string: _DataType = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
29-
def sha384(string: _DataType = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
30-
def sha512(string: _DataType = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
24+
def md5(string: ReadableBuffer = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
25+
def sha1(string: ReadableBuffer = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
26+
def sha224(string: ReadableBuffer = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
27+
def sha256(string: ReadableBuffer = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
28+
def sha384(string: ReadableBuffer = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
29+
def sha512(string: ReadableBuffer = ..., *, usedforsecurity: bool = ...) -> _Hash: ...
3130
elif sys.version_info >= (3, 8):
32-
def md5(string: _DataType = ...) -> _Hash: ...
33-
def sha1(string: _DataType = ...) -> _Hash: ...
34-
def sha224(string: _DataType = ...) -> _Hash: ...
35-
def sha256(string: _DataType = ...) -> _Hash: ...
36-
def sha384(string: _DataType = ...) -> _Hash: ...
37-
def sha512(string: _DataType = ...) -> _Hash: ...
31+
def md5(string: ReadableBuffer = ...) -> _Hash: ...
32+
def sha1(string: ReadableBuffer = ...) -> _Hash: ...
33+
def sha224(string: ReadableBuffer = ...) -> _Hash: ...
34+
def sha256(string: ReadableBuffer = ...) -> _Hash: ...
35+
def sha384(string: ReadableBuffer = ...) -> _Hash: ...
36+
def sha512(string: ReadableBuffer = ...) -> _Hash: ...
3837
else:
39-
def md5(__string: _DataType = ...) -> _Hash: ...
40-
def sha1(__string: _DataType = ...) -> _Hash: ...
41-
def sha224(__string: _DataType = ...) -> _Hash: ...
42-
def sha256(__string: _DataType = ...) -> _Hash: ...
43-
def sha384(__string: _DataType = ...) -> _Hash: ...
44-
def sha512(__string: _DataType = ...) -> _Hash: ...
38+
def md5(__string: ReadableBuffer = ...) -> _Hash: ...
39+
def sha1(__string: ReadableBuffer = ...) -> _Hash: ...
40+
def sha224(__string: ReadableBuffer = ...) -> _Hash: ...
41+
def sha256(__string: ReadableBuffer = ...) -> _Hash: ...
42+
def sha384(__string: ReadableBuffer = ...) -> _Hash: ...
43+
def sha512(__string: ReadableBuffer = ...) -> _Hash: ...
4544

46-
def new(name: str, data: _DataType = ...) -> _Hash: ...
45+
def new(name: str, data: ReadableBuffer = ...) -> _Hash: ...
4746

4847
algorithms_guaranteed: AbstractSet[str]
4948
algorithms_available: AbstractSet[str]
5049

51-
def pbkdf2_hmac(hash_name: str, password: _DataType, salt: _DataType, iterations: int, dklen: Optional[int] = ...) -> bytes: ...
50+
def pbkdf2_hmac(hash_name: str, password: ReadableBuffer, salt: ReadableBuffer, iterations: int, dklen: Optional[int] = ...) -> bytes: ...
5251

5352
if sys.version_info >= (3, 6):
5453
class _VarLenHash(object):
5554
digest_size: int
5655
block_size: int
5756
name: str
5857

59-
def __init__(self, data: _DataType = ...) -> None: ...
58+
def __init__(self, data: ReadableBuffer = ...) -> None: ...
6059

6160
def copy(self) -> _VarLenHash: ...
6261
def digest(self, __length: int) -> bytes: ...
6362
def hexdigest(self, __length: int) -> str: ...
64-
def update(self, __data: _DataType) -> None: ...
63+
def update(self, __data: ReadableBuffer) -> None: ...
6564

6665
sha3_224 = _Hash
6766
sha3_256 = _Hash
@@ -70,7 +69,7 @@ if sys.version_info >= (3, 6):
7069
shake_128 = _VarLenHash
7170
shake_256 = _VarLenHash
7271

73-
def scrypt(password: _DataType, *, salt: Optional[_DataType] = ..., n: Optional[int] = ..., r: Optional[int] = ..., p: Optional[int] = ..., maxmem: int = ..., dklen: int = ...) -> bytes: ...
72+
def scrypt(password: ReadableBuffer, *, salt: Optional[ReadableBuffer] = ..., n: Optional[int] = ..., r: Optional[int] = ..., p: Optional[int] = ..., maxmem: int = ..., dklen: int = ...) -> bytes: ...
7473

7574
class _BlakeHash(_Hash):
7675
MAX_DIGEST_SIZE: int
@@ -79,9 +78,9 @@ if sys.version_info >= (3, 6):
7978
SALT_SIZE: int
8079

8180
if sys.version_info >= (3, 9):
82-
def __init__(self, __data: _DataType = ..., *, digest_size: int = ..., key: _DataType = ..., salt: _DataType = ..., person: _DataType = ..., fanout: int = ..., depth: int = ..., leaf_size: int = ..., node_offset: int = ..., node_depth: int = ..., inner_size: int = ..., last_node: bool = ..., usedforsecurity: bool = ...) -> None: ...
81+
def __init__(self, __data: ReadableBuffer = ..., *, digest_size: int = ..., key: ReadableBuffer = ..., salt: ReadableBuffer = ..., person: ReadableBuffer = ..., fanout: int = ..., depth: int = ..., leaf_size: int = ..., node_offset: int = ..., node_depth: int = ..., inner_size: int = ..., last_node: bool = ..., usedforsecurity: bool = ...) -> None: ...
8382
else:
84-
def __init__(self, __data: _DataType = ..., *, digest_size: int = ..., key: _DataType = ..., salt: _DataType = ..., person: _DataType = ..., fanout: int = ..., depth: int = ..., leaf_size: int = ..., node_offset: int = ..., node_depth: int = ..., inner_size: int = ..., last_node: bool = ...) -> None: ...
83+
def __init__(self, __data: ReadableBuffer = ..., *, digest_size: int = ..., key: ReadableBuffer = ..., salt: ReadableBuffer = ..., person: ReadableBuffer = ..., fanout: int = ..., depth: int = ..., leaf_size: int = ..., node_offset: int = ..., node_depth: int = ..., inner_size: int = ..., last_node: bool = ...) -> None: ...
8584

8685
blake2b = _BlakeHash
8786
blake2s = _BlakeHash

0 commit comments

Comments
 (0)