hive-nectar 0.2.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hive_nectar-0.2.9.dist-info/METADATA +194 -0
- hive_nectar-0.2.9.dist-info/RECORD +87 -0
- hive_nectar-0.2.9.dist-info/WHEEL +4 -0
- hive_nectar-0.2.9.dist-info/entry_points.txt +2 -0
- hive_nectar-0.2.9.dist-info/licenses/LICENSE.txt +23 -0
- nectar/__init__.py +37 -0
- nectar/account.py +5076 -0
- nectar/amount.py +553 -0
- nectar/asciichart.py +303 -0
- nectar/asset.py +122 -0
- nectar/block.py +574 -0
- nectar/blockchain.py +1242 -0
- nectar/blockchaininstance.py +2590 -0
- nectar/blockchainobject.py +263 -0
- nectar/cli.py +5937 -0
- nectar/comment.py +1552 -0
- nectar/community.py +854 -0
- nectar/constants.py +95 -0
- nectar/discussions.py +1437 -0
- nectar/exceptions.py +152 -0
- nectar/haf.py +381 -0
- nectar/hive.py +630 -0
- nectar/imageuploader.py +114 -0
- nectar/instance.py +113 -0
- nectar/market.py +876 -0
- nectar/memo.py +542 -0
- nectar/message.py +379 -0
- nectar/nodelist.py +309 -0
- nectar/price.py +603 -0
- nectar/profile.py +74 -0
- nectar/py.typed +0 -0
- nectar/rc.py +333 -0
- nectar/snapshot.py +1024 -0
- nectar/storage.py +62 -0
- nectar/transactionbuilder.py +659 -0
- nectar/utils.py +630 -0
- nectar/version.py +3 -0
- nectar/vote.py +722 -0
- nectar/wallet.py +472 -0
- nectar/witness.py +728 -0
- nectarapi/__init__.py +12 -0
- nectarapi/exceptions.py +126 -0
- nectarapi/graphenerpc.py +596 -0
- nectarapi/node.py +194 -0
- nectarapi/noderpc.py +79 -0
- nectarapi/openapi.py +107 -0
- nectarapi/py.typed +0 -0
- nectarapi/rpcutils.py +98 -0
- nectarapi/version.py +3 -0
- nectarbase/__init__.py +15 -0
- nectarbase/ledgertransactions.py +106 -0
- nectarbase/memo.py +242 -0
- nectarbase/objects.py +521 -0
- nectarbase/objecttypes.py +21 -0
- nectarbase/operationids.py +102 -0
- nectarbase/operations.py +1357 -0
- nectarbase/py.typed +0 -0
- nectarbase/signedtransactions.py +89 -0
- nectarbase/transactions.py +11 -0
- nectarbase/version.py +3 -0
- nectargraphenebase/__init__.py +27 -0
- nectargraphenebase/account.py +1121 -0
- nectargraphenebase/aes.py +49 -0
- nectargraphenebase/base58.py +197 -0
- nectargraphenebase/bip32.py +575 -0
- nectargraphenebase/bip38.py +110 -0
- nectargraphenebase/chains.py +15 -0
- nectargraphenebase/dictionary.py +2 -0
- nectargraphenebase/ecdsasig.py +309 -0
- nectargraphenebase/objects.py +130 -0
- nectargraphenebase/objecttypes.py +8 -0
- nectargraphenebase/operationids.py +5 -0
- nectargraphenebase/operations.py +25 -0
- nectargraphenebase/prefix.py +13 -0
- nectargraphenebase/py.typed +0 -0
- nectargraphenebase/signedtransactions.py +221 -0
- nectargraphenebase/types.py +557 -0
- nectargraphenebase/unsignedtransactions.py +288 -0
- nectargraphenebase/version.py +3 -0
- nectarstorage/__init__.py +57 -0
- nectarstorage/base.py +317 -0
- nectarstorage/exceptions.py +15 -0
- nectarstorage/interfaces.py +244 -0
- nectarstorage/masterpassword.py +237 -0
- nectarstorage/py.typed +0 -0
- nectarstorage/ram.py +27 -0
- nectarstorage/sqlite.py +343 -0
nectar/asciichart.py
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from math import ceil, floor
|
|
3
|
+
from typing import List, Optional, Union
|
|
4
|
+
|
|
5
|
+
# Basic idea from https://github.com/kroitor/asciichart
|
|
6
|
+
# ╱ ╲ ╳ ─ └┲┲┲─
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AsciiChart:
|
|
10
|
+
"""Can be used to plot price and trade history
|
|
11
|
+
|
|
12
|
+
:param int height: Height of the plot
|
|
13
|
+
:param int width: Width of the plot
|
|
14
|
+
:param int offset: Offset between tick strings and y-axis (default is 3)
|
|
15
|
+
:param str placeholder: Defines how the numbers on the y-axes are formatted (default is '{:8.2f}')
|
|
16
|
+
:param str charset: sets the charset for plotting, uft8 or ascii (default: utf8)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
height: Optional[int] = None,
|
|
22
|
+
width: Optional[int] = None,
|
|
23
|
+
offset: int = 3,
|
|
24
|
+
placeholder: str = "{:8.2f} ",
|
|
25
|
+
charset: str = "utf8",
|
|
26
|
+
) -> None:
|
|
27
|
+
self.height = height
|
|
28
|
+
self.width = width
|
|
29
|
+
self.offset = offset
|
|
30
|
+
self.placeholder = placeholder
|
|
31
|
+
self.clear_data()
|
|
32
|
+
if charset == "ascii" or sys.version_info[0] < 3:
|
|
33
|
+
self.char_set = {
|
|
34
|
+
"first_axis_elem": "|",
|
|
35
|
+
"axis_elem": "|",
|
|
36
|
+
"axis_elem_with_graph": "|",
|
|
37
|
+
"curve_ar": "\\",
|
|
38
|
+
"curve_lb": "\\",
|
|
39
|
+
"curve_br": "/",
|
|
40
|
+
"curve_la": "/",
|
|
41
|
+
"curve_hl": "-",
|
|
42
|
+
"curve_vl": "|",
|
|
43
|
+
"curve_hl_dot": "-",
|
|
44
|
+
"curve_vl_dot": "|",
|
|
45
|
+
}
|
|
46
|
+
else:
|
|
47
|
+
self.char_set = {
|
|
48
|
+
"first_axis_elem": "┼",
|
|
49
|
+
"axis_elem": "┤",
|
|
50
|
+
"axis_elem_with_graph": "┼",
|
|
51
|
+
"curve_ar": "╰",
|
|
52
|
+
"curve_lb": "╮",
|
|
53
|
+
"curve_br": "╭",
|
|
54
|
+
"curve_la": "╯",
|
|
55
|
+
"curve_hl": "─",
|
|
56
|
+
"curve_vl": "│",
|
|
57
|
+
"curve_hl_dot": "┈",
|
|
58
|
+
"curve_vl_dot": "┊",
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def clear_data(self) -> None:
|
|
62
|
+
"""Clears all data"""
|
|
63
|
+
self.canvas = []
|
|
64
|
+
self.minimum = None
|
|
65
|
+
self.maximum = None
|
|
66
|
+
self.n = None
|
|
67
|
+
self.skip = 1
|
|
68
|
+
|
|
69
|
+
def set_parameter(
|
|
70
|
+
self,
|
|
71
|
+
height: Optional[int] = None,
|
|
72
|
+
offset: Optional[int] = None,
|
|
73
|
+
placeholder: Optional[str] = None,
|
|
74
|
+
) -> None:
|
|
75
|
+
"""Can be used to change parameter"""
|
|
76
|
+
if height is not None:
|
|
77
|
+
self.height = height
|
|
78
|
+
if offset is not None:
|
|
79
|
+
self.offset = offset
|
|
80
|
+
if placeholder is not None:
|
|
81
|
+
self.placeholder = placeholder
|
|
82
|
+
self._calc_plot_parameter()
|
|
83
|
+
|
|
84
|
+
def adapt_on_series(self, series: List[Union[int, float]]) -> None:
|
|
85
|
+
"""Calculates the minimum, maximum and length from the given list
|
|
86
|
+
|
|
87
|
+
:param list series: time series to plot
|
|
88
|
+
|
|
89
|
+
.. testcode::
|
|
90
|
+
|
|
91
|
+
from nectar.asciichart import AsciiChart
|
|
92
|
+
chart = AsciiChart()
|
|
93
|
+
series = [1, 2, 3, 7, 2, -4, -2]
|
|
94
|
+
chart.adapt_on_series(series)
|
|
95
|
+
chart.new_chart()
|
|
96
|
+
chart.add_axis()
|
|
97
|
+
chart.add_curve(series)
|
|
98
|
+
print(str(chart))
|
|
99
|
+
|
|
100
|
+
"""
|
|
101
|
+
self.minimum = min(series)
|
|
102
|
+
self.maximum = max(series)
|
|
103
|
+
self.n = len(series)
|
|
104
|
+
self._calc_plot_parameter()
|
|
105
|
+
|
|
106
|
+
def _calc_plot_parameter(
|
|
107
|
+
self,
|
|
108
|
+
minimum: Optional[Union[int, float]] = None,
|
|
109
|
+
maximum: Optional[Union[int, float]] = None,
|
|
110
|
+
n: Optional[int] = None,
|
|
111
|
+
) -> None:
|
|
112
|
+
"""Calculates parameter from minimum, maximum and length"""
|
|
113
|
+
if minimum is not None:
|
|
114
|
+
self.minimum = minimum
|
|
115
|
+
if maximum is not None:
|
|
116
|
+
self.maximum = maximum
|
|
117
|
+
if n is not None:
|
|
118
|
+
self.n = n
|
|
119
|
+
if self.n is None or self.maximum is None or self.minimum is None:
|
|
120
|
+
return
|
|
121
|
+
interval = abs(float(self.maximum) - float(self.minimum))
|
|
122
|
+
if interval == 0:
|
|
123
|
+
interval = 1
|
|
124
|
+
if self.height is None:
|
|
125
|
+
self.height = interval
|
|
126
|
+
self.ratio = self.height / interval
|
|
127
|
+
self.min2 = floor(float(self.minimum) * self.ratio)
|
|
128
|
+
self.max2 = ceil(float(self.maximum) * self.ratio)
|
|
129
|
+
if self.min2 == self.max2:
|
|
130
|
+
self.max2 += 1
|
|
131
|
+
intmin2 = int(self.min2)
|
|
132
|
+
intmax2 = int(self.max2)
|
|
133
|
+
self.rows = abs(intmax2 - intmin2)
|
|
134
|
+
if self.width is not None:
|
|
135
|
+
self.skip = int(self.n / self.width)
|
|
136
|
+
if self.skip < 1:
|
|
137
|
+
self.skip = 1
|
|
138
|
+
else:
|
|
139
|
+
self.skip = 1
|
|
140
|
+
|
|
141
|
+
def plot(self, series: List[Union[int, float]], return_str: bool = False) -> Optional[str]:
|
|
142
|
+
"""All in one function for plotting
|
|
143
|
+
|
|
144
|
+
.. testcode::
|
|
145
|
+
|
|
146
|
+
from nectar.asciichart import AsciiChart
|
|
147
|
+
chart = AsciiChart()
|
|
148
|
+
series = [1, 2, 3, 7, 2, -4, -2]
|
|
149
|
+
chart.plot(series)
|
|
150
|
+
"""
|
|
151
|
+
self.clear_data()
|
|
152
|
+
self.adapt_on_series(series)
|
|
153
|
+
self.new_chart()
|
|
154
|
+
self.add_axis()
|
|
155
|
+
self.add_curve(series)
|
|
156
|
+
if not return_str:
|
|
157
|
+
print(str(self))
|
|
158
|
+
else:
|
|
159
|
+
return str(self)
|
|
160
|
+
|
|
161
|
+
def new_chart(
|
|
162
|
+
self,
|
|
163
|
+
minimum: Optional[Union[int, float]] = None,
|
|
164
|
+
maximum: Optional[Union[int, float]] = None,
|
|
165
|
+
n: Optional[int] = None,
|
|
166
|
+
) -> None:
|
|
167
|
+
"""Clears the canvas
|
|
168
|
+
|
|
169
|
+
.. testcode::
|
|
170
|
+
|
|
171
|
+
from nectar.asciichart import AsciiChart
|
|
172
|
+
chart = AsciiChart()
|
|
173
|
+
series = [1, 2, 3, 7, 2, -4, -2]
|
|
174
|
+
chart.adapt_on_series(series)
|
|
175
|
+
chart.new_chart()
|
|
176
|
+
chart.add_axis()
|
|
177
|
+
chart.add_curve(series)
|
|
178
|
+
print(str(chart))
|
|
179
|
+
|
|
180
|
+
"""
|
|
181
|
+
if minimum is not None:
|
|
182
|
+
self.minimum = minimum
|
|
183
|
+
if maximum is not None:
|
|
184
|
+
self.maximum = maximum
|
|
185
|
+
if n is not None:
|
|
186
|
+
self.n = n
|
|
187
|
+
self._calc_plot_parameter()
|
|
188
|
+
if self.n is None or self.rows is None:
|
|
189
|
+
return
|
|
190
|
+
self.canvas = [
|
|
191
|
+
[" "] * (int(self.n / (self.skip or 1)) + self.offset) for i in range(self.rows + 1)
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
def add_axis(self) -> None:
|
|
195
|
+
"""Adds a y-axis to the canvas
|
|
196
|
+
|
|
197
|
+
.. testcode::
|
|
198
|
+
|
|
199
|
+
from nectar.asciichart import AsciiChart
|
|
200
|
+
chart = AsciiChart()
|
|
201
|
+
series = [1, 2, 3, 7, 2, -4, -2]
|
|
202
|
+
chart.adapt_on_series(series)
|
|
203
|
+
chart.new_chart()
|
|
204
|
+
chart.add_axis()
|
|
205
|
+
chart.add_curve(series)
|
|
206
|
+
print(str(chart))
|
|
207
|
+
|
|
208
|
+
"""
|
|
209
|
+
# axis and labels
|
|
210
|
+
if (
|
|
211
|
+
self.minimum is None
|
|
212
|
+
or self.maximum is None
|
|
213
|
+
or self.min2 is None
|
|
214
|
+
or self.max2 is None
|
|
215
|
+
or self.rows is None
|
|
216
|
+
):
|
|
217
|
+
# Chart was not initialized; nothing to render.
|
|
218
|
+
return
|
|
219
|
+
|
|
220
|
+
interval = abs(float(self.maximum) - float(self.minimum))
|
|
221
|
+
intmin2 = int(self.min2)
|
|
222
|
+
intmax2 = int(self.max2)
|
|
223
|
+
for y in range(intmin2, intmax2 + 1):
|
|
224
|
+
label = f"{float(self.maximum) - ((y - intmin2) * interval / self.rows)}"
|
|
225
|
+
if label:
|
|
226
|
+
self._set_y_axis_elem(y, label)
|
|
227
|
+
|
|
228
|
+
def _set_y_axis_elem(self, y: Union[int, float], label: str) -> None:
|
|
229
|
+
intmin2 = int(self.min2)
|
|
230
|
+
y_int = int(y)
|
|
231
|
+
self.canvas[y_int - intmin2][max(self.offset - len(label), 0)] = label
|
|
232
|
+
if y == 0:
|
|
233
|
+
self.canvas[y_int - intmin2][self.offset - 1] = self.char_set["first_axis_elem"]
|
|
234
|
+
else:
|
|
235
|
+
self.canvas[y_int - intmin2][self.offset - 1] = self.char_set["axis_elem"]
|
|
236
|
+
|
|
237
|
+
def _map_y(self, y_float: Union[int, float]) -> int:
|
|
238
|
+
intmin2 = int(self.min2)
|
|
239
|
+
return int(round(y_float * self.ratio) - intmin2)
|
|
240
|
+
|
|
241
|
+
def add_curve(self, series: List[Union[int, float]]) -> None:
|
|
242
|
+
"""Add a curve to the canvas
|
|
243
|
+
|
|
244
|
+
:param list series: List width float data points
|
|
245
|
+
|
|
246
|
+
.. testcode::
|
|
247
|
+
|
|
248
|
+
from nectar.asciichart import AsciiChart
|
|
249
|
+
chart = AsciiChart()
|
|
250
|
+
series = [1, 2, 3, 7, 2, -4, -2]
|
|
251
|
+
chart.adapt_on_series(series)
|
|
252
|
+
chart.new_chart()
|
|
253
|
+
chart.add_axis()
|
|
254
|
+
chart.add_curve(series)
|
|
255
|
+
print(str(chart))
|
|
256
|
+
|
|
257
|
+
"""
|
|
258
|
+
if self.n is None:
|
|
259
|
+
self.adapt_on_series(series)
|
|
260
|
+
if len(self.canvas) == 0:
|
|
261
|
+
self.new_chart()
|
|
262
|
+
y0 = self._map_y(series[0])
|
|
263
|
+
self._set_elem(y0, -1, self.char_set["axis_elem_with_graph"])
|
|
264
|
+
for x in range(0, len(series[:: self.skip]) - 1):
|
|
265
|
+
y0 = self._map_y(series[:: self.skip][x + 0])
|
|
266
|
+
y1 = self._map_y(series[:: self.skip][x + 1])
|
|
267
|
+
if y0 == y1:
|
|
268
|
+
self._draw_h_line(y0, x, x + 1, line=self.char_set["curve_hl"])
|
|
269
|
+
else:
|
|
270
|
+
self._draw_diag(y0, y1, x)
|
|
271
|
+
start = min(y0, y1) + 1
|
|
272
|
+
end = max(y0, y1)
|
|
273
|
+
self._draw_v_line(start, end, x, line=self.char_set["curve_vl"])
|
|
274
|
+
|
|
275
|
+
def _draw_diag(self, y0: Union[int, float], y1: Union[int, float], x: int) -> None:
|
|
276
|
+
"""Plot diagonal element"""
|
|
277
|
+
if y0 > y1:
|
|
278
|
+
c1 = self.char_set["curve_ar"]
|
|
279
|
+
c0 = self.char_set["curve_lb"]
|
|
280
|
+
else:
|
|
281
|
+
c1 = self.char_set["curve_br"]
|
|
282
|
+
c0 = self.char_set["curve_la"]
|
|
283
|
+
self._set_elem(int(y1), x, c1)
|
|
284
|
+
self._set_elem(int(y0), x, c0)
|
|
285
|
+
|
|
286
|
+
def _draw_h_line(self, y: Union[int, float], x_start: int, x_end: int, line: str = "-") -> None:
|
|
287
|
+
"""Plot horizontal line"""
|
|
288
|
+
for x in range(x_start, x_end):
|
|
289
|
+
self._set_elem(int(y), x, line)
|
|
290
|
+
|
|
291
|
+
def _draw_v_line(self, y_start: int, y_end: int, x: int, line: str = "|") -> None:
|
|
292
|
+
"""Plot vertical line"""
|
|
293
|
+
for y in range(y_start, y_end):
|
|
294
|
+
self._set_elem(y, x, line)
|
|
295
|
+
|
|
296
|
+
def _set_elem(self, y: int, x: int, c: str) -> None:
|
|
297
|
+
"""Plot signle element into canvas"""
|
|
298
|
+
self.canvas[self.rows - y][x + self.offset] = c
|
|
299
|
+
|
|
300
|
+
def __repr__(self) -> str:
|
|
301
|
+
return "\n".join(["".join(row) for row in self.canvas])
|
|
302
|
+
|
|
303
|
+
__str__ = __repr__
|
nectar/asset.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from typing import Any, Dict, Union, cast
|
|
2
|
+
|
|
3
|
+
from .blockchainobject import BlockchainObject
|
|
4
|
+
from .exceptions import AssetDoesNotExistsException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Asset(BlockchainObject):
|
|
8
|
+
"""Deals with Assets of the network.
|
|
9
|
+
|
|
10
|
+
:param str Asset: Symbol name or object id of an asset
|
|
11
|
+
:param bool lazy: Lazy loading
|
|
12
|
+
:param bool full: Also obtain bitasset-data and dynamic asset dat
|
|
13
|
+
:param Blockchain blockchain_instance: Blockchain instance
|
|
14
|
+
:returns: All data of an asset
|
|
15
|
+
|
|
16
|
+
.. note:: This class comes with its own caching function to reduce the
|
|
17
|
+
load on the API server. Instances of this class can be
|
|
18
|
+
refreshed with ``Asset.refresh()``.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
type_id = 3
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
asset: Union[str, int],
|
|
26
|
+
lazy: bool = False,
|
|
27
|
+
full: bool = False,
|
|
28
|
+
blockchain_instance: Any = None,
|
|
29
|
+
**kwargs,
|
|
30
|
+
) -> None:
|
|
31
|
+
self.full = full
|
|
32
|
+
super().__init__(
|
|
33
|
+
asset, lazy=lazy, full=full, blockchain_instance=blockchain_instance, **kwargs
|
|
34
|
+
)
|
|
35
|
+
# self.refresh()
|
|
36
|
+
|
|
37
|
+
def refresh(self) -> None:
|
|
38
|
+
"""Refresh the data from the API server"""
|
|
39
|
+
self.chain_params = self.blockchain.get_network()
|
|
40
|
+
if self.chain_params is None:
|
|
41
|
+
from nectargraphenebase.chains import known_chains
|
|
42
|
+
|
|
43
|
+
self.chain_params = known_chains["HIVE"]
|
|
44
|
+
cast(Dict[str, Any], self)["asset"] = ""
|
|
45
|
+
found_asset = False
|
|
46
|
+
|
|
47
|
+
# Store original identifier before it gets overwritten
|
|
48
|
+
original_identifier = self.identifier
|
|
49
|
+
if hasattr(original_identifier, "symbol"):
|
|
50
|
+
# If identifier is an Asset object, get its symbol
|
|
51
|
+
original_identifier = original_identifier.symbol
|
|
52
|
+
elif hasattr(original_identifier, "identifier"):
|
|
53
|
+
# If identifier has an identifier attribute, get its string representation
|
|
54
|
+
original_identifier = str(original_identifier)
|
|
55
|
+
elif not isinstance(original_identifier, (str, int)):
|
|
56
|
+
# Convert to string if it's not already a string or int
|
|
57
|
+
original_identifier = str(original_identifier)
|
|
58
|
+
|
|
59
|
+
for asset in self.chain_params["chain_assets"]:
|
|
60
|
+
if original_identifier in [asset["symbol"], str(asset["asset"]), str(asset["id"])]:
|
|
61
|
+
cast(Dict[str, Any], self)["asset"] = asset["asset"]
|
|
62
|
+
cast(Dict[str, Any], self)["precision"] = asset["precision"]
|
|
63
|
+
cast(Dict[str, Any], self)["id"] = asset["id"]
|
|
64
|
+
cast(Dict[str, Any], self)["symbol"] = asset["symbol"]
|
|
65
|
+
found_asset = True
|
|
66
|
+
break
|
|
67
|
+
if not found_asset:
|
|
68
|
+
raise AssetDoesNotExistsException(
|
|
69
|
+
f"{original_identifier} chain_assets:{self.chain_params['chain_assets']}"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def symbol(self) -> str:
|
|
74
|
+
return cast(Dict[str, Any], self)["symbol"]
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def asset(self) -> str:
|
|
78
|
+
return cast(Dict[str, Any], self)["asset"]
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def precision(self) -> int:
|
|
82
|
+
return cast(Dict[str, Any], self)["precision"]
|
|
83
|
+
|
|
84
|
+
def __eq__(self, other: object) -> bool:
|
|
85
|
+
if isinstance(other, Asset):
|
|
86
|
+
return (
|
|
87
|
+
cast(Dict[str, Any], self)["symbol"] == other["symbol"]
|
|
88
|
+
and cast(Dict[str, Any], self)["asset"] == other["asset"]
|
|
89
|
+
and cast(Dict[str, Any], self)["precision"] == other["precision"]
|
|
90
|
+
)
|
|
91
|
+
if isinstance(other, dict):
|
|
92
|
+
symbol = other["symbol"] if "symbol" in other else None
|
|
93
|
+
asset = other["asset"] if "asset" in other else None
|
|
94
|
+
precision = other["precision"] if "precision" in other else None
|
|
95
|
+
return (
|
|
96
|
+
cast(Dict[str, Any], self)["symbol"] == symbol
|
|
97
|
+
and cast(Dict[str, Any], self)["asset"] == asset
|
|
98
|
+
and cast(Dict[str, Any], self)["precision"] == precision
|
|
99
|
+
)
|
|
100
|
+
if isinstance(other, (str, int)):
|
|
101
|
+
return cast(Dict[str, Any], self)["symbol"] == other
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
def __ne__(self, other: object) -> bool:
|
|
105
|
+
if isinstance(other, Asset):
|
|
106
|
+
return (
|
|
107
|
+
cast(Dict[str, Any], self)["symbol"] != other["symbol"]
|
|
108
|
+
or cast(Dict[str, Any], self)["asset"] != other["asset"]
|
|
109
|
+
or cast(Dict[str, Any], self)["precision"] != other["precision"]
|
|
110
|
+
)
|
|
111
|
+
if isinstance(other, dict):
|
|
112
|
+
symbol = other["symbol"] if "symbol" in other else None
|
|
113
|
+
asset = other["asset"] if "asset" in other else None
|
|
114
|
+
precision = other["precision"] if "precision" in other else None
|
|
115
|
+
return (
|
|
116
|
+
cast(Dict[str, Any], self)["symbol"] != symbol
|
|
117
|
+
or cast(Dict[str, Any], self)["asset"] != asset
|
|
118
|
+
or cast(Dict[str, Any], self)["precision"] != precision
|
|
119
|
+
)
|
|
120
|
+
if isinstance(other, (str, int)):
|
|
121
|
+
return cast(Dict[str, Any], self)["symbol"] != other
|
|
122
|
+
return True
|