From 5e3e056421f3573bb1afadc96ec8e8caf9c0c55b Mon Sep 17 00:00:00 2001 From: Semyon Moroz Date: Mon, 7 Apr 2025 16:21:51 +0400 Subject: [PATCH] Improve `passlib.utils` (#13798) --- stubs/passlib/passlib/__init__.pyi | 3 ++ stubs/passlib/passlib/utils/__init__.pyi | 60 ++++++++++++++---------- stubs/passlib/passlib/utils/binary.pyi | 45 +++++++++--------- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/stubs/passlib/passlib/__init__.pyi b/stubs/passlib/passlib/__init__.pyi index e69de29bb..c5dd95466 100644 --- a/stubs/passlib/passlib/__init__.pyi +++ b/stubs/passlib/passlib/__init__.pyi @@ -0,0 +1,3 @@ +from typing import Final + +__version__: Final[str] diff --git a/stubs/passlib/passlib/utils/__init__.pyi b/stubs/passlib/passlib/utils/__init__.pyi index 05c444674..0e1c25103 100644 --- a/stubs/passlib/passlib/utils/__init__.pyi +++ b/stubs/passlib/passlib/utils/__init__.pyi @@ -1,8 +1,9 @@ +import random import timeit -from _typeshed import Incomplete -from collections.abc import Generator +from _typeshed import ReadableBuffer +from collections.abc import Iterable from hmac import compare_digest -from typing import Any +from typing import Final, Literal, SupportsBytes, SupportsIndex, overload from passlib.utils.compat import JYTHON as JYTHON @@ -34,9 +35,9 @@ __all__ = [ "has_salt_info", ] -sys_bits: Any +sys_bits: Final[int] unix_crypt_schemes: list[str] -rounds_cost_values: Any +rounds_cost_values: Final[list[str]] class SequenceMixin: def __getitem__(self, idx): ... @@ -47,29 +48,40 @@ class SequenceMixin: consteq = compare_digest -def str_consteq(left, right): ... -def saslprep(source, param: str = "value"): ... -def render_bytes(source, *args): ... -def xor_bytes(left, right): ... -def is_same_codec(left, right): ... -def is_ascii_safe(source): ... -def to_bytes(source, encoding: str = "utf-8", param: str = "value", source_encoding: Incomplete | None = None): ... -def to_unicode(source, encoding: str = "utf-8", param: str = "value"): ... -def to_native_str(source, encoding: str = "utf-8", param: str = "value"): ... +def str_consteq(left: str | bytes, right: str | bytes) -> bool: ... +def splitcomma(source: str, sep: str = ",") -> list[str]: ... +def saslprep(source: str, param: str = "value") -> str: ... +def render_bytes(source: str | bytes, *args: str | bytes) -> bytes: ... +def bytes_to_int(value: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer) -> int: ... +def int_to_bytes(value: int, count: SupportsIndex) -> bytes: ... +def xor_bytes( + left: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer, + right: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer, +) -> bytes: ... +def repeat_string(source: str | bytes, size: int) -> str | bytes: ... +def is_ascii_codec(codec: str) -> bool: ... +def is_same_codec(left: str, right: str) -> bool: ... +def is_ascii_safe(source: str | bytes) -> bool: ... +def to_bytes(source: str | bytes, encoding: str = "utf-8", param: str = "value", source_encoding: str | None = None) -> bytes: ... +def to_unicode(source: str | bytes, encoding: str = "utf-8", param: str = "value") -> str: ... +def to_native_str(source: str | bytes, encoding: str = "utf-8", param: str = "value") -> str: ... has_crypt: bool -def safe_crypt(secret, hash) -> None: ... -def test_crypt(secret, hash): ... +def safe_crypt(secret: str | bytes, hash: str | bytes) -> str | None: ... +def test_crypt(secret: str | bytes, hash: str) -> bool: ... timer = timeit.default_timer tick = timer -rng: Any +rng: random.Random -def getrandbytes(rng, count) -> Generator[None, None, Any]: ... -def getrandstr(rng, charset, count) -> Generator[None, None, Any]: ... -def generate_password(size: int = 10, charset=...): ... -def is_crypt_handler(obj): ... -def is_crypt_context(obj): ... -def has_rounds_info(handler): ... -def has_salt_info(handler): ... +@overload +def getrandbytes(rng: random.Random, count: None) -> Literal[b""]: ... +@overload +def getrandbytes(rng: random.Random, count) -> bytes: ... +def getrandstr(rng: random.Random, charset: str, count: int) -> str: ... +def generate_password(size: int = 10, charset: str = ...) -> str: ... +def is_crypt_handler(obj) -> bool: ... +def is_crypt_context(obj) -> bool: ... +def has_rounds_info(handler) -> bool: ... +def has_salt_info(handler) -> bool: ... diff --git a/stubs/passlib/passlib/utils/binary.pyi b/stubs/passlib/passlib/utils/binary.pyi index 64b5d5d8c..2c1336b51 100644 --- a/stubs/passlib/passlib/utils/binary.pyi +++ b/stubs/passlib/passlib/utils/binary.pyi @@ -1,23 +1,26 @@ -from _typeshed import Incomplete -from typing import Any +from _typeshed import ReadableBuffer +from logging import Logger +from typing import Any, Final -BASE64_CHARS: Any -AB64_CHARS: Any -HASH64_CHARS: Any -BCRYPT_CHARS: Any -PADDED_BASE64_CHARS: Any -HEX_CHARS: Any -UPPER_HEX_CHARS: Any -LOWER_HEX_CHARS: Any -ALL_BYTE_VALUES: Any +log: Logger -def compile_byte_translation(mapping, source: Incomplete | None = None): ... -def b64s_encode(data): ... -def b64s_decode(data): ... -def ab64_encode(data): ... -def ab64_decode(data): ... -def b32encode(source): ... -def b32decode(source): ... +BASE64_CHARS: Final[str] +AB64_CHARS: Final[str] +HASH64_CHARS: Final[str] +BCRYPT_CHARS: Final[str] +PADDED_BASE64_CHARS: Final[str] +HEX_CHARS: Final[str] +UPPER_HEX_CHARS: Final[str] +LOWER_HEX_CHARS: Final[str] +ALL_BYTE_VALUES: Final[bytes] + +def compile_byte_translation(mapping: dict[str | bytes | int, str | bytes], source: bytes | None = None) -> bytes: ... +def b64s_encode(data: ReadableBuffer) -> bytes: ... +def b64s_decode(data: str | ReadableBuffer) -> bytes: ... +def ab64_encode(data: ReadableBuffer) -> bytes: ... +def ab64_decode(data: str | ReadableBuffer) -> bytes: ... +def b32encode(source: ReadableBuffer) -> str: ... +def b32decode(source: str | bytes) -> bytes: ... class Base64Engine: bytemap: Any @@ -46,9 +49,9 @@ class LazyBase64Engine(Base64Engine): def __init__(self, *args, **kwds) -> None: ... def __getattribute__(self, attr: str): ... -h64: Any -h64big: Any -bcrypt64: Any +h64: Base64Engine +h64big: Base64Engine +bcrypt64: Base64Engine __all__ = [ # constants