Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pandas/core/ops/common.py: 24%
51 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2Boilerplate functions used in defining binary operations.
3"""
4from __future__ import annotations
6from functools import wraps
7from typing import Callable
9from pandas._libs.lib import item_from_zerodim
10from pandas._libs.missing import is_matching_na
11from pandas._typing import F
13from pandas.core.dtypes.generic import (
14 ABCDataFrame,
15 ABCIndex,
16 ABCSeries,
17)
20def unpack_zerodim_and_defer(name: str) -> Callable[[F], F]:
21 """
22 Boilerplate for pandas conventions in arithmetic and comparison methods.
24 Parameters
25 ----------
26 name : str
28 Returns
29 -------
30 decorator
31 """
33 def wrapper(method: F) -> F:
34 return _unpack_zerodim_and_defer(method, name)
36 return wrapper
39def _unpack_zerodim_and_defer(method, name: str):
40 """
41 Boilerplate for pandas conventions in arithmetic and comparison methods.
43 Ensure method returns NotImplemented when operating against "senior"
44 classes. Ensure zero-dimensional ndarrays are always unpacked.
46 Parameters
47 ----------
48 method : binary method
49 name : str
51 Returns
52 -------
53 method
54 """
55 is_cmp = name.strip("__") in {"eq", "ne", "lt", "le", "gt", "ge"}
57 @wraps(method)
58 def new_method(self, other):
60 if is_cmp and isinstance(self, ABCIndex) and isinstance(other, ABCSeries):
61 # For comparison ops, Index does *not* defer to Series
62 pass
63 else:
64 for cls in [ABCDataFrame, ABCSeries, ABCIndex]:
65 if isinstance(self, cls):
66 break
67 if isinstance(other, cls):
68 return NotImplemented
70 other = item_from_zerodim(other)
72 return method(self, other)
74 return new_method
77def get_op_result_name(left, right):
78 """
79 Find the appropriate name to pin to an operation result. This result
80 should always be either an Index or a Series.
82 Parameters
83 ----------
84 left : {Series, Index}
85 right : object
87 Returns
88 -------
89 name : object
90 Usually a string
91 """
92 if isinstance(right, (ABCSeries, ABCIndex)):
93 name = _maybe_match_name(left, right)
94 else:
95 name = left.name
96 return name
99def _maybe_match_name(a, b):
100 """
101 Try to find a name to attach to the result of an operation between
102 a and b. If only one of these has a `name` attribute, return that
103 name. Otherwise return a consensus name if they match or None if
104 they have different names.
106 Parameters
107 ----------
108 a : object
109 b : object
111 Returns
112 -------
113 name : str or None
115 See Also
116 --------
117 pandas.core.common.consensus_name_attr
118 """
119 a_has = hasattr(a, "name")
120 b_has = hasattr(b, "name")
121 if a_has and b_has:
122 try:
123 if a.name == b.name:
124 return a.name
125 elif is_matching_na(a.name, b.name):
126 # e.g. both are np.nan
127 return a.name
128 else:
129 return None
130 except TypeError:
131 # pd.NA
132 if is_matching_na(a.name, b.name):
133 return a.name
134 return None
135 except ValueError:
136 # e.g. np.int64(1) vs (np.int64(1), np.int64(2))
137 return None
138 elif a_has:
139 return a.name
140 elif b_has:
141 return b.name
142 return None