1"""
2Templates for invalid operations.
3"""
4from __future__ import annotations
5
6import operator
7from typing import TYPE_CHECKING
8
9import numpy as np
10
11if TYPE_CHECKING:
12 from pandas._typing import npt
13
14
15def invalid_comparison(left, right, op) -> npt.NDArray[np.bool_]:
16 """
17 If a comparison has mismatched types and is not necessarily meaningful,
18 follow python3 conventions by:
19
20 - returning all-False for equality
21 - returning all-True for inequality
22 - raising TypeError otherwise
23
24 Parameters
25 ----------
26 left : array-like
27 right : scalar, array-like
28 op : operator.{eq, ne, lt, le, gt}
29
30 Raises
31 ------
32 TypeError : on inequality comparisons
33 """
34 if op is operator.eq:
35 res_values = np.zeros(left.shape, dtype=bool)
36 elif op is operator.ne:
37 res_values = np.ones(left.shape, dtype=bool)
38 else:
39 typ = type(right).__name__
40 raise TypeError(f"Invalid comparison between dtype={left.dtype} and {typ}")
41 return res_values
42
43
44def make_invalid_op(name: str):
45 """
46 Return a binary method that always raises a TypeError.
47
48 Parameters
49 ----------
50 name : str
51
52 Returns
53 -------
54 invalid_op : function
55 """
56
57 def invalid_op(self, other=None):
58 typ = type(self).__name__
59 raise TypeError(f"cannot perform {name} with this index type: {typ}")
60
61 invalid_op.__name__ = name
62 return invalid_op