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

1""" 

2Boilerplate functions used in defining binary operations. 

3""" 

4from __future__ import annotations 

5 

6from functools import wraps 

7from typing import Callable 

8 

9from pandas._libs.lib import item_from_zerodim 

10from pandas._libs.missing import is_matching_na 

11from pandas._typing import F 

12 

13from pandas.core.dtypes.generic import ( 

14 ABCDataFrame, 

15 ABCIndex, 

16 ABCSeries, 

17) 

18 

19 

20def unpack_zerodim_and_defer(name: str) -> Callable[[F], F]: 

21 """ 

22 Boilerplate for pandas conventions in arithmetic and comparison methods. 

23 

24 Parameters 

25 ---------- 

26 name : str 

27 

28 Returns 

29 ------- 

30 decorator 

31 """ 

32 

33 def wrapper(method: F) -> F: 

34 return _unpack_zerodim_and_defer(method, name) 

35 

36 return wrapper 

37 

38 

39def _unpack_zerodim_and_defer(method, name: str): 

40 """ 

41 Boilerplate for pandas conventions in arithmetic and comparison methods. 

42 

43 Ensure method returns NotImplemented when operating against "senior" 

44 classes. Ensure zero-dimensional ndarrays are always unpacked. 

45 

46 Parameters 

47 ---------- 

48 method : binary method 

49 name : str 

50 

51 Returns 

52 ------- 

53 method 

54 """ 

55 is_cmp = name.strip("__") in {"eq", "ne", "lt", "le", "gt", "ge"} 

56 

57 @wraps(method) 

58 def new_method(self, other): 

59 

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 

69 

70 other = item_from_zerodim(other) 

71 

72 return method(self, other) 

73 

74 return new_method 

75 

76 

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. 

81 

82 Parameters 

83 ---------- 

84 left : {Series, Index} 

85 right : object 

86 

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 

97 

98 

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. 

105 

106 Parameters 

107 ---------- 

108 a : object 

109 b : object 

110 

111 Returns 

112 ------- 

113 name : str or None 

114 

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