Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/redis/utils.py: 65%
79 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 06:16 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 06:16 +0000
1import logging
2import sys
3from contextlib import contextmanager
4from functools import wraps
5from typing import Any, Dict, Mapping, Union
7try:
8 import hiredis # noqa
10 # Only support Hiredis >= 1.0:
11 HIREDIS_AVAILABLE = not hiredis.__version__.startswith("0.")
12 HIREDIS_PACK_AVAILABLE = hasattr(hiredis, "pack_command")
13except ImportError:
14 HIREDIS_AVAILABLE = False
15 HIREDIS_PACK_AVAILABLE = False
17try:
18 import ssl # noqa
20 SSL_AVAILABLE = True
21except ImportError:
22 SSL_AVAILABLE = False
24try:
25 import cryptography # noqa
27 CRYPTOGRAPHY_AVAILABLE = True
28except ImportError:
29 CRYPTOGRAPHY_AVAILABLE = False
31if sys.version_info >= (3, 8):
32 from importlib import metadata
33else:
34 import importlib_metadata as metadata
37def from_url(url, **kwargs):
38 """
39 Returns an active Redis client generated from the given database URL.
41 Will attempt to extract the database id from the path url fragment, if
42 none is provided.
43 """
44 from redis.client import Redis
46 return Redis.from_url(url, **kwargs)
49@contextmanager
50def pipeline(redis_obj):
51 p = redis_obj.pipeline()
52 yield p
53 p.execute()
56def str_if_bytes(value: Union[str, bytes]) -> str:
57 return (
58 value.decode("utf-8", errors="replace") if isinstance(value, bytes) else value
59 )
62def safe_str(value):
63 return str(str_if_bytes(value))
66def dict_merge(*dicts: Mapping[str, Any]) -> Dict[str, Any]:
67 """
68 Merge all provided dicts into 1 dict.
69 *dicts : `dict`
70 dictionaries to merge
71 """
72 merged = {}
74 for d in dicts:
75 merged.update(d)
77 return merged
80def list_keys_to_dict(key_list, callback):
81 return dict.fromkeys(key_list, callback)
84def merge_result(command, res):
85 """
86 Merge all items in `res` into a list.
88 This command is used when sending a command to multiple nodes
89 and the result from each node should be merged into a single list.
91 res : 'dict'
92 """
93 result = set()
95 for v in res.values():
96 for value in v:
97 result.add(value)
99 return list(result)
102def warn_deprecated(name, reason="", version="", stacklevel=2):
103 import warnings
105 msg = f"Call to deprecated {name}."
106 if reason:
107 msg += f" ({reason})"
108 if version:
109 msg += f" -- Deprecated since version {version}."
110 warnings.warn(msg, category=DeprecationWarning, stacklevel=stacklevel)
113def deprecated_function(reason="", version="", name=None):
114 """
115 Decorator to mark a function as deprecated.
116 """
118 def decorator(func):
119 @wraps(func)
120 def wrapper(*args, **kwargs):
121 warn_deprecated(name or func.__name__, reason, version, stacklevel=3)
122 return func(*args, **kwargs)
124 return wrapper
126 return decorator
129def _set_info_logger():
130 """
131 Set up a logger that log info logs to stdout.
132 (This is used by the default push response handler)
133 """
134 if "push_response" not in logging.root.manager.loggerDict.keys():
135 logger = logging.getLogger("push_response")
136 logger.setLevel(logging.INFO)
137 handler = logging.StreamHandler()
138 handler.setLevel(logging.INFO)
139 logger.addHandler(handler)
142def get_lib_version():
143 try:
144 libver = metadata.version("redis")
145 except metadata.PackageNotFoundError:
146 libver = "99.99.99"
147 return libver