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,340 @@
1
+ """This module implements a CYK parser."""
2
+
3
+ # Author: https://github.com/ehudt (2018)
4
+ #
5
+ # Adapted by Erez
6
+
7
+
8
+ from collections import defaultdict
9
+ import itertools
10
+
11
+ from ..exceptions import ParseError
12
+ from ..lexer import Token
13
+ from ..tree import Tree
14
+ from ..grammar import Terminal as T, NonTerminal as NT, Symbol
15
+
16
+ def match(t, s):
17
+ assert isinstance(t, T)
18
+ return t.name == s.type
19
+
20
+
21
+ class Rule:
22
+ """Context-free grammar rule."""
23
+
24
+ def __init__(self, lhs, rhs, weight, alias):
25
+ super(Rule, self).__init__()
26
+ assert isinstance(lhs, NT), lhs
27
+ assert all(isinstance(x, NT) or isinstance(x, T) for x in rhs), rhs
28
+ self.lhs = lhs
29
+ self.rhs = rhs
30
+ self.weight = weight
31
+ self.alias = alias
32
+
33
+ def __str__(self):
34
+ return '%s -> %s' % (str(self.lhs), ' '.join(str(x) for x in self.rhs))
35
+
36
+ def __repr__(self):
37
+ return str(self)
38
+
39
+ def __hash__(self):
40
+ return hash((self.lhs, tuple(self.rhs)))
41
+
42
+ def __eq__(self, other):
43
+ return self.lhs == other.lhs and self.rhs == other.rhs
44
+
45
+ def __ne__(self, other):
46
+ return not (self == other)
47
+
48
+
49
+ class Grammar:
50
+ """Context-free grammar."""
51
+
52
+ def __init__(self, rules):
53
+ self.rules = frozenset(rules)
54
+
55
+ def __eq__(self, other):
56
+ return self.rules == other.rules
57
+
58
+ def __str__(self):
59
+ return '\n' + '\n'.join(sorted(repr(x) for x in self.rules)) + '\n'
60
+
61
+ def __repr__(self):
62
+ return str(self)
63
+
64
+
65
+ # Parse tree data structures
66
+ class RuleNode:
67
+ """A node in the parse tree, which also contains the full rhs rule."""
68
+
69
+ def __init__(self, rule, children, weight=0):
70
+ self.rule = rule
71
+ self.children = children
72
+ self.weight = weight
73
+
74
+ def __repr__(self):
75
+ return 'RuleNode(%s, [%s])' % (repr(self.rule.lhs), ', '.join(str(x) for x in self.children))
76
+
77
+
78
+
79
+ class Parser:
80
+ """Parser wrapper."""
81
+
82
+ def __init__(self, rules):
83
+ super(Parser, self).__init__()
84
+ self.orig_rules = {rule: rule for rule in rules}
85
+ rules = [self._to_rule(rule) for rule in rules]
86
+ self.grammar = to_cnf(Grammar(rules))
87
+
88
+ def _to_rule(self, lark_rule):
89
+ """Converts a lark rule, (lhs, rhs, callback, options), to a Rule."""
90
+ assert isinstance(lark_rule.origin, NT)
91
+ assert all(isinstance(x, Symbol) for x in lark_rule.expansion)
92
+ return Rule(
93
+ lark_rule.origin, lark_rule.expansion,
94
+ weight=lark_rule.options.priority if lark_rule.options.priority else 0,
95
+ alias=lark_rule)
96
+
97
+ def parse(self, tokenized, start): # pylint: disable=invalid-name
98
+ """Parses input, which is a list of tokens."""
99
+ assert start
100
+ start = NT(start)
101
+
102
+ table, trees = _parse(tokenized, self.grammar)
103
+ # Check if the parse succeeded.
104
+ if all(r.lhs != start for r in table[(0, len(tokenized) - 1)]):
105
+ raise ParseError('Parsing failed.')
106
+ parse = trees[(0, len(tokenized) - 1)][start]
107
+ return self._to_tree(revert_cnf(parse))
108
+
109
+ def _to_tree(self, rule_node):
110
+ """Converts a RuleNode parse tree to a lark Tree."""
111
+ orig_rule = self.orig_rules[rule_node.rule.alias]
112
+ children = []
113
+ for child in rule_node.children:
114
+ if isinstance(child, RuleNode):
115
+ children.append(self._to_tree(child))
116
+ else:
117
+ assert isinstance(child.name, Token)
118
+ children.append(child.name)
119
+ t = Tree(orig_rule.origin, children)
120
+ t.rule=orig_rule
121
+ return t
122
+
123
+
124
+ def print_parse(node, indent=0):
125
+ if isinstance(node, RuleNode):
126
+ print(' ' * (indent * 2) + str(node.rule.lhs))
127
+ for child in node.children:
128
+ print_parse(child, indent + 1)
129
+ else:
130
+ print(' ' * (indent * 2) + str(node.s))
131
+
132
+
133
+ def _parse(s, g):
134
+ """Parses sentence 's' using CNF grammar 'g'."""
135
+ # The CYK table. Indexed with a 2-tuple: (start pos, end pos)
136
+ table = defaultdict(set)
137
+ # Top-level structure is similar to the CYK table. Each cell is a dict from
138
+ # rule name to the best (lightest) tree for that rule.
139
+ trees = defaultdict(dict)
140
+ # Populate base case with existing terminal production rules
141
+ for i, w in enumerate(s):
142
+ for terminal, rules in g.terminal_rules.items():
143
+ if match(terminal, w):
144
+ for rule in rules:
145
+ table[(i, i)].add(rule)
146
+ if (rule.lhs not in trees[(i, i)] or
147
+ rule.weight < trees[(i, i)][rule.lhs].weight):
148
+ trees[(i, i)][rule.lhs] = RuleNode(rule, [T(w)], weight=rule.weight)
149
+
150
+ # Iterate over lengths of sub-sentences
151
+ for l in range(2, len(s) + 1):
152
+ # Iterate over sub-sentences with the given length
153
+ for i in range(len(s) - l + 1):
154
+ # Choose partition of the sub-sentence in [1, l)
155
+ for p in range(i + 1, i + l):
156
+ span1 = (i, p - 1)
157
+ span2 = (p, i + l - 1)
158
+ for r1, r2 in itertools.product(table[span1], table[span2]):
159
+ for rule in g.nonterminal_rules.get((r1.lhs, r2.lhs), []):
160
+ table[(i, i + l - 1)].add(rule)
161
+ r1_tree = trees[span1][r1.lhs]
162
+ r2_tree = trees[span2][r2.lhs]
163
+ rule_total_weight = rule.weight + r1_tree.weight + r2_tree.weight
164
+ if (rule.lhs not in trees[(i, i + l - 1)]
165
+ or rule_total_weight < trees[(i, i + l - 1)][rule.lhs].weight):
166
+ trees[(i, i + l - 1)][rule.lhs] = RuleNode(rule, [r1_tree, r2_tree], weight=rule_total_weight)
167
+ return table, trees
168
+
169
+
170
+ # This section implements context-free grammar converter to Chomsky normal form.
171
+ # It also implements a conversion of parse trees from its CNF to the original
172
+ # grammar.
173
+ # Overview:
174
+ # Applies the following operations in this order:
175
+ # * TERM: Eliminates non-solitary terminals from all rules
176
+ # * BIN: Eliminates rules with more than 2 symbols on their right-hand-side.
177
+ # * UNIT: Eliminates non-terminal unit rules
178
+ #
179
+ # The following grammar characteristics aren't featured:
180
+ # * Start symbol appears on RHS
181
+ # * Empty rules (epsilon rules)
182
+
183
+
184
+ class CnfWrapper:
185
+ """CNF wrapper for grammar.
186
+
187
+ Validates that the input grammar is CNF and provides helper data structures.
188
+ """
189
+
190
+ def __init__(self, grammar):
191
+ super(CnfWrapper, self).__init__()
192
+ self.grammar = grammar
193
+ self.rules = grammar.rules
194
+ self.terminal_rules = defaultdict(list)
195
+ self.nonterminal_rules = defaultdict(list)
196
+ for r in self.rules:
197
+ # Validate that the grammar is CNF and populate auxiliary data structures.
198
+ assert isinstance(r.lhs, NT), r
199
+ if len(r.rhs) not in [1, 2]:
200
+ raise ParseError("CYK doesn't support empty rules")
201
+ if len(r.rhs) == 1 and isinstance(r.rhs[0], T):
202
+ self.terminal_rules[r.rhs[0]].append(r)
203
+ elif len(r.rhs) == 2 and all(isinstance(x, NT) for x in r.rhs):
204
+ self.nonterminal_rules[tuple(r.rhs)].append(r)
205
+ else:
206
+ assert False, r
207
+
208
+ def __eq__(self, other):
209
+ return self.grammar == other.grammar
210
+
211
+ def __repr__(self):
212
+ return repr(self.grammar)
213
+
214
+
215
+ class UnitSkipRule(Rule):
216
+ """A rule that records NTs that were skipped during transformation."""
217
+
218
+ def __init__(self, lhs, rhs, skipped_rules, weight, alias):
219
+ super(UnitSkipRule, self).__init__(lhs, rhs, weight, alias)
220
+ self.skipped_rules = skipped_rules
221
+
222
+ def __eq__(self, other):
223
+ return isinstance(other, type(self)) and self.skipped_rules == other.skipped_rules
224
+
225
+ __hash__ = Rule.__hash__
226
+
227
+
228
+ def build_unit_skiprule(unit_rule, target_rule):
229
+ skipped_rules = []
230
+ if isinstance(unit_rule, UnitSkipRule):
231
+ skipped_rules += unit_rule.skipped_rules
232
+ skipped_rules.append(target_rule)
233
+ if isinstance(target_rule, UnitSkipRule):
234
+ skipped_rules += target_rule.skipped_rules
235
+ return UnitSkipRule(unit_rule.lhs, target_rule.rhs, skipped_rules,
236
+ weight=unit_rule.weight + target_rule.weight, alias=unit_rule.alias)
237
+
238
+
239
+ def get_any_nt_unit_rule(g):
240
+ """Returns a non-terminal unit rule from 'g', or None if there is none."""
241
+ for rule in g.rules:
242
+ if len(rule.rhs) == 1 and isinstance(rule.rhs[0], NT):
243
+ return rule
244
+ return None
245
+
246
+
247
+ def _remove_unit_rule(g, rule):
248
+ """Removes 'rule' from 'g' without changing the language produced by 'g'."""
249
+ new_rules = [x for x in g.rules if x != rule]
250
+ refs = [x for x in g.rules if x.lhs == rule.rhs[0]]
251
+ new_rules += [build_unit_skiprule(rule, ref) for ref in refs]
252
+ return Grammar(new_rules)
253
+
254
+
255
+ def _split(rule):
256
+ """Splits a rule whose len(rhs) > 2 into shorter rules."""
257
+ rule_str = str(rule.lhs) + '__' + '_'.join(str(x) for x in rule.rhs)
258
+ rule_name = '__SP_%s' % (rule_str) + '_%d'
259
+ yield Rule(rule.lhs, [rule.rhs[0], NT(rule_name % 1)], weight=rule.weight, alias=rule.alias)
260
+ for i in range(1, len(rule.rhs) - 2):
261
+ yield Rule(NT(rule_name % i), [rule.rhs[i], NT(rule_name % (i + 1))], weight=0, alias='Split')
262
+ yield Rule(NT(rule_name % (len(rule.rhs) - 2)), rule.rhs[-2:], weight=0, alias='Split')
263
+
264
+
265
+ def _term(g):
266
+ """Applies the TERM rule on 'g' (see top comment)."""
267
+ all_t = {x for rule in g.rules for x in rule.rhs if isinstance(x, T)}
268
+ t_rules = {t: Rule(NT('__T_%s' % str(t)), [t], weight=0, alias='Term') for t in all_t}
269
+ new_rules = []
270
+ for rule in g.rules:
271
+ if len(rule.rhs) > 1 and any(isinstance(x, T) for x in rule.rhs):
272
+ new_rhs = [t_rules[x].lhs if isinstance(x, T) else x for x in rule.rhs]
273
+ new_rules.append(Rule(rule.lhs, new_rhs, weight=rule.weight, alias=rule.alias))
274
+ new_rules.extend(v for k, v in t_rules.items() if k in rule.rhs)
275
+ else:
276
+ new_rules.append(rule)
277
+ return Grammar(new_rules)
278
+
279
+
280
+ def _bin(g):
281
+ """Applies the BIN rule to 'g' (see top comment)."""
282
+ new_rules = []
283
+ for rule in g.rules:
284
+ if len(rule.rhs) > 2:
285
+ new_rules += _split(rule)
286
+ else:
287
+ new_rules.append(rule)
288
+ return Grammar(new_rules)
289
+
290
+
291
+ def _unit(g):
292
+ """Applies the UNIT rule to 'g' (see top comment)."""
293
+ nt_unit_rule = get_any_nt_unit_rule(g)
294
+ while nt_unit_rule:
295
+ g = _remove_unit_rule(g, nt_unit_rule)
296
+ nt_unit_rule = get_any_nt_unit_rule(g)
297
+ return g
298
+
299
+
300
+ def to_cnf(g):
301
+ """Creates a CNF grammar from a general context-free grammar 'g'."""
302
+ g = _unit(_bin(_term(g)))
303
+ return CnfWrapper(g)
304
+
305
+
306
+ def unroll_unit_skiprule(lhs, orig_rhs, skipped_rules, children, weight, alias):
307
+ if not skipped_rules:
308
+ return RuleNode(Rule(lhs, orig_rhs, weight=weight, alias=alias), children, weight=weight)
309
+ else:
310
+ weight = weight - skipped_rules[0].weight
311
+ return RuleNode(
312
+ Rule(lhs, [skipped_rules[0].lhs], weight=weight, alias=alias), [
313
+ unroll_unit_skiprule(skipped_rules[0].lhs, orig_rhs,
314
+ skipped_rules[1:], children,
315
+ skipped_rules[0].weight, skipped_rules[0].alias)
316
+ ], weight=weight)
317
+
318
+
319
+ def revert_cnf(node):
320
+ """Reverts a parse tree (RuleNode) to its original non-CNF form (Node)."""
321
+ if isinstance(node, T):
322
+ return node
323
+ # Reverts TERM rule.
324
+ if node.rule.lhs.name.startswith('__T_'):
325
+ return node.children[0]
326
+ else:
327
+ children = []
328
+ for child in map(revert_cnf, node.children):
329
+ # Reverts BIN rule.
330
+ if isinstance(child, RuleNode) and child.rule.lhs.name.startswith('__SP_'):
331
+ children += child.children
332
+ else:
333
+ children.append(child)
334
+ # Reverts UNIT rule.
335
+ if isinstance(node.rule, UnitSkipRule):
336
+ return unroll_unit_skiprule(node.rule.lhs, node.rule.rhs,
337
+ node.rule.skipped_rules, children,
338
+ node.rule.weight, node.rule.alias)
339
+ else:
340
+ return RuleNode(node.rule, children)
@@ -0,0 +1,314 @@
1
+ """This module implements an Earley parser.
2
+
3
+ The core Earley algorithm used here is based on Elizabeth Scott's implementation, here:
4
+ https://www.sciencedirect.com/science/article/pii/S1571066108001497
5
+
6
+ That is probably the best reference for understanding the algorithm here.
7
+
8
+ The Earley parser outputs an SPPF-tree as per that document. The SPPF tree format
9
+ is explained here: https://lark-parser.readthedocs.io/en/latest/_static/sppf/sppf.html
10
+ """
11
+
12
+ from typing import TYPE_CHECKING, Callable, Optional, List, Any
13
+ from collections import deque
14
+
15
+ from ..lexer import Token
16
+ from ..tree import Tree
17
+ from ..exceptions import UnexpectedEOF, UnexpectedToken
18
+ from ..utils import logger, OrderedSet, dedup_list
19
+ from .grammar_analysis import GrammarAnalyzer
20
+ from ..grammar import NonTerminal
21
+ from .earley_common import Item
22
+ from .earley_forest import ForestSumVisitor, SymbolNode, StableSymbolNode, TokenNode, ForestToParseTree
23
+
24
+ if TYPE_CHECKING:
25
+ from ..common import LexerConf, ParserConf
26
+
27
+ class Parser:
28
+ lexer_conf: 'LexerConf'
29
+ parser_conf: 'ParserConf'
30
+ debug: bool
31
+
32
+ def __init__(self, lexer_conf: 'LexerConf', parser_conf: 'ParserConf', term_matcher: Callable,
33
+ resolve_ambiguity: bool=True, debug: bool=False,
34
+ tree_class: Optional[Callable[[str, List], Any]]=Tree, ordered_sets: bool=True):
35
+ analysis = GrammarAnalyzer(parser_conf)
36
+ self.lexer_conf = lexer_conf
37
+ self.parser_conf = parser_conf
38
+ self.resolve_ambiguity = resolve_ambiguity
39
+ self.debug = debug
40
+ self.Tree = tree_class
41
+ self.Set = OrderedSet if ordered_sets else set
42
+ self.SymbolNode = StableSymbolNode if ordered_sets else SymbolNode
43
+
44
+ self.FIRST = analysis.FIRST
45
+ self.NULLABLE = analysis.NULLABLE
46
+ self.callbacks = parser_conf.callbacks
47
+ # TODO add typing info
48
+ self.predictions = {} # type: ignore[var-annotated]
49
+
50
+ ## These could be moved to the grammar analyzer. Pre-computing these is *much* faster than
51
+ # the slow 'isupper' in is_terminal.
52
+ self.TERMINALS = { sym for r in parser_conf.rules for sym in r.expansion if sym.is_term }
53
+ self.NON_TERMINALS = { sym for r in parser_conf.rules for sym in r.expansion if not sym.is_term }
54
+
55
+ self.forest_sum_visitor = None
56
+ for rule in parser_conf.rules:
57
+ if rule.origin not in self.predictions:
58
+ self.predictions[rule.origin] = [x.rule for x in analysis.expand_rule(rule.origin)]
59
+
60
+ ## Detect if any rules/terminals have priorities set. If the user specified priority = None, then
61
+ # the priorities will be stripped from all rules/terminals before they reach us, allowing us to
62
+ # skip the extra tree walk. We'll also skip this if the user just didn't specify priorities
63
+ # on any rules/terminals.
64
+ if self.forest_sum_visitor is None and rule.options.priority is not None:
65
+ self.forest_sum_visitor = ForestSumVisitor
66
+
67
+ # Check terminals for priorities
68
+ # Ignore terminal priorities if the basic lexer is used
69
+ if self.lexer_conf.lexer_type != 'basic' and self.forest_sum_visitor is None:
70
+ for term in self.lexer_conf.terminals:
71
+ if term.priority:
72
+ self.forest_sum_visitor = ForestSumVisitor
73
+ break
74
+
75
+ self.term_matcher = term_matcher
76
+
77
+
78
+ def predict_and_complete(self, i, to_scan, columns, transitives):
79
+ """The core Earley Predictor and Completer.
80
+
81
+ At each stage of the input, we handling any completed items (things
82
+ that matched on the last cycle) and use those to predict what should
83
+ come next in the input stream. The completions and any predicted
84
+ non-terminals are recursively processed until we reach a set of,
85
+ which can be added to the scan list for the next scanner cycle."""
86
+ # Held Completions (H in E.Scotts paper).
87
+ node_cache = {}
88
+ held_completions = {}
89
+
90
+ column = columns[i]
91
+ # R (items) = Ei (column.items)
92
+ items = deque(column)
93
+ while items:
94
+ item = items.pop() # remove an element, A say, from R
95
+
96
+ ### The Earley completer
97
+ if item.is_complete: ### (item.s == string)
98
+ if item.node is None:
99
+ label = (item.s, item.start, i)
100
+ item.node = node_cache[label] if label in node_cache else node_cache.setdefault(label, self.SymbolNode(*label))
101
+ item.node.add_family(item.s, item.rule, item.start, None, None)
102
+
103
+ # create_leo_transitives(item.rule.origin, item.start)
104
+
105
+ ###R Joop Leo right recursion Completer
106
+ if item.rule.origin in transitives[item.start]:
107
+ transitive = transitives[item.start][item.s]
108
+ if transitive.previous in transitives[transitive.column]:
109
+ root_transitive = transitives[transitive.column][transitive.previous]
110
+ else:
111
+ root_transitive = transitive
112
+
113
+ new_item = Item(transitive.rule, transitive.ptr, transitive.start)
114
+ label = (root_transitive.s, root_transitive.start, i)
115
+ new_item.node = node_cache[label] if label in node_cache else node_cache.setdefault(label, self.SymbolNode(*label))
116
+ new_item.node.add_path(root_transitive, item.node)
117
+ if new_item.expect in self.TERMINALS:
118
+ # Add (B :: aC.B, h, y) to Q
119
+ to_scan.add(new_item)
120
+ elif new_item not in column:
121
+ # Add (B :: aC.B, h, y) to Ei and R
122
+ column.add(new_item)
123
+ items.append(new_item)
124
+ ###R Regular Earley completer
125
+ else:
126
+ # Empty has 0 length. If we complete an empty symbol in a particular
127
+ # parse step, we need to be able to use that same empty symbol to complete
128
+ # any predictions that result, that themselves require empty. Avoids
129
+ # infinite recursion on empty symbols.
130
+ # held_completions is 'H' in E.Scott's paper.
131
+ is_empty_item = item.start == i
132
+ if is_empty_item:
133
+ held_completions[item.rule.origin] = item.node
134
+
135
+ originators = [originator for originator in columns[item.start] if originator.expect is not None and originator.expect == item.s]
136
+ for originator in originators:
137
+ new_item = originator.advance()
138
+ label = (new_item.s, originator.start, i)
139
+ new_item.node = node_cache[label] if label in node_cache else node_cache.setdefault(label, self.SymbolNode(*label))
140
+ new_item.node.add_family(new_item.s, new_item.rule, i, originator.node, item.node)
141
+ if new_item.expect in self.TERMINALS:
142
+ # Add (B :: aC.B, h, y) to Q
143
+ to_scan.add(new_item)
144
+ elif new_item not in column:
145
+ # Add (B :: aC.B, h, y) to Ei and R
146
+ column.add(new_item)
147
+ items.append(new_item)
148
+
149
+ ### The Earley predictor
150
+ elif item.expect in self.NON_TERMINALS: ### (item.s == lr0)
151
+ new_items = []
152
+ for rule in self.predictions[item.expect]:
153
+ new_item = Item(rule, 0, i)
154
+ new_items.append(new_item)
155
+
156
+ # Process any held completions (H).
157
+ if item.expect in held_completions:
158
+ new_item = item.advance()
159
+ label = (new_item.s, item.start, i)
160
+ new_item.node = node_cache[label] if label in node_cache else node_cache.setdefault(label, self.SymbolNode(*label))
161
+ new_item.node.add_family(new_item.s, new_item.rule, new_item.start, item.node, held_completions[item.expect])
162
+ new_items.append(new_item)
163
+
164
+ for new_item in new_items:
165
+ if new_item.expect in self.TERMINALS:
166
+ to_scan.add(new_item)
167
+ elif new_item not in column:
168
+ column.add(new_item)
169
+ items.append(new_item)
170
+
171
+ def _parse(self, lexer, columns, to_scan, start_symbol=None):
172
+
173
+ def is_quasi_complete(item):
174
+ if item.is_complete:
175
+ return True
176
+
177
+ quasi = item.advance()
178
+ while not quasi.is_complete:
179
+ if quasi.expect not in self.NULLABLE:
180
+ return False
181
+ if quasi.rule.origin == start_symbol and quasi.expect == start_symbol:
182
+ return False
183
+ quasi = quasi.advance()
184
+ return True
185
+
186
+ # def create_leo_transitives(origin, start):
187
+ # ... # removed at commit 4c1cfb2faf24e8f8bff7112627a00b94d261b420
188
+
189
+ def scan(i, token, to_scan):
190
+ """The core Earley Scanner.
191
+
192
+ This is a custom implementation of the scanner that uses the
193
+ Lark lexer to match tokens. The scan list is built by the
194
+ Earley predictor, based on the previously completed tokens.
195
+ This ensures that at each phase of the parse we have a custom
196
+ lexer context, allowing for more complex ambiguities."""
197
+ next_to_scan = self.Set()
198
+ next_set = self.Set()
199
+ columns.append(next_set)
200
+ transitives.append({})
201
+ node_cache = {}
202
+
203
+ for item in self.Set(to_scan):
204
+ if match(item.expect, token):
205
+ new_item = item.advance()
206
+ label = (new_item.s, new_item.start, i)
207
+ # 'terminals' may not contain token.type when using %declare
208
+ # Additionally, token is not always a Token
209
+ # For example, it can be a Tree when using TreeMatcher
210
+ term = terminals.get(token.type) if isinstance(token, Token) else None
211
+ # Set the priority of the token node to 0 so that the
212
+ # terminal priorities do not affect the Tree chosen by
213
+ # ForestSumVisitor after the basic lexer has already
214
+ # "used up" the terminal priorities
215
+ token_node = TokenNode(token, term, priority=0)
216
+ new_item.node = node_cache[label] if label in node_cache else node_cache.setdefault(label, self.SymbolNode(*label))
217
+ new_item.node.add_family(new_item.s, item.rule, new_item.start, item.node, token_node)
218
+
219
+ if new_item.expect in self.TERMINALS:
220
+ # add (B ::= Aai+1.B, h, y) to Q'
221
+ next_to_scan.add(new_item)
222
+ else:
223
+ # add (B ::= Aa+1.B, h, y) to Ei+1
224
+ next_set.add(new_item)
225
+
226
+ if not next_set and not next_to_scan:
227
+ expect = {i.expect.name for i in to_scan}
228
+ raise UnexpectedToken(token, expect, considered_rules=set(to_scan), state=frozenset(i.s for i in to_scan))
229
+
230
+ return next_to_scan
231
+
232
+
233
+ # Define parser functions
234
+ match = self.term_matcher
235
+
236
+ terminals = self.lexer_conf.terminals_by_name
237
+
238
+ # Cache for nodes & tokens created in a particular parse step.
239
+ transitives = [{}]
240
+
241
+ ## The main Earley loop.
242
+ # Run the Prediction/Completion cycle for any Items in the current Earley set.
243
+ # Completions will be added to the SPPF tree, and predictions will be recursively
244
+ # processed down to terminals/empty nodes to be added to the scanner for the next
245
+ # step.
246
+ expects = {i.expect for i in to_scan}
247
+ i = 0
248
+ for token in lexer.lex(expects):
249
+ self.predict_and_complete(i, to_scan, columns, transitives)
250
+
251
+ to_scan = scan(i, token, to_scan)
252
+ i += 1
253
+
254
+ expects.clear()
255
+ expects |= {i.expect for i in to_scan}
256
+
257
+ self.predict_and_complete(i, to_scan, columns, transitives)
258
+
259
+ ## Column is now the final column in the parse.
260
+ assert i == len(columns)-1
261
+ return to_scan
262
+
263
+ def parse(self, lexer, start):
264
+ assert start, start
265
+ start_symbol = NonTerminal(start)
266
+
267
+ columns = [self.Set()]
268
+ to_scan = self.Set() # The scan buffer. 'Q' in E.Scott's paper.
269
+
270
+ ## Predict for the start_symbol.
271
+ # Add predicted items to the first Earley set (for the predictor) if they
272
+ # result in a non-terminal, or the scanner if they result in a terminal.
273
+ for rule in self.predictions[start_symbol]:
274
+ item = Item(rule, 0, 0)
275
+ if item.expect in self.TERMINALS:
276
+ to_scan.add(item)
277
+ else:
278
+ columns[0].add(item)
279
+
280
+ to_scan = self._parse(lexer, columns, to_scan, start_symbol)
281
+
282
+ # If the parse was successful, the start
283
+ # symbol should have been completed in the last step of the Earley cycle, and will be in
284
+ # this column. Find the item for the start_symbol, which is the root of the SPPF tree.
285
+ solutions = dedup_list(n.node for n in columns[-1] if n.is_complete and n.node is not None and n.s == start_symbol and n.start == 0)
286
+ if not solutions:
287
+ expected_terminals = [t.expect.name for t in to_scan]
288
+ raise UnexpectedEOF(expected_terminals, state=frozenset(i.s for i in to_scan))
289
+
290
+ if self.debug:
291
+ from .earley_forest import ForestToPyDotVisitor
292
+ try:
293
+ debug_walker = ForestToPyDotVisitor()
294
+ except ImportError:
295
+ logger.warning("Cannot find dependency 'pydot', will not generate sppf debug image")
296
+ else:
297
+ for i, s in enumerate(solutions):
298
+ debug_walker.visit(s, f"sppf{i}.png")
299
+
300
+
301
+ if self.Tree is not None:
302
+ # Perform our SPPF -> AST conversion
303
+ transformer = ForestToParseTree(self.Tree, self.callbacks, self.forest_sum_visitor and self.forest_sum_visitor(), self.resolve_ambiguity)
304
+ solutions = [transformer.transform(s) for s in solutions]
305
+
306
+ if len(solutions) > 1:
307
+ t: Tree = self.Tree('_ambig', solutions)
308
+ t.expand_kids_by_data('_ambig') # solutions may themselves be _ambig nodes
309
+ return t
310
+ return solutions[0]
311
+
312
+ # return the root of the SPPF
313
+ # TODO return a list of solutions, or join them together somehow
314
+ return solutions[0]
@@ -0,0 +1,42 @@
1
+ """This module implements useful building blocks for the Earley parser
2
+ """
3
+
4
+
5
+ class Item:
6
+ "An Earley Item, the atom of the algorithm."
7
+
8
+ __slots__ = ('s', 'rule', 'ptr', 'start', 'is_complete', 'expect', 'previous', 'node', '_hash')
9
+ def __init__(self, rule, ptr, start):
10
+ self.is_complete = len(rule.expansion) == ptr
11
+ self.rule = rule # rule
12
+ self.ptr = ptr # ptr
13
+ self.start = start # j
14
+ self.node = None # w
15
+ if self.is_complete:
16
+ self.s = rule.origin
17
+ self.expect = None
18
+ self.previous = rule.expansion[ptr - 1] if ptr > 0 and len(rule.expansion) else None
19
+ else:
20
+ self.s = (rule, ptr)
21
+ self.expect = rule.expansion[ptr]
22
+ self.previous = rule.expansion[ptr - 1] if ptr > 0 and len(rule.expansion) else None
23
+ self._hash = hash((self.s, self.start, self.rule))
24
+
25
+ def advance(self):
26
+ return Item(self.rule, self.ptr + 1, self.start)
27
+
28
+ def __eq__(self, other):
29
+ return self is other or (self.s == other.s and self.start == other.start and self.rule == other.rule)
30
+
31
+ def __hash__(self):
32
+ return self._hash
33
+
34
+ def __repr__(self):
35
+ before = ( expansion.name for expansion in self.rule.expansion[:self.ptr] )
36
+ after = ( expansion.name for expansion in self.rule.expansion[self.ptr:] )
37
+ symbol = "{} ::= {}* {}".format(self.rule.origin.name, ' '.join(before), ' '.join(after))
38
+ return '%s (%d)' % (symbol, self.start)
39
+
40
+
41
+ # class TransitiveItem(Item):
42
+ # ... # removed at commit 4c1cfb2faf24e8f8bff7112627a00b94d261b420