ccxt 4.2.77__py2.py3-none-any.whl → 4.4.49__py2.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.
Files changed (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +24 -0
  44. ccxt/abstract/kucoinfutures.py +34 -0
  45. ccxt/abstract/luno.py +2 -0
  46. ccxt/abstract/mexc.py +4 -0
  47. ccxt/abstract/myokx.py +340 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +30 -0
  50. ccxt/abstract/onetrading.py +0 -12
  51. ccxt/abstract/oxfun.py +34 -0
  52. ccxt/abstract/paradex.py +40 -0
  53. ccxt/abstract/phemex.py +1 -0
  54. ccxt/abstract/upbit.py +4 -0
  55. ccxt/abstract/vertex.py +19 -0
  56. ccxt/abstract/whitebit.py +31 -1
  57. ccxt/abstract/woo.py +6 -2
  58. ccxt/abstract/woofipro.py +119 -0
  59. ccxt/abstract/xt.py +153 -0
  60. ccxt/abstract/zonda.py +6 -0
  61. ccxt/ace.py +164 -60
  62. ccxt/alpaca.py +727 -63
  63. ccxt/ascendex.py +395 -249
  64. ccxt/async_support/__init__.py +36 -14
  65. ccxt/async_support/ace.py +164 -60
  66. ccxt/async_support/alpaca.py +727 -63
  67. ccxt/async_support/ascendex.py +396 -249
  68. ccxt/async_support/base/exchange.py +531 -155
  69. ccxt/async_support/base/ws/aiohttp_client.py +28 -5
  70. ccxt/async_support/base/ws/cache.py +3 -2
  71. ccxt/async_support/base/ws/client.py +26 -5
  72. ccxt/async_support/base/ws/fast_client.py +4 -3
  73. ccxt/async_support/base/ws/functions.py +1 -1
  74. ccxt/async_support/base/ws/future.py +40 -31
  75. ccxt/async_support/base/ws/order_book_side.py +3 -0
  76. ccxt/async_support/bequant.py +1 -1
  77. ccxt/async_support/bigone.py +329 -202
  78. ccxt/async_support/binance.py +3030 -1087
  79. ccxt/async_support/binancecoinm.py +2 -1
  80. ccxt/async_support/binanceus.py +12 -1
  81. ccxt/async_support/binanceusdm.py +3 -1
  82. ccxt/async_support/bingx.py +3205 -937
  83. ccxt/async_support/bit2c.py +119 -38
  84. ccxt/async_support/bitbank.py +215 -76
  85. ccxt/async_support/bitbns.py +124 -53
  86. ccxt/async_support/bitfinex.py +3236 -1078
  87. ccxt/async_support/bitfinex1.py +1711 -0
  88. ccxt/async_support/bitflyer.py +238 -49
  89. ccxt/async_support/bitget.py +1525 -573
  90. ccxt/async_support/bithumb.py +199 -65
  91. ccxt/async_support/bitmart.py +1320 -435
  92. ccxt/async_support/bitmex.py +308 -111
  93. ccxt/async_support/bitopro.py +256 -96
  94. ccxt/async_support/bitrue.py +365 -233
  95. ccxt/async_support/bitso.py +201 -89
  96. ccxt/async_support/bitstamp.py +438 -269
  97. ccxt/async_support/bitteam.py +179 -73
  98. ccxt/async_support/bitvavo.py +180 -70
  99. ccxt/async_support/bl3p.py +92 -25
  100. ccxt/async_support/blockchaincom.py +193 -79
  101. ccxt/async_support/blofin.py +392 -148
  102. ccxt/async_support/btcalpha.py +161 -55
  103. ccxt/async_support/btcbox.py +250 -34
  104. ccxt/async_support/btcmarkets.py +232 -85
  105. ccxt/async_support/btcturk.py +159 -60
  106. ccxt/async_support/bybit.py +2231 -1193
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1454 -287
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +223 -97
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +404 -109
  125. ccxt/async_support/deribit.py +639 -323
  126. ccxt/async_support/digifinex.py +465 -233
  127. ccxt/async_support/ellipx.py +1887 -0
  128. ccxt/async_support/exmo.py +317 -128
  129. ccxt/async_support/gate.py +1472 -463
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +433 -178
  133. ccxt/async_support/hollaex.py +207 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +178 -56
  136. ccxt/async_support/hyperliquid.py +1678 -292
  137. ccxt/async_support/idex.py +219 -95
  138. ccxt/async_support/independentreserve.py +300 -31
  139. ccxt/async_support/indodax.py +226 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +917 -357
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +198 -107
  145. ccxt/async_support/latoken.py +199 -79
  146. ccxt/async_support/lbank.py +360 -113
  147. ccxt/async_support/luno.py +185 -62
  148. ccxt/async_support/lykke.py +168 -55
  149. ccxt/async_support/mercado.py +101 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +53 -0
  152. ccxt/async_support/ndax.py +234 -82
  153. ccxt/async_support/novadax.py +195 -75
  154. ccxt/async_support/oceanex.py +244 -59
  155. ccxt/async_support/okcoin.py +301 -165
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +198 -414
  158. ccxt/async_support/oxfun.py +2898 -0
  159. ccxt/async_support/p2b.py +142 -52
  160. ccxt/async_support/paradex.py +2085 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1137 -296
  175. ccxt/async_support/woofipro.py +2716 -0
  176. ccxt/async_support/xt.py +4628 -0
  177. ccxt/async_support/yobit.py +160 -92
  178. ccxt/async_support/zaif.py +80 -33
  179. ccxt/async_support/zonda.py +140 -69
  180. ccxt/base/errors.py +51 -20
  181. ccxt/base/exchange.py +1722 -480
  182. ccxt/base/precise.py +10 -0
  183. ccxt/base/types.py +223 -4
  184. ccxt/bequant.py +1 -1
  185. ccxt/bigone.py +329 -202
  186. ccxt/binance.py +3030 -1087
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3205 -937
  191. ccxt/bit2c.py +119 -38
  192. ccxt/bitbank.py +215 -76
  193. ccxt/bitbns.py +124 -53
  194. ccxt/bitfinex.py +3235 -1078
  195. ccxt/bitfinex1.py +1710 -0
  196. ccxt/bitflyer.py +238 -49
  197. ccxt/bitget.py +1525 -573
  198. ccxt/bithumb.py +198 -65
  199. ccxt/bitmart.py +1320 -435
  200. ccxt/bitmex.py +308 -111
  201. ccxt/bitopro.py +256 -96
  202. ccxt/bitrue.py +365 -233
  203. ccxt/bitso.py +201 -89
  204. ccxt/bitstamp.py +438 -269
  205. ccxt/bitteam.py +179 -73
  206. ccxt/bitvavo.py +180 -70
  207. ccxt/bl3p.py +92 -25
  208. ccxt/blockchaincom.py +193 -79
  209. ccxt/blofin.py +392 -148
  210. ccxt/btcalpha.py +161 -55
  211. ccxt/btcbox.py +250 -34
  212. ccxt/btcmarkets.py +232 -85
  213. ccxt/btcturk.py +159 -60
  214. ccxt/bybit.py +2231 -1193
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1454 -287
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +223 -97
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +404 -109
  233. ccxt/deribit.py +639 -323
  234. ccxt/digifinex.py +465 -233
  235. ccxt/ellipx.py +1887 -0
  236. ccxt/exmo.py +317 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +433 -178
  241. ccxt/hollaex.py +207 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +178 -56
  244. ccxt/hyperliquid.py +1677 -292
  245. ccxt/idex.py +219 -95
  246. ccxt/independentreserve.py +299 -31
  247. ccxt/indodax.py +226 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +917 -357
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +198 -107
  253. ccxt/latoken.py +199 -79
  254. ccxt/lbank.py +360 -113
  255. ccxt/luno.py +185 -62
  256. ccxt/lykke.py +168 -55
  257. ccxt/mercado.py +101 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +53 -0
  260. ccxt/ndax.py +234 -82
  261. ccxt/novadax.py +195 -75
  262. ccxt/oceanex.py +244 -59
  263. ccxt/okcoin.py +301 -165
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +198 -414
  266. ccxt/oxfun.py +2897 -0
  267. ccxt/p2b.py +142 -52
  268. ccxt/paradex.py +2085 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +62 -14
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +143 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +203 -81
  293. ccxt/pro/blockchaincom.py +30 -17
  294. ccxt/pro/blofin.py +692 -0
  295. ccxt/pro/bybit.py +791 -82
  296. ccxt/pro/cex.py +99 -51
  297. ccxt/pro/coinbase.py +220 -30
  298. ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
  299. ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
  300. ccxt/pro/coinbaseinternational.py +193 -30
  301. ccxt/pro/coincatch.py +1464 -0
  302. ccxt/pro/coincheck.py +11 -6
  303. ccxt/pro/coinex.py +965 -665
  304. ccxt/pro/coinone.py +17 -10
  305. ccxt/pro/cryptocom.py +446 -66
  306. ccxt/pro/currencycom.py +11 -10
  307. ccxt/pro/defx.py +832 -0
  308. ccxt/pro/deribit.py +167 -31
  309. ccxt/pro/exmo.py +252 -20
  310. ccxt/pro/gate.py +729 -64
  311. ccxt/pro/gemini.py +44 -26
  312. ccxt/pro/hashkey.py +802 -0
  313. ccxt/pro/hitbtc.py +208 -103
  314. ccxt/pro/hollaex.py +25 -9
  315. ccxt/pro/htx.py +83 -39
  316. ccxt/pro/huobijp.py +17 -16
  317. ccxt/pro/hyperliquid.py +502 -31
  318. ccxt/pro/idex.py +28 -13
  319. ccxt/pro/independentreserve.py +21 -16
  320. ccxt/pro/kraken.py +298 -51
  321. ccxt/pro/krakenfutures.py +166 -75
  322. ccxt/pro/kucoin.py +395 -77
  323. ccxt/pro/kucoinfutures.py +400 -99
  324. ccxt/pro/lbank.py +52 -31
  325. ccxt/pro/luno.py +12 -10
  326. ccxt/pro/mexc.py +400 -50
  327. ccxt/pro/myokx.py +28 -0
  328. ccxt/pro/ndax.py +25 -12
  329. ccxt/pro/okcoin.py +28 -9
  330. ccxt/pro/okx.py +935 -124
  331. ccxt/pro/onetrading.py +41 -24
  332. ccxt/pro/oxfun.py +1054 -0
  333. ccxt/pro/p2b.py +100 -24
  334. ccxt/pro/paradex.py +352 -0
  335. ccxt/pro/phemex.py +92 -33
  336. ccxt/pro/poloniex.py +128 -49
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +92 -85
  339. ccxt/pro/upbit.py +401 -8
  340. ccxt/pro/vertex.py +943 -0
  341. ccxt/pro/wazirx.py +46 -28
  342. ccxt/pro/whitebit.py +65 -12
  343. ccxt/pro/woo.py +437 -65
  344. ccxt/pro/woofipro.py +1271 -0
  345. ccxt/pro/xt.py +1067 -0
  346. ccxt/probit.py +143 -110
  347. ccxt/static_dependencies/__init__.py +1 -1
  348. ccxt/static_dependencies/lark/__init__.py +38 -0
  349. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  350. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  351. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  352. ccxt/static_dependencies/lark/common.py +86 -0
  353. ccxt/static_dependencies/lark/exceptions.py +292 -0
  354. ccxt/static_dependencies/lark/grammar.py +130 -0
  355. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  356. ccxt/static_dependencies/lark/indenter.py +143 -0
  357. ccxt/static_dependencies/lark/lark.py +658 -0
  358. ccxt/static_dependencies/lark/lexer.py +678 -0
  359. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  360. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  361. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  362. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  363. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  364. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  365. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  366. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  367. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  368. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  369. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  370. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  371. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  372. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  373. ccxt/static_dependencies/lark/py.typed +0 -0
  374. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  375. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  376. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  377. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  378. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  379. ccxt/static_dependencies/lark/tree.py +267 -0
  380. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  381. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  382. ccxt/static_dependencies/lark/utils.py +343 -0
  383. ccxt/static_dependencies/lark/visitors.py +596 -0
  384. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  385. ccxt/static_dependencies/marshmallow/base.py +65 -0
  386. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  387. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  388. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  389. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  390. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  391. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  392. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  393. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  394. ccxt/static_dependencies/marshmallow/types.py +12 -0
  395. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  396. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  397. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  398. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  399. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  400. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  401. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  402. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  403. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  404. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  405. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  406. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  407. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  408. ccxt/static_dependencies/starknet/__init__.py +0 -0
  409. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  410. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  411. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  412. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  413. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  414. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  415. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  416. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  417. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  418. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  419. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  420. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  421. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  422. ccxt/static_dependencies/starknet/common.py +15 -0
  423. ccxt/static_dependencies/starknet/constants.py +39 -0
  424. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  425. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  426. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  427. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  428. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  429. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  430. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  431. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  432. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  433. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  434. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  435. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  436. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  437. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  438. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  439. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  440. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  441. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  442. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  443. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  444. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  445. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  446. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  447. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  448. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  449. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  450. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  451. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  452. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  453. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  454. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  455. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  456. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  457. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  458. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  459. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  460. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  461. ccxt/static_dependencies/starkware/__init__.py +0 -0
  462. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  463. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  464. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  465. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  466. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  467. ccxt/static_dependencies/sympy/__init__.py +0 -0
  468. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  469. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  470. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  471. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  472. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  473. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  474. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  475. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  476. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  477. ccxt/test/{test_async.py → tests_async.py} +456 -391
  478. ccxt/test/tests_helpers.py +285 -0
  479. ccxt/test/tests_init.py +39 -0
  480. ccxt/test/{test_sync.py → tests_sync.py} +456 -393
  481. ccxt/timex.py +123 -70
  482. ccxt/tokocrypto.py +129 -93
  483. ccxt/tradeogre.py +39 -25
  484. ccxt/upbit.py +322 -113
  485. ccxt/vertex.py +2983 -0
  486. ccxt/wavesexchange.py +227 -173
  487. ccxt/wazirx.py +145 -65
  488. ccxt/whitebit.py +533 -138
  489. ccxt/woo.py +1137 -296
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.49.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.49.dist-info/METADATA +646 -0
  497. ccxt-4.4.49.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.77.dist-info/METADATA +0 -626
  545. ccxt-4.2.77.dist-info/RECORD +0 -534
  546. {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,678 @@
1
+ # Lexer Implementation
2
+
3
+ from abc import abstractmethod, ABC
4
+ import re
5
+ from contextlib import suppress
6
+ from typing import (
7
+ TypeVar, Type, Dict, Iterator, Collection, Callable, Optional, FrozenSet, Any,
8
+ ClassVar, TYPE_CHECKING, overload
9
+ )
10
+ from types import ModuleType
11
+ import warnings
12
+ try:
13
+ import interegular
14
+ except ImportError:
15
+ pass
16
+ if TYPE_CHECKING:
17
+ from .common import LexerConf
18
+ from .parsers.lalr_parser_state import ParserState
19
+
20
+ from .utils import classify, get_regexp_width, Serialize, logger
21
+ from .exceptions import UnexpectedCharacters, LexError, UnexpectedToken
22
+ from .grammar import TOKEN_DEFAULT_PRIORITY
23
+
24
+
25
+ ###{standalone
26
+ from copy import copy
27
+
28
+ try: # For the standalone parser, we need to make sure that has_interegular is False to avoid NameErrors later on
29
+ has_interegular = bool(interegular)
30
+ except NameError:
31
+ has_interegular = False
32
+
33
+ class Pattern(Serialize, ABC):
34
+ "An abstraction over regular expressions."
35
+
36
+ value: str
37
+ flags: Collection[str]
38
+ raw: Optional[str]
39
+ type: ClassVar[str]
40
+
41
+ def __init__(self, value: str, flags: Collection[str] = (), raw: Optional[str] = None) -> None:
42
+ self.value = value
43
+ self.flags = frozenset(flags)
44
+ self.raw = raw
45
+
46
+ def __repr__(self):
47
+ return repr(self.to_regexp())
48
+
49
+ # Pattern Hashing assumes all subclasses have a different priority!
50
+ def __hash__(self):
51
+ return hash((type(self), self.value, self.flags))
52
+
53
+ def __eq__(self, other):
54
+ return type(self) == type(other) and self.value == other.value and self.flags == other.flags
55
+
56
+ @abstractmethod
57
+ def to_regexp(self) -> str:
58
+ raise NotImplementedError()
59
+
60
+ @property
61
+ @abstractmethod
62
+ def min_width(self) -> int:
63
+ raise NotImplementedError()
64
+
65
+ @property
66
+ @abstractmethod
67
+ def max_width(self) -> int:
68
+ raise NotImplementedError()
69
+
70
+ def _get_flags(self, value):
71
+ for f in self.flags:
72
+ value = ('(?%s:%s)' % (f, value))
73
+ return value
74
+
75
+
76
+ class PatternStr(Pattern):
77
+ __serialize_fields__ = 'value', 'flags', 'raw'
78
+
79
+ type: ClassVar[str] = "str"
80
+
81
+ def to_regexp(self) -> str:
82
+ return self._get_flags(re.escape(self.value))
83
+
84
+ @property
85
+ def min_width(self) -> int:
86
+ return len(self.value)
87
+
88
+ @property
89
+ def max_width(self) -> int:
90
+ return len(self.value)
91
+
92
+
93
+ class PatternRE(Pattern):
94
+ __serialize_fields__ = 'value', 'flags', 'raw', '_width'
95
+
96
+ type: ClassVar[str] = "re"
97
+
98
+ def to_regexp(self) -> str:
99
+ return self._get_flags(self.value)
100
+
101
+ _width = None
102
+ def _get_width(self):
103
+ if self._width is None:
104
+ self._width = get_regexp_width(self.to_regexp())
105
+ return self._width
106
+
107
+ @property
108
+ def min_width(self) -> int:
109
+ return self._get_width()[0]
110
+
111
+ @property
112
+ def max_width(self) -> int:
113
+ return self._get_width()[1]
114
+
115
+
116
+ class TerminalDef(Serialize):
117
+ "A definition of a terminal"
118
+ __serialize_fields__ = 'name', 'pattern', 'priority'
119
+ __serialize_namespace__ = PatternStr, PatternRE
120
+
121
+ name: str
122
+ pattern: Pattern
123
+ priority: int
124
+
125
+ def __init__(self, name: str, pattern: Pattern, priority: int = TOKEN_DEFAULT_PRIORITY) -> None:
126
+ assert isinstance(pattern, Pattern), pattern
127
+ self.name = name
128
+ self.pattern = pattern
129
+ self.priority = priority
130
+
131
+ def __repr__(self):
132
+ return '%s(%r, %r)' % (type(self).__name__, self.name, self.pattern)
133
+
134
+ def user_repr(self) -> str:
135
+ if self.name.startswith('__'): # We represent a generated terminal
136
+ return self.pattern.raw or self.name
137
+ else:
138
+ return self.name
139
+
140
+ _T = TypeVar('_T', bound="Token")
141
+
142
+ class Token(str):
143
+ """A string with meta-information, that is produced by the lexer.
144
+
145
+ When parsing text, the resulting chunks of the input that haven't been discarded,
146
+ will end up in the tree as Token instances. The Token class inherits from Python's ``str``,
147
+ so normal string comparisons and operations will work as expected.
148
+
149
+ Attributes:
150
+ type: Name of the token (as specified in grammar)
151
+ value: Value of the token (redundant, as ``token.value == token`` will always be true)
152
+ start_pos: The index of the token in the text
153
+ line: The line of the token in the text (starting with 1)
154
+ column: The column of the token in the text (starting with 1)
155
+ end_line: The line where the token ends
156
+ end_column: The next column after the end of the token. For example,
157
+ if the token is a single character with a column value of 4,
158
+ end_column will be 5.
159
+ end_pos: the index where the token ends (basically ``start_pos + len(token)``)
160
+ """
161
+ __slots__ = ('type', 'start_pos', 'value', 'line', 'column', 'end_line', 'end_column', 'end_pos')
162
+
163
+ __match_args__ = ('type', 'value')
164
+
165
+ type: str
166
+ start_pos: Optional[int]
167
+ value: Any
168
+ line: Optional[int]
169
+ column: Optional[int]
170
+ end_line: Optional[int]
171
+ end_column: Optional[int]
172
+ end_pos: Optional[int]
173
+
174
+
175
+ @overload
176
+ def __new__(
177
+ cls,
178
+ type: str,
179
+ value: Any,
180
+ start_pos: Optional[int] = None,
181
+ line: Optional[int] = None,
182
+ column: Optional[int] = None,
183
+ end_line: Optional[int] = None,
184
+ end_column: Optional[int] = None,
185
+ end_pos: Optional[int] = None
186
+ ) -> 'Token':
187
+ ...
188
+
189
+ @overload
190
+ def __new__(
191
+ cls,
192
+ type_: str,
193
+ value: Any,
194
+ start_pos: Optional[int] = None,
195
+ line: Optional[int] = None,
196
+ column: Optional[int] = None,
197
+ end_line: Optional[int] = None,
198
+ end_column: Optional[int] = None,
199
+ end_pos: Optional[int] = None
200
+ ) -> 'Token': ...
201
+
202
+ def __new__(cls, *args, **kwargs):
203
+ if "type_" in kwargs:
204
+ warnings.warn("`type_` is deprecated use `type` instead", DeprecationWarning)
205
+
206
+ if "type" in kwargs:
207
+ raise TypeError("Error: using both 'type' and the deprecated 'type_' as arguments.")
208
+ kwargs["type"] = kwargs.pop("type_")
209
+
210
+ return cls._future_new(*args, **kwargs)
211
+
212
+
213
+ @classmethod
214
+ def _future_new(cls, type, value, start_pos=None, line=None, column=None, end_line=None, end_column=None, end_pos=None):
215
+ inst = super(Token, cls).__new__(cls, value)
216
+
217
+ inst.type = type
218
+ inst.start_pos = start_pos
219
+ inst.value = value
220
+ inst.line = line
221
+ inst.column = column
222
+ inst.end_line = end_line
223
+ inst.end_column = end_column
224
+ inst.end_pos = end_pos
225
+ return inst
226
+
227
+ @overload
228
+ def update(self, type: Optional[str] = None, value: Optional[Any] = None) -> 'Token':
229
+ ...
230
+
231
+ @overload
232
+ def update(self, type_: Optional[str] = None, value: Optional[Any] = None) -> 'Token':
233
+ ...
234
+
235
+ def update(self, *args, **kwargs):
236
+ if "type_" in kwargs:
237
+ warnings.warn("`type_` is deprecated use `type` instead", DeprecationWarning)
238
+
239
+ if "type" in kwargs:
240
+ raise TypeError("Error: using both 'type' and the deprecated 'type_' as arguments.")
241
+ kwargs["type"] = kwargs.pop("type_")
242
+
243
+ return self._future_update(*args, **kwargs)
244
+
245
+ def _future_update(self, type: Optional[str] = None, value: Optional[Any] = None) -> 'Token':
246
+ return Token.new_borrow_pos(
247
+ type if type is not None else self.type,
248
+ value if value is not None else self.value,
249
+ self
250
+ )
251
+
252
+ @classmethod
253
+ def new_borrow_pos(cls: Type[_T], type_: str, value: Any, borrow_t: 'Token') -> _T:
254
+ return cls(type_, value, borrow_t.start_pos, borrow_t.line, borrow_t.column, borrow_t.end_line, borrow_t.end_column, borrow_t.end_pos)
255
+
256
+ def __reduce__(self):
257
+ return (self.__class__, (self.type, self.value, self.start_pos, self.line, self.column))
258
+
259
+ def __repr__(self):
260
+ return 'Token(%r, %r)' % (self.type, self.value)
261
+
262
+ def __deepcopy__(self, memo):
263
+ return Token(self.type, self.value, self.start_pos, self.line, self.column)
264
+
265
+ def __eq__(self, other):
266
+ if isinstance(other, Token) and self.type != other.type:
267
+ return False
268
+
269
+ return str.__eq__(self, other)
270
+
271
+ __hash__ = str.__hash__
272
+
273
+
274
+ class LineCounter:
275
+ "A utility class for keeping track of line & column information"
276
+
277
+ __slots__ = 'char_pos', 'line', 'column', 'line_start_pos', 'newline_char'
278
+
279
+ def __init__(self, newline_char):
280
+ self.newline_char = newline_char
281
+ self.char_pos = 0
282
+ self.line = 1
283
+ self.column = 1
284
+ self.line_start_pos = 0
285
+
286
+ def __eq__(self, other):
287
+ if not isinstance(other, LineCounter):
288
+ return NotImplemented
289
+
290
+ return self.char_pos == other.char_pos and self.newline_char == other.newline_char
291
+
292
+ def feed(self, token: Token, test_newline=True):
293
+ """Consume a token and calculate the new line & column.
294
+
295
+ As an optional optimization, set test_newline=False if token doesn't contain a newline.
296
+ """
297
+ if test_newline:
298
+ newlines = token.count(self.newline_char)
299
+ if newlines:
300
+ self.line += newlines
301
+ self.line_start_pos = self.char_pos + token.rindex(self.newline_char) + 1
302
+
303
+ self.char_pos += len(token)
304
+ self.column = self.char_pos - self.line_start_pos + 1
305
+
306
+
307
+ class UnlessCallback:
308
+ def __init__(self, scanner):
309
+ self.scanner = scanner
310
+
311
+ def __call__(self, t):
312
+ res = self.scanner.match(t.value, 0)
313
+ if res:
314
+ _value, t.type = res
315
+ return t
316
+
317
+
318
+ class CallChain:
319
+ def __init__(self, callback1, callback2, cond):
320
+ self.callback1 = callback1
321
+ self.callback2 = callback2
322
+ self.cond = cond
323
+
324
+ def __call__(self, t):
325
+ t2 = self.callback1(t)
326
+ return self.callback2(t) if self.cond(t2) else t2
327
+
328
+
329
+ def _get_match(re_, regexp, s, flags):
330
+ m = re_.match(regexp, s, flags)
331
+ if m:
332
+ return m.group(0)
333
+
334
+ def _create_unless(terminals, g_regex_flags, re_, use_bytes):
335
+ tokens_by_type = classify(terminals, lambda t: type(t.pattern))
336
+ assert len(tokens_by_type) <= 2, tokens_by_type.keys()
337
+ embedded_strs = set()
338
+ callback = {}
339
+ for retok in tokens_by_type.get(PatternRE, []):
340
+ unless = []
341
+ for strtok in tokens_by_type.get(PatternStr, []):
342
+ if strtok.priority != retok.priority:
343
+ continue
344
+ s = strtok.pattern.value
345
+ if s == _get_match(re_, retok.pattern.to_regexp(), s, g_regex_flags):
346
+ unless.append(strtok)
347
+ if strtok.pattern.flags <= retok.pattern.flags:
348
+ embedded_strs.add(strtok)
349
+ if unless:
350
+ callback[retok.name] = UnlessCallback(Scanner(unless, g_regex_flags, re_, match_whole=True, use_bytes=use_bytes))
351
+
352
+ new_terminals = [t for t in terminals if t not in embedded_strs]
353
+ return new_terminals, callback
354
+
355
+
356
+ class Scanner:
357
+ def __init__(self, terminals, g_regex_flags, re_, use_bytes, match_whole=False):
358
+ self.terminals = terminals
359
+ self.g_regex_flags = g_regex_flags
360
+ self.re_ = re_
361
+ self.use_bytes = use_bytes
362
+ self.match_whole = match_whole
363
+
364
+ self.allowed_types = {t.name for t in self.terminals}
365
+
366
+ self._mres = self._build_mres(terminals, len(terminals))
367
+
368
+ def _build_mres(self, terminals, max_size):
369
+ # Python sets an unreasonable group limit (currently 100) in its re module
370
+ # Worse, the only way to know we reached it is by catching an AssertionError!
371
+ # This function recursively tries less and less groups until it's successful.
372
+ postfix = '$' if self.match_whole else ''
373
+ mres = []
374
+ while terminals:
375
+ pattern = u'|'.join(u'(?P<%s>%s)' % (t.name, t.pattern.to_regexp() + postfix) for t in terminals[:max_size])
376
+ if self.use_bytes:
377
+ pattern = pattern.encode('latin-1')
378
+ try:
379
+ mre = self.re_.compile(pattern, self.g_regex_flags)
380
+ except AssertionError: # Yes, this is what Python provides us.. :/
381
+ return self._build_mres(terminals, max_size // 2)
382
+
383
+ mres.append(mre)
384
+ terminals = terminals[max_size:]
385
+ return mres
386
+
387
+ def match(self, text, pos):
388
+ for mre in self._mres:
389
+ m = mre.match(text, pos)
390
+ if m:
391
+ return m.group(0), m.lastgroup
392
+
393
+
394
+ def _regexp_has_newline(r: str):
395
+ r"""Expressions that may indicate newlines in a regexp:
396
+ - newlines (\n)
397
+ - escaped newline (\\n)
398
+ - anything but ([^...])
399
+ - any-char (.) when the flag (?s) exists
400
+ - spaces (\s)
401
+ """
402
+ return '\n' in r or '\\n' in r or '\\s' in r or '[^' in r or ('(?s' in r and '.' in r)
403
+
404
+
405
+ class LexerState:
406
+ """Represents the current state of the lexer as it scans the text
407
+ (Lexer objects are only instantiated per grammar, not per text)
408
+ """
409
+
410
+ __slots__ = 'text', 'line_ctr', 'last_token'
411
+
412
+ text: str
413
+ line_ctr: LineCounter
414
+ last_token: Optional[Token]
415
+
416
+ def __init__(self, text: str, line_ctr: Optional[LineCounter]=None, last_token: Optional[Token]=None):
417
+ self.text = text
418
+ self.line_ctr = line_ctr or LineCounter(b'\n' if isinstance(text, bytes) else '\n')
419
+ self.last_token = last_token
420
+
421
+ def __eq__(self, other):
422
+ if not isinstance(other, LexerState):
423
+ return NotImplemented
424
+
425
+ return self.text is other.text and self.line_ctr == other.line_ctr and self.last_token == other.last_token
426
+
427
+ def __copy__(self):
428
+ return type(self)(self.text, copy(self.line_ctr), self.last_token)
429
+
430
+
431
+ class LexerThread:
432
+ """A thread that ties a lexer instance and a lexer state, to be used by the parser
433
+ """
434
+
435
+ def __init__(self, lexer: 'Lexer', lexer_state: LexerState):
436
+ self.lexer = lexer
437
+ self.state = lexer_state
438
+
439
+ @classmethod
440
+ def from_text(cls, lexer: 'Lexer', text: str) -> 'LexerThread':
441
+ return cls(lexer, LexerState(text))
442
+
443
+ def lex(self, parser_state):
444
+ return self.lexer.lex(self.state, parser_state)
445
+
446
+ def __copy__(self):
447
+ return type(self)(self.lexer, copy(self.state))
448
+
449
+ _Token = Token
450
+
451
+
452
+ _Callback = Callable[[Token], Token]
453
+
454
+ class Lexer(ABC):
455
+ """Lexer interface
456
+
457
+ Method Signatures:
458
+ lex(self, lexer_state, parser_state) -> Iterator[Token]
459
+ """
460
+ @abstractmethod
461
+ def lex(self, lexer_state: LexerState, parser_state: Any) -> Iterator[Token]:
462
+ return NotImplemented
463
+
464
+ def make_lexer_state(self, text):
465
+ "Deprecated"
466
+ return LexerState(text)
467
+
468
+
469
+ def _check_regex_collisions(terminal_to_regexp: Dict[TerminalDef, str], comparator, strict_mode, max_collisions_to_show=8):
470
+ if not comparator:
471
+ comparator = interegular.Comparator.from_regexes(terminal_to_regexp)
472
+
473
+ # When in strict mode, we only ever try to provide one example, so taking
474
+ # a long time for that should be fine
475
+ max_time = 2 if strict_mode else 0.2
476
+
477
+ # We don't want to show too many collisions.
478
+ if comparator.count_marked_pairs() >= max_collisions_to_show:
479
+ return
480
+ for group in classify(terminal_to_regexp, lambda t: t.priority).values():
481
+ for a, b in comparator.check(group, skip_marked=True):
482
+ assert a.priority == b.priority
483
+ # Mark this pair to not repeat warnings when multiple different BasicLexers see the same collision
484
+ comparator.mark(a, b)
485
+
486
+ # Notify the user
487
+ message = f"Collision between Terminals {a.name} and {b.name}. "
488
+ try:
489
+ example = comparator.get_example_overlap(a, b, max_time).format_multiline()
490
+ except ValueError:
491
+ # Couldn't find an example within max_time steps.
492
+ example = "No example could be found fast enough. However, the collision does still exists"
493
+ if strict_mode:
494
+ raise LexError(f"{message}\n{example}")
495
+ logger.warning("%s The lexer will choose between them arbitrarily.\n%s", message, example)
496
+ if comparator.count_marked_pairs() >= max_collisions_to_show:
497
+ logger.warning("Found 8 regex collisions, will not check for more.")
498
+ return
499
+
500
+
501
+ class AbstractBasicLexer(Lexer):
502
+ terminals_by_name: Dict[str, TerminalDef]
503
+
504
+ @abstractmethod
505
+ def __init__(self, conf: 'LexerConf', comparator=None) -> None:
506
+ ...
507
+
508
+ @abstractmethod
509
+ def next_token(self, lex_state: LexerState, parser_state: Any = None) -> Token:
510
+ ...
511
+
512
+ def lex(self, state: LexerState, parser_state: Any) -> Iterator[Token]:
513
+ with suppress(EOFError):
514
+ while True:
515
+ yield self.next_token(state, parser_state)
516
+
517
+
518
+ class BasicLexer(AbstractBasicLexer):
519
+ terminals: Collection[TerminalDef]
520
+ ignore_types: FrozenSet[str]
521
+ newline_types: FrozenSet[str]
522
+ user_callbacks: Dict[str, _Callback]
523
+ callback: Dict[str, _Callback]
524
+ re: ModuleType
525
+
526
+ def __init__(self, conf: 'LexerConf', comparator=None) -> None:
527
+ terminals = list(conf.terminals)
528
+ assert all(isinstance(t, TerminalDef) for t in terminals), terminals
529
+
530
+ self.re = conf.re_module
531
+
532
+ if not conf.skip_validation:
533
+ # Sanitization
534
+ terminal_to_regexp = {}
535
+ for t in terminals:
536
+ regexp = t.pattern.to_regexp()
537
+ try:
538
+ self.re.compile(regexp, conf.g_regex_flags)
539
+ except self.re.error:
540
+ raise LexError("Cannot compile token %s: %s" % (t.name, t.pattern))
541
+
542
+ if t.pattern.min_width == 0:
543
+ raise LexError("Lexer does not allow zero-width terminals. (%s: %s)" % (t.name, t.pattern))
544
+ if t.pattern.type == "re":
545
+ terminal_to_regexp[t] = regexp
546
+
547
+ if not (set(conf.ignore) <= {t.name for t in terminals}):
548
+ raise LexError("Ignore terminals are not defined: %s" % (set(conf.ignore) - {t.name for t in terminals}))
549
+
550
+ if has_interegular:
551
+ _check_regex_collisions(terminal_to_regexp, comparator, conf.strict)
552
+ elif conf.strict:
553
+ raise LexError("interegular must be installed for strict mode. Use `pip install 'lark[interegular]'`.")
554
+
555
+ # Init
556
+ self.newline_types = frozenset(t.name for t in terminals if _regexp_has_newline(t.pattern.to_regexp()))
557
+ self.ignore_types = frozenset(conf.ignore)
558
+
559
+ terminals.sort(key=lambda x: (-x.priority, -x.pattern.max_width, -len(x.pattern.value), x.name))
560
+ self.terminals = terminals
561
+ self.user_callbacks = conf.callbacks
562
+ self.g_regex_flags = conf.g_regex_flags
563
+ self.use_bytes = conf.use_bytes
564
+ self.terminals_by_name = conf.terminals_by_name
565
+
566
+ self._scanner = None
567
+
568
+ def _build_scanner(self):
569
+ terminals, self.callback = _create_unless(self.terminals, self.g_regex_flags, self.re, self.use_bytes)
570
+ assert all(self.callback.values())
571
+
572
+ for type_, f in self.user_callbacks.items():
573
+ if type_ in self.callback:
574
+ # Already a callback there, probably UnlessCallback
575
+ self.callback[type_] = CallChain(self.callback[type_], f, lambda t: t.type == type_)
576
+ else:
577
+ self.callback[type_] = f
578
+
579
+ self._scanner = Scanner(terminals, self.g_regex_flags, self.re, self.use_bytes)
580
+
581
+ @property
582
+ def scanner(self):
583
+ if self._scanner is None:
584
+ self._build_scanner()
585
+ return self._scanner
586
+
587
+ def match(self, text, pos):
588
+ return self.scanner.match(text, pos)
589
+
590
+ def next_token(self, lex_state: LexerState, parser_state: Any = None) -> Token:
591
+ line_ctr = lex_state.line_ctr
592
+ while line_ctr.char_pos < len(lex_state.text):
593
+ res = self.match(lex_state.text, line_ctr.char_pos)
594
+ if not res:
595
+ allowed = self.scanner.allowed_types - self.ignore_types
596
+ if not allowed:
597
+ allowed = {"<END-OF-FILE>"}
598
+ raise UnexpectedCharacters(lex_state.text, line_ctr.char_pos, line_ctr.line, line_ctr.column,
599
+ allowed=allowed, token_history=lex_state.last_token and [lex_state.last_token],
600
+ state=parser_state, terminals_by_name=self.terminals_by_name)
601
+
602
+ value, type_ = res
603
+
604
+ ignored = type_ in self.ignore_types
605
+ t = None
606
+ if not ignored or type_ in self.callback:
607
+ t = Token(type_, value, line_ctr.char_pos, line_ctr.line, line_ctr.column)
608
+ line_ctr.feed(value, type_ in self.newline_types)
609
+ if t is not None:
610
+ t.end_line = line_ctr.line
611
+ t.end_column = line_ctr.column
612
+ t.end_pos = line_ctr.char_pos
613
+ if t.type in self.callback:
614
+ t = self.callback[t.type](t)
615
+ if not ignored:
616
+ if not isinstance(t, Token):
617
+ raise LexError("Callbacks must return a token (returned %r)" % t)
618
+ lex_state.last_token = t
619
+ return t
620
+
621
+ # EOF
622
+ raise EOFError(self)
623
+
624
+
625
+ class ContextualLexer(Lexer):
626
+ lexers: Dict[int, AbstractBasicLexer]
627
+ root_lexer: AbstractBasicLexer
628
+
629
+ BasicLexer: Type[AbstractBasicLexer] = BasicLexer
630
+
631
+ def __init__(self, conf: 'LexerConf', states: Dict[int, Collection[str]], always_accept: Collection[str]=()) -> None:
632
+ terminals = list(conf.terminals)
633
+ terminals_by_name = conf.terminals_by_name
634
+
635
+ trad_conf = copy(conf)
636
+ trad_conf.terminals = terminals
637
+
638
+ if has_interegular and not conf.skip_validation:
639
+ comparator = interegular.Comparator.from_regexes({t: t.pattern.to_regexp() for t in terminals})
640
+ else:
641
+ comparator = None
642
+ lexer_by_tokens: Dict[FrozenSet[str], AbstractBasicLexer] = {}
643
+ self.lexers = {}
644
+ for state, accepts in states.items():
645
+ key = frozenset(accepts)
646
+ try:
647
+ lexer = lexer_by_tokens[key]
648
+ except KeyError:
649
+ accepts = set(accepts) | set(conf.ignore) | set(always_accept)
650
+ lexer_conf = copy(trad_conf)
651
+ lexer_conf.terminals = [terminals_by_name[n] for n in accepts if n in terminals_by_name]
652
+ lexer = self.BasicLexer(lexer_conf, comparator)
653
+ lexer_by_tokens[key] = lexer
654
+
655
+ self.lexers[state] = lexer
656
+
657
+ assert trad_conf.terminals is terminals
658
+ trad_conf.skip_validation = True # We don't need to verify all terminals again
659
+ self.root_lexer = self.BasicLexer(trad_conf, comparator)
660
+
661
+ def lex(self, lexer_state: LexerState, parser_state: 'ParserState') -> Iterator[Token]:
662
+ try:
663
+ while True:
664
+ lexer = self.lexers[parser_state.position]
665
+ yield lexer.next_token(lexer_state, parser_state)
666
+ except EOFError:
667
+ pass
668
+ except UnexpectedCharacters as e:
669
+ # In the contextual lexer, UnexpectedCharacters can mean that the terminal is defined, but not in the current context.
670
+ # This tests the input against the global context, to provide a nicer error.
671
+ try:
672
+ last_token = lexer_state.last_token # Save last_token. Calling root_lexer.next_token will change this to the wrong token
673
+ token = self.root_lexer.next_token(lexer_state, parser_state)
674
+ raise UnexpectedToken(token, e.allowed, state=parser_state, token_history=[last_token], terminals_by_name=self.root_lexer.terminals_by_name)
675
+ except UnexpectedCharacters:
676
+ raise e # Raise the original UnexpectedCharacters. The root lexer raises it with the wrong expected set.
677
+
678
+ ###}