main commit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-16 16:30:25 +09:00
parent 91c7e04474
commit 537e7b363f
1146 changed files with 45926 additions and 77196 deletions

View File

@@ -1,26 +1,18 @@
import datetime
import logging
import textwrap
from collections.abc import Callable
import sys
from contextlib import contextmanager
from functools import wraps
from typing import Any, Dict, List, Mapping, Optional, TypeVar, Union
from redis.exceptions import DataError
from redis.typing import AbsExpiryT, EncodableT, ExpiryT
from typing import Any, Dict, Mapping, Union
try:
import hiredis # noqa
# Only support Hiredis >= 3.0:
hiredis_version = hiredis.__version__.split(".")
HIREDIS_AVAILABLE = int(hiredis_version[0]) > 3 or (
int(hiredis_version[0]) == 3 and int(hiredis_version[1]) >= 2
)
if not HIREDIS_AVAILABLE:
raise ImportError("hiredis package should be >= 3.2.0")
# Only support Hiredis >= 1.0:
HIREDIS_AVAILABLE = not hiredis.__version__.startswith("0.")
HIREDIS_PACK_AVAILABLE = hasattr(hiredis, "pack_command")
except ImportError:
HIREDIS_AVAILABLE = False
HIREDIS_PACK_AVAILABLE = False
try:
import ssl # noqa
@@ -36,7 +28,10 @@ try:
except ImportError:
CRYPTOGRAPHY_AVAILABLE = False
from importlib import metadata
if sys.version_info >= (3, 8):
from importlib import metadata
else:
import importlib_metadata as metadata
def from_url(url, **kwargs):
@@ -131,74 +126,6 @@ def deprecated_function(reason="", version="", name=None):
return decorator
def warn_deprecated_arg_usage(
arg_name: Union[list, str],
function_name: str,
reason: str = "",
version: str = "",
stacklevel: int = 2,
):
import warnings
msg = (
f"Call to '{function_name}' function with deprecated"
f" usage of input argument/s '{arg_name}'."
)
if reason:
msg += f" ({reason})"
if version:
msg += f" -- Deprecated since version {version}."
warnings.warn(msg, category=DeprecationWarning, stacklevel=stacklevel)
C = TypeVar("C", bound=Callable)
def deprecated_args(
args_to_warn: list = ["*"],
allowed_args: list = [],
reason: str = "",
version: str = "",
) -> Callable[[C], C]:
"""
Decorator to mark specified args of a function as deprecated.
If '*' is in args_to_warn, all arguments will be marked as deprecated.
"""
def decorator(func: C) -> C:
@wraps(func)
def wrapper(*args, **kwargs):
# Get function argument names
arg_names = func.__code__.co_varnames[: func.__code__.co_argcount]
provided_args = dict(zip(arg_names, args))
provided_args.update(kwargs)
provided_args.pop("self", None)
for allowed_arg in allowed_args:
provided_args.pop(allowed_arg, None)
for arg in args_to_warn:
if arg == "*" and len(provided_args) > 0:
warn_deprecated_arg_usage(
list(provided_args.keys()),
func.__name__,
reason,
version,
stacklevel=3,
)
elif arg in provided_args:
warn_deprecated_arg_usage(
arg, func.__name__, reason, version, stacklevel=3
)
return func(*args, **kwargs)
return wrapper
return decorator
def _set_info_logger():
"""
Set up a logger that log info logs to stdout.
@@ -218,97 +145,3 @@ def get_lib_version():
except metadata.PackageNotFoundError:
libver = "99.99.99"
return libver
def format_error_message(host_error: str, exception: BaseException) -> str:
if not exception.args:
return f"Error connecting to {host_error}."
elif len(exception.args) == 1:
return f"Error {exception.args[0]} connecting to {host_error}."
else:
return (
f"Error {exception.args[0]} connecting to {host_error}. "
f"{exception.args[1]}."
)
def compare_versions(version1: str, version2: str) -> int:
"""
Compare two versions.
:return: -1 if version1 > version2
0 if both versions are equal
1 if version1 < version2
"""
num_versions1 = list(map(int, version1.split(".")))
num_versions2 = list(map(int, version2.split(".")))
if len(num_versions1) > len(num_versions2):
diff = len(num_versions1) - len(num_versions2)
for _ in range(diff):
num_versions2.append(0)
elif len(num_versions1) < len(num_versions2):
diff = len(num_versions2) - len(num_versions1)
for _ in range(diff):
num_versions1.append(0)
for i, ver in enumerate(num_versions1):
if num_versions1[i] > num_versions2[i]:
return -1
elif num_versions1[i] < num_versions2[i]:
return 1
return 0
def ensure_string(key):
if isinstance(key, bytes):
return key.decode("utf-8")
elif isinstance(key, str):
return key
else:
raise TypeError("Key must be either a string or bytes")
def extract_expire_flags(
ex: Optional[ExpiryT] = None,
px: Optional[ExpiryT] = None,
exat: Optional[AbsExpiryT] = None,
pxat: Optional[AbsExpiryT] = None,
) -> List[EncodableT]:
exp_options: list[EncodableT] = []
if ex is not None:
exp_options.append("EX")
if isinstance(ex, datetime.timedelta):
exp_options.append(int(ex.total_seconds()))
elif isinstance(ex, int):
exp_options.append(ex)
elif isinstance(ex, str) and ex.isdigit():
exp_options.append(int(ex))
else:
raise DataError("ex must be datetime.timedelta or int")
elif px is not None:
exp_options.append("PX")
if isinstance(px, datetime.timedelta):
exp_options.append(int(px.total_seconds() * 1000))
elif isinstance(px, int):
exp_options.append(px)
else:
raise DataError("px must be datetime.timedelta or int")
elif exat is not None:
if isinstance(exat, datetime.datetime):
exat = int(exat.timestamp())
exp_options.extend(["EXAT", exat])
elif pxat is not None:
if isinstance(pxat, datetime.datetime):
pxat = int(pxat.timestamp() * 1000)
exp_options.extend(["PXAT", pxat])
return exp_options
def truncate_text(txt, max_length=100):
return textwrap.shorten(
text=txt, width=max_length, placeholder="...", break_long_words=True
)