1from __future__ import annotations
2
3from functools import reduce
4from typing import (
5 TYPE_CHECKING,
6 Any,
7)
8
9import numpy as np
10
11from pandas._config.config import _global_config as config
12
13if TYPE_CHECKING:
14 from pandas._typing import DtypeObj
15
16
17def ensure_decoded(s: str | bytes) -> str:
18 """
19 If we have bytes, decode them to unicode.
20 """
21 if isinstance(s, (np.bytes_, bytes)):
22 s = s.decode(config["display"]["encoding"])
23 return s
24
25
26def result_type_many(*arrays_and_dtypes: Any) -> DtypeObj:
27 """
28 Wrapper around numpy.result_type which overcomes the NPY_MAXARGS (32)
29 argument limit.
30 """
31 try:
32 return np.result_type(*arrays_and_dtypes)
33 except ValueError:
34 # we have > NPY_MAXARGS terms in our expression
35 return reduce(np.result_type, arrays_and_dtypes)
36 except TypeError:
37 from pandas.core.dtypes.cast import find_common_type
38 from pandas.core.dtypes.common import is_extension_array_dtype
39
40 arr_and_dtypes = list(arrays_and_dtypes)
41 ea_dtypes, non_ea_dtypes = [], []
42 for arr_or_dtype in arr_and_dtypes:
43 if is_extension_array_dtype(arr_or_dtype):
44 ea_dtypes.append(arr_or_dtype)
45 else:
46 non_ea_dtypes.append(arr_or_dtype)
47
48 if non_ea_dtypes:
49 try:
50 np_dtype = np.result_type(*non_ea_dtypes)
51 except ValueError:
52 np_dtype = reduce(np.result_type, arrays_and_dtypes)
53 return find_common_type([*ea_dtypes, np_dtype])
54
55 return find_common_type(ea_dtypes)