Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/attr/_cmp.py
7763 views
1
# SPDX-License-Identifier: MIT
2
3
from __future__ import absolute_import, division, print_function
4
5
import functools
6
7
from ._compat import new_class
8
from ._make import _make_ne
9
10
11
_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="}
12
13
14
def cmp_using(
15
eq=None,
16
lt=None,
17
le=None,
18
gt=None,
19
ge=None,
20
require_same_type=True,
21
class_name="Comparable",
22
):
23
"""
24
Create a class that can be passed into `attr.ib`'s ``eq``, ``order``, and
25
``cmp`` arguments to customize field comparison.
26
27
The resulting class will have a full set of ordering methods if
28
at least one of ``{lt, le, gt, ge}`` and ``eq`` are provided.
29
30
:param Optional[callable] eq: `callable` used to evaluate equality
31
of two objects.
32
:param Optional[callable] lt: `callable` used to evaluate whether
33
one object is less than another object.
34
:param Optional[callable] le: `callable` used to evaluate whether
35
one object is less than or equal to another object.
36
:param Optional[callable] gt: `callable` used to evaluate whether
37
one object is greater than another object.
38
:param Optional[callable] ge: `callable` used to evaluate whether
39
one object is greater than or equal to another object.
40
41
:param bool require_same_type: When `True`, equality and ordering methods
42
will return `NotImplemented` if objects are not of the same type.
43
44
:param Optional[str] class_name: Name of class. Defaults to 'Comparable'.
45
46
See `comparison` for more details.
47
48
.. versionadded:: 21.1.0
49
"""
50
51
body = {
52
"__slots__": ["value"],
53
"__init__": _make_init(),
54
"_requirements": [],
55
"_is_comparable_to": _is_comparable_to,
56
}
57
58
# Add operations.
59
num_order_functions = 0
60
has_eq_function = False
61
62
if eq is not None:
63
has_eq_function = True
64
body["__eq__"] = _make_operator("eq", eq)
65
body["__ne__"] = _make_ne()
66
67
if lt is not None:
68
num_order_functions += 1
69
body["__lt__"] = _make_operator("lt", lt)
70
71
if le is not None:
72
num_order_functions += 1
73
body["__le__"] = _make_operator("le", le)
74
75
if gt is not None:
76
num_order_functions += 1
77
body["__gt__"] = _make_operator("gt", gt)
78
79
if ge is not None:
80
num_order_functions += 1
81
body["__ge__"] = _make_operator("ge", ge)
82
83
type_ = new_class(class_name, (object,), {}, lambda ns: ns.update(body))
84
85
# Add same type requirement.
86
if require_same_type:
87
type_._requirements.append(_check_same_type)
88
89
# Add total ordering if at least one operation was defined.
90
if 0 < num_order_functions < 4:
91
if not has_eq_function:
92
# functools.total_ordering requires __eq__ to be defined,
93
# so raise early error here to keep a nice stack.
94
raise ValueError(
95
"eq must be define is order to complete ordering from "
96
"lt, le, gt, ge."
97
)
98
type_ = functools.total_ordering(type_)
99
100
return type_
101
102
103
def _make_init():
104
"""
105
Create __init__ method.
106
"""
107
108
def __init__(self, value):
109
"""
110
Initialize object with *value*.
111
"""
112
self.value = value
113
114
return __init__
115
116
117
def _make_operator(name, func):
118
"""
119
Create operator method.
120
"""
121
122
def method(self, other):
123
if not self._is_comparable_to(other):
124
return NotImplemented
125
126
result = func(self.value, other.value)
127
if result is NotImplemented:
128
return NotImplemented
129
130
return result
131
132
method.__name__ = "__%s__" % (name,)
133
method.__doc__ = "Return a %s b. Computed by attrs." % (
134
_operation_names[name],
135
)
136
137
return method
138
139
140
def _is_comparable_to(self, other):
141
"""
142
Check whether `other` is comparable to `self`.
143
"""
144
for func in self._requirements:
145
if not func(self, other):
146
return False
147
return True
148
149
150
def _check_same_type(self, other):
151
"""
152
Return True if *self* and *other* are of the same type, False otherwise.
153
"""
154
return other.value.__class__ is self.value.__class__
155
156