ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__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.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +24 -0
- ccxt/abstract/kucoinfutures.py +34 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3030 -1087
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3104 -880
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +238 -49
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +199 -65
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +392 -148
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2231 -1193
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1454 -287
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +404 -109
- ccxt/async_support/deribit.py +557 -323
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1472 -463
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1633 -268
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +917 -357
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1776 -454
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1137 -296
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1722 -480
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3030 -1087
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3104 -880
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +238 -49
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +198 -65
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +392 -148
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2231 -1193
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1454 -287
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +404 -109
- ccxt/deribit.py +557 -323
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1472 -463
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1632 -268
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +917 -357
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1776 -454
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +62 -14
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +203 -81
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +965 -665
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +167 -31
- ccxt/pro/exmo.py +252 -20
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +92 -33
- ccxt/pro/poloniex.py +128 -49
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +92 -85
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +437 -65
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +456 -391
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +456 -393
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1137 -296
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.77.dist-info/METADATA +0 -626
- ccxt-4.2.77.dist-info/RECORD +0 -534
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,391 @@
|
|
1
|
+
"""Provides functions for the automatic building and shaping of the parse-tree."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from .exceptions import GrammarError, ConfigurationError
|
6
|
+
from .lexer import Token
|
7
|
+
from .tree import Tree
|
8
|
+
from .visitors import Transformer_InPlace
|
9
|
+
from .visitors import _vargs_meta, _vargs_meta_inline
|
10
|
+
|
11
|
+
###{standalone
|
12
|
+
from functools import partial, wraps
|
13
|
+
from itertools import product
|
14
|
+
|
15
|
+
|
16
|
+
class ExpandSingleChild:
|
17
|
+
def __init__(self, node_builder):
|
18
|
+
self.node_builder = node_builder
|
19
|
+
|
20
|
+
def __call__(self, children):
|
21
|
+
if len(children) == 1:
|
22
|
+
return children[0]
|
23
|
+
else:
|
24
|
+
return self.node_builder(children)
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
class PropagatePositions:
|
29
|
+
def __init__(self, node_builder, node_filter=None):
|
30
|
+
self.node_builder = node_builder
|
31
|
+
self.node_filter = node_filter
|
32
|
+
|
33
|
+
def __call__(self, children):
|
34
|
+
res = self.node_builder(children)
|
35
|
+
|
36
|
+
if isinstance(res, Tree):
|
37
|
+
# Calculate positions while the tree is streaming, according to the rule:
|
38
|
+
# - nodes start at the start of their first child's container,
|
39
|
+
# and end at the end of their last child's container.
|
40
|
+
# Containers are nodes that take up space in text, but have been inlined in the tree.
|
41
|
+
|
42
|
+
res_meta = res.meta
|
43
|
+
|
44
|
+
first_meta = self._pp_get_meta(children)
|
45
|
+
if first_meta is not None:
|
46
|
+
if not hasattr(res_meta, 'line'):
|
47
|
+
# meta was already set, probably because the rule has been inlined (e.g. `?rule`)
|
48
|
+
res_meta.line = getattr(first_meta, 'container_line', first_meta.line)
|
49
|
+
res_meta.column = getattr(first_meta, 'container_column', first_meta.column)
|
50
|
+
res_meta.start_pos = getattr(first_meta, 'container_start_pos', first_meta.start_pos)
|
51
|
+
res_meta.empty = False
|
52
|
+
|
53
|
+
res_meta.container_line = getattr(first_meta, 'container_line', first_meta.line)
|
54
|
+
res_meta.container_column = getattr(first_meta, 'container_column', first_meta.column)
|
55
|
+
res_meta.container_start_pos = getattr(first_meta, 'container_start_pos', first_meta.start_pos)
|
56
|
+
|
57
|
+
last_meta = self._pp_get_meta(reversed(children))
|
58
|
+
if last_meta is not None:
|
59
|
+
if not hasattr(res_meta, 'end_line'):
|
60
|
+
res_meta.end_line = getattr(last_meta, 'container_end_line', last_meta.end_line)
|
61
|
+
res_meta.end_column = getattr(last_meta, 'container_end_column', last_meta.end_column)
|
62
|
+
res_meta.end_pos = getattr(last_meta, 'container_end_pos', last_meta.end_pos)
|
63
|
+
res_meta.empty = False
|
64
|
+
|
65
|
+
res_meta.container_end_line = getattr(last_meta, 'container_end_line', last_meta.end_line)
|
66
|
+
res_meta.container_end_column = getattr(last_meta, 'container_end_column', last_meta.end_column)
|
67
|
+
res_meta.container_end_pos = getattr(last_meta, 'container_end_pos', last_meta.end_pos)
|
68
|
+
|
69
|
+
return res
|
70
|
+
|
71
|
+
def _pp_get_meta(self, children):
|
72
|
+
for c in children:
|
73
|
+
if self.node_filter is not None and not self.node_filter(c):
|
74
|
+
continue
|
75
|
+
if isinstance(c, Tree):
|
76
|
+
if not c.meta.empty:
|
77
|
+
return c.meta
|
78
|
+
elif isinstance(c, Token):
|
79
|
+
return c
|
80
|
+
elif hasattr(c, '__lark_meta__'):
|
81
|
+
return c.__lark_meta__()
|
82
|
+
|
83
|
+
def make_propagate_positions(option):
|
84
|
+
if callable(option):
|
85
|
+
return partial(PropagatePositions, node_filter=option)
|
86
|
+
elif option is True:
|
87
|
+
return PropagatePositions
|
88
|
+
elif option is False:
|
89
|
+
return None
|
90
|
+
|
91
|
+
raise ConfigurationError('Invalid option for propagate_positions: %r' % option)
|
92
|
+
|
93
|
+
|
94
|
+
class ChildFilter:
|
95
|
+
def __init__(self, to_include, append_none, node_builder):
|
96
|
+
self.node_builder = node_builder
|
97
|
+
self.to_include = to_include
|
98
|
+
self.append_none = append_none
|
99
|
+
|
100
|
+
def __call__(self, children):
|
101
|
+
filtered = []
|
102
|
+
|
103
|
+
for i, to_expand, add_none in self.to_include:
|
104
|
+
if add_none:
|
105
|
+
filtered += [None] * add_none
|
106
|
+
if to_expand:
|
107
|
+
filtered += children[i].children
|
108
|
+
else:
|
109
|
+
filtered.append(children[i])
|
110
|
+
|
111
|
+
if self.append_none:
|
112
|
+
filtered += [None] * self.append_none
|
113
|
+
|
114
|
+
return self.node_builder(filtered)
|
115
|
+
|
116
|
+
|
117
|
+
class ChildFilterLALR(ChildFilter):
|
118
|
+
"""Optimized childfilter for LALR (assumes no duplication in parse tree, so it's safe to change it)"""
|
119
|
+
|
120
|
+
def __call__(self, children):
|
121
|
+
filtered = []
|
122
|
+
for i, to_expand, add_none in self.to_include:
|
123
|
+
if add_none:
|
124
|
+
filtered += [None] * add_none
|
125
|
+
if to_expand:
|
126
|
+
if filtered:
|
127
|
+
filtered += children[i].children
|
128
|
+
else: # Optimize for left-recursion
|
129
|
+
filtered = children[i].children
|
130
|
+
else:
|
131
|
+
filtered.append(children[i])
|
132
|
+
|
133
|
+
if self.append_none:
|
134
|
+
filtered += [None] * self.append_none
|
135
|
+
|
136
|
+
return self.node_builder(filtered)
|
137
|
+
|
138
|
+
|
139
|
+
class ChildFilterLALR_NoPlaceholders(ChildFilter):
|
140
|
+
"Optimized childfilter for LALR (assumes no duplication in parse tree, so it's safe to change it)"
|
141
|
+
def __init__(self, to_include, node_builder):
|
142
|
+
self.node_builder = node_builder
|
143
|
+
self.to_include = to_include
|
144
|
+
|
145
|
+
def __call__(self, children):
|
146
|
+
filtered = []
|
147
|
+
for i, to_expand in self.to_include:
|
148
|
+
if to_expand:
|
149
|
+
if filtered:
|
150
|
+
filtered += children[i].children
|
151
|
+
else: # Optimize for left-recursion
|
152
|
+
filtered = children[i].children
|
153
|
+
else:
|
154
|
+
filtered.append(children[i])
|
155
|
+
return self.node_builder(filtered)
|
156
|
+
|
157
|
+
|
158
|
+
def _should_expand(sym):
|
159
|
+
return not sym.is_term and sym.name.startswith('_')
|
160
|
+
|
161
|
+
|
162
|
+
def maybe_create_child_filter(expansion, keep_all_tokens, ambiguous, _empty_indices: List[bool]):
|
163
|
+
# Prepare empty_indices as: How many Nones to insert at each index?
|
164
|
+
if _empty_indices:
|
165
|
+
assert _empty_indices.count(False) == len(expansion)
|
166
|
+
s = ''.join(str(int(b)) for b in _empty_indices)
|
167
|
+
empty_indices = [len(ones) for ones in s.split('0')]
|
168
|
+
assert len(empty_indices) == len(expansion)+1, (empty_indices, len(expansion))
|
169
|
+
else:
|
170
|
+
empty_indices = [0] * (len(expansion)+1)
|
171
|
+
|
172
|
+
to_include = []
|
173
|
+
nones_to_add = 0
|
174
|
+
for i, sym in enumerate(expansion):
|
175
|
+
nones_to_add += empty_indices[i]
|
176
|
+
if keep_all_tokens or not (sym.is_term and sym.filter_out):
|
177
|
+
to_include.append((i, _should_expand(sym), nones_to_add))
|
178
|
+
nones_to_add = 0
|
179
|
+
|
180
|
+
nones_to_add += empty_indices[len(expansion)]
|
181
|
+
|
182
|
+
if _empty_indices or len(to_include) < len(expansion) or any(to_expand for i, to_expand,_ in to_include):
|
183
|
+
if _empty_indices or ambiguous:
|
184
|
+
return partial(ChildFilter if ambiguous else ChildFilterLALR, to_include, nones_to_add)
|
185
|
+
else:
|
186
|
+
# LALR without placeholders
|
187
|
+
return partial(ChildFilterLALR_NoPlaceholders, [(i, x) for i,x,_ in to_include])
|
188
|
+
|
189
|
+
|
190
|
+
class AmbiguousExpander:
|
191
|
+
"""Deal with the case where we're expanding children ('_rule') into a parent but the children
|
192
|
+
are ambiguous. i.e. (parent->_ambig->_expand_this_rule). In this case, make the parent itself
|
193
|
+
ambiguous with as many copies as there are ambiguous children, and then copy the ambiguous children
|
194
|
+
into the right parents in the right places, essentially shifting the ambiguity up the tree."""
|
195
|
+
def __init__(self, to_expand, tree_class, node_builder):
|
196
|
+
self.node_builder = node_builder
|
197
|
+
self.tree_class = tree_class
|
198
|
+
self.to_expand = to_expand
|
199
|
+
|
200
|
+
def __call__(self, children):
|
201
|
+
def _is_ambig_tree(t):
|
202
|
+
return hasattr(t, 'data') and t.data == '_ambig'
|
203
|
+
|
204
|
+
# -- When we're repeatedly expanding ambiguities we can end up with nested ambiguities.
|
205
|
+
# All children of an _ambig node should be a derivation of that ambig node, hence
|
206
|
+
# it is safe to assume that if we see an _ambig node nested within an ambig node
|
207
|
+
# it is safe to simply expand it into the parent _ambig node as an alternative derivation.
|
208
|
+
ambiguous = []
|
209
|
+
for i, child in enumerate(children):
|
210
|
+
if _is_ambig_tree(child):
|
211
|
+
if i in self.to_expand:
|
212
|
+
ambiguous.append(i)
|
213
|
+
|
214
|
+
child.expand_kids_by_data('_ambig')
|
215
|
+
|
216
|
+
if not ambiguous:
|
217
|
+
return self.node_builder(children)
|
218
|
+
|
219
|
+
expand = [child.children if i in ambiguous else (child,) for i, child in enumerate(children)]
|
220
|
+
return self.tree_class('_ambig', [self.node_builder(list(f)) for f in product(*expand)])
|
221
|
+
|
222
|
+
|
223
|
+
def maybe_create_ambiguous_expander(tree_class, expansion, keep_all_tokens):
|
224
|
+
to_expand = [i for i, sym in enumerate(expansion)
|
225
|
+
if keep_all_tokens or ((not (sym.is_term and sym.filter_out)) and _should_expand(sym))]
|
226
|
+
if to_expand:
|
227
|
+
return partial(AmbiguousExpander, to_expand, tree_class)
|
228
|
+
|
229
|
+
|
230
|
+
class AmbiguousIntermediateExpander:
|
231
|
+
"""
|
232
|
+
Propagate ambiguous intermediate nodes and their derivations up to the
|
233
|
+
current rule.
|
234
|
+
|
235
|
+
In general, converts
|
236
|
+
|
237
|
+
rule
|
238
|
+
_iambig
|
239
|
+
_inter
|
240
|
+
someChildren1
|
241
|
+
...
|
242
|
+
_inter
|
243
|
+
someChildren2
|
244
|
+
...
|
245
|
+
someChildren3
|
246
|
+
...
|
247
|
+
|
248
|
+
to
|
249
|
+
|
250
|
+
_ambig
|
251
|
+
rule
|
252
|
+
someChildren1
|
253
|
+
...
|
254
|
+
someChildren3
|
255
|
+
...
|
256
|
+
rule
|
257
|
+
someChildren2
|
258
|
+
...
|
259
|
+
someChildren3
|
260
|
+
...
|
261
|
+
rule
|
262
|
+
childrenFromNestedIambigs
|
263
|
+
...
|
264
|
+
someChildren3
|
265
|
+
...
|
266
|
+
...
|
267
|
+
|
268
|
+
propagating up any nested '_iambig' nodes along the way.
|
269
|
+
"""
|
270
|
+
|
271
|
+
def __init__(self, tree_class, node_builder):
|
272
|
+
self.node_builder = node_builder
|
273
|
+
self.tree_class = tree_class
|
274
|
+
|
275
|
+
def __call__(self, children):
|
276
|
+
def _is_iambig_tree(child):
|
277
|
+
return hasattr(child, 'data') and child.data == '_iambig'
|
278
|
+
|
279
|
+
def _collapse_iambig(children):
|
280
|
+
"""
|
281
|
+
Recursively flatten the derivations of the parent of an '_iambig'
|
282
|
+
node. Returns a list of '_inter' nodes guaranteed not
|
283
|
+
to contain any nested '_iambig' nodes, or None if children does
|
284
|
+
not contain an '_iambig' node.
|
285
|
+
"""
|
286
|
+
|
287
|
+
# Due to the structure of the SPPF,
|
288
|
+
# an '_iambig' node can only appear as the first child
|
289
|
+
if children and _is_iambig_tree(children[0]):
|
290
|
+
iambig_node = children[0]
|
291
|
+
result = []
|
292
|
+
for grandchild in iambig_node.children:
|
293
|
+
collapsed = _collapse_iambig(grandchild.children)
|
294
|
+
if collapsed:
|
295
|
+
for child in collapsed:
|
296
|
+
child.children += children[1:]
|
297
|
+
result += collapsed
|
298
|
+
else:
|
299
|
+
new_tree = self.tree_class('_inter', grandchild.children + children[1:])
|
300
|
+
result.append(new_tree)
|
301
|
+
return result
|
302
|
+
|
303
|
+
collapsed = _collapse_iambig(children)
|
304
|
+
if collapsed:
|
305
|
+
processed_nodes = [self.node_builder(c.children) for c in collapsed]
|
306
|
+
return self.tree_class('_ambig', processed_nodes)
|
307
|
+
|
308
|
+
return self.node_builder(children)
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
def inplace_transformer(func):
|
313
|
+
@wraps(func)
|
314
|
+
def f(children):
|
315
|
+
# function name in a Transformer is a rule name.
|
316
|
+
tree = Tree(func.__name__, children)
|
317
|
+
return func(tree)
|
318
|
+
return f
|
319
|
+
|
320
|
+
|
321
|
+
def apply_visit_wrapper(func, name, wrapper):
|
322
|
+
if wrapper is _vargs_meta or wrapper is _vargs_meta_inline:
|
323
|
+
raise NotImplementedError("Meta args not supported for internal transformer")
|
324
|
+
|
325
|
+
@wraps(func)
|
326
|
+
def f(children):
|
327
|
+
return wrapper(func, name, children, None)
|
328
|
+
return f
|
329
|
+
|
330
|
+
|
331
|
+
class ParseTreeBuilder:
|
332
|
+
def __init__(self, rules, tree_class, propagate_positions=False, ambiguous=False, maybe_placeholders=False):
|
333
|
+
self.tree_class = tree_class
|
334
|
+
self.propagate_positions = propagate_positions
|
335
|
+
self.ambiguous = ambiguous
|
336
|
+
self.maybe_placeholders = maybe_placeholders
|
337
|
+
|
338
|
+
self.rule_builders = list(self._init_builders(rules))
|
339
|
+
|
340
|
+
def _init_builders(self, rules):
|
341
|
+
propagate_positions = make_propagate_positions(self.propagate_positions)
|
342
|
+
|
343
|
+
for rule in rules:
|
344
|
+
options = rule.options
|
345
|
+
keep_all_tokens = options.keep_all_tokens
|
346
|
+
expand_single_child = options.expand1
|
347
|
+
|
348
|
+
wrapper_chain = list(filter(None, [
|
349
|
+
(expand_single_child and not rule.alias) and ExpandSingleChild,
|
350
|
+
maybe_create_child_filter(rule.expansion, keep_all_tokens, self.ambiguous, options.empty_indices if self.maybe_placeholders else None),
|
351
|
+
propagate_positions,
|
352
|
+
self.ambiguous and maybe_create_ambiguous_expander(self.tree_class, rule.expansion, keep_all_tokens),
|
353
|
+
self.ambiguous and partial(AmbiguousIntermediateExpander, self.tree_class)
|
354
|
+
]))
|
355
|
+
|
356
|
+
yield rule, wrapper_chain
|
357
|
+
|
358
|
+
def create_callback(self, transformer=None):
|
359
|
+
callbacks = {}
|
360
|
+
|
361
|
+
default_handler = getattr(transformer, '__default__', None)
|
362
|
+
if default_handler:
|
363
|
+
def default_callback(data, children):
|
364
|
+
return default_handler(data, children, None)
|
365
|
+
else:
|
366
|
+
default_callback = self.tree_class
|
367
|
+
|
368
|
+
for rule, wrapper_chain in self.rule_builders:
|
369
|
+
|
370
|
+
user_callback_name = rule.alias or rule.options.template_source or rule.origin.name
|
371
|
+
try:
|
372
|
+
f = getattr(transformer, user_callback_name)
|
373
|
+
wrapper = getattr(f, 'visit_wrapper', None)
|
374
|
+
if wrapper is not None:
|
375
|
+
f = apply_visit_wrapper(f, user_callback_name, wrapper)
|
376
|
+
elif isinstance(transformer, Transformer_InPlace):
|
377
|
+
f = inplace_transformer(f)
|
378
|
+
except AttributeError:
|
379
|
+
f = partial(default_callback, user_callback_name)
|
380
|
+
|
381
|
+
for w in wrapper_chain:
|
382
|
+
f = w(f)
|
383
|
+
|
384
|
+
if rule in callbacks:
|
385
|
+
raise GrammarError("Rule '%s' already exists" % (rule,))
|
386
|
+
|
387
|
+
callbacks[rule] = f
|
388
|
+
|
389
|
+
return callbacks
|
390
|
+
|
391
|
+
###}
|
@@ -0,0 +1,257 @@
|
|
1
|
+
from typing import Any, Callable, Dict, Optional, Collection, Union, TYPE_CHECKING
|
2
|
+
|
3
|
+
from .exceptions import ConfigurationError, GrammarError, assert_config
|
4
|
+
from .utils import get_regexp_width, Serialize
|
5
|
+
from .lexer import LexerThread, BasicLexer, ContextualLexer, Lexer
|
6
|
+
from .parsers import earley, xearley, cyk
|
7
|
+
from .parsers.lalr_parser import LALR_Parser
|
8
|
+
from .tree import Tree
|
9
|
+
from .common import LexerConf, ParserConf, _ParserArgType, _LexerArgType
|
10
|
+
|
11
|
+
if TYPE_CHECKING:
|
12
|
+
from .parsers.lalr_analysis import ParseTableBase
|
13
|
+
|
14
|
+
|
15
|
+
###{standalone
|
16
|
+
|
17
|
+
def _wrap_lexer(lexer_class):
|
18
|
+
future_interface = getattr(lexer_class, '__future_interface__', False)
|
19
|
+
if future_interface:
|
20
|
+
return lexer_class
|
21
|
+
else:
|
22
|
+
class CustomLexerWrapper(Lexer):
|
23
|
+
def __init__(self, lexer_conf):
|
24
|
+
self.lexer = lexer_class(lexer_conf)
|
25
|
+
def lex(self, lexer_state, parser_state):
|
26
|
+
return self.lexer.lex(lexer_state.text)
|
27
|
+
return CustomLexerWrapper
|
28
|
+
|
29
|
+
|
30
|
+
def _deserialize_parsing_frontend(data, memo, lexer_conf, callbacks, options):
|
31
|
+
parser_conf = ParserConf.deserialize(data['parser_conf'], memo)
|
32
|
+
cls = (options and options._plugins.get('LALR_Parser')) or LALR_Parser
|
33
|
+
parser = cls.deserialize(data['parser'], memo, callbacks, options.debug)
|
34
|
+
parser_conf.callbacks = callbacks
|
35
|
+
return ParsingFrontend(lexer_conf, parser_conf, options, parser=parser)
|
36
|
+
|
37
|
+
|
38
|
+
_parser_creators: 'Dict[str, Callable[[LexerConf, Any, Any], Any]]' = {}
|
39
|
+
|
40
|
+
|
41
|
+
class ParsingFrontend(Serialize):
|
42
|
+
__serialize_fields__ = 'lexer_conf', 'parser_conf', 'parser'
|
43
|
+
|
44
|
+
lexer_conf: LexerConf
|
45
|
+
parser_conf: ParserConf
|
46
|
+
options: Any
|
47
|
+
|
48
|
+
def __init__(self, lexer_conf: LexerConf, parser_conf: ParserConf, options, parser=None):
|
49
|
+
self.parser_conf = parser_conf
|
50
|
+
self.lexer_conf = lexer_conf
|
51
|
+
self.options = options
|
52
|
+
|
53
|
+
# Set-up parser
|
54
|
+
if parser: # From cache
|
55
|
+
self.parser = parser
|
56
|
+
else:
|
57
|
+
create_parser = _parser_creators.get(parser_conf.parser_type)
|
58
|
+
assert create_parser is not None, "{} is not supported in standalone mode".format(
|
59
|
+
parser_conf.parser_type
|
60
|
+
)
|
61
|
+
self.parser = create_parser(lexer_conf, parser_conf, options)
|
62
|
+
|
63
|
+
# Set-up lexer
|
64
|
+
lexer_type = lexer_conf.lexer_type
|
65
|
+
self.skip_lexer = False
|
66
|
+
if lexer_type in ('dynamic', 'dynamic_complete'):
|
67
|
+
assert lexer_conf.postlex is None
|
68
|
+
self.skip_lexer = True
|
69
|
+
return
|
70
|
+
|
71
|
+
if isinstance(lexer_type, type):
|
72
|
+
assert issubclass(lexer_type, Lexer)
|
73
|
+
self.lexer = _wrap_lexer(lexer_type)(lexer_conf)
|
74
|
+
elif isinstance(lexer_type, str):
|
75
|
+
create_lexer = {
|
76
|
+
'basic': create_basic_lexer,
|
77
|
+
'contextual': create_contextual_lexer,
|
78
|
+
}[lexer_type]
|
79
|
+
self.lexer = create_lexer(lexer_conf, self.parser, lexer_conf.postlex, options)
|
80
|
+
else:
|
81
|
+
raise TypeError("Bad value for lexer_type: {lexer_type}")
|
82
|
+
|
83
|
+
if lexer_conf.postlex:
|
84
|
+
self.lexer = PostLexConnector(self.lexer, lexer_conf.postlex)
|
85
|
+
|
86
|
+
def _verify_start(self, start=None):
|
87
|
+
if start is None:
|
88
|
+
start_decls = self.parser_conf.start
|
89
|
+
if len(start_decls) > 1:
|
90
|
+
raise ConfigurationError("Lark initialized with more than 1 possible start rule. Must specify which start rule to parse", start_decls)
|
91
|
+
start ,= start_decls
|
92
|
+
elif start not in self.parser_conf.start:
|
93
|
+
raise ConfigurationError("Unknown start rule %s. Must be one of %r" % (start, self.parser_conf.start))
|
94
|
+
return start
|
95
|
+
|
96
|
+
def _make_lexer_thread(self, text: str) -> Union[str, LexerThread]:
|
97
|
+
cls = (self.options and self.options._plugins.get('LexerThread')) or LexerThread
|
98
|
+
return text if self.skip_lexer else cls.from_text(self.lexer, text)
|
99
|
+
|
100
|
+
def parse(self, text: str, start=None, on_error=None):
|
101
|
+
chosen_start = self._verify_start(start)
|
102
|
+
kw = {} if on_error is None else {'on_error': on_error}
|
103
|
+
stream = self._make_lexer_thread(text)
|
104
|
+
return self.parser.parse(stream, chosen_start, **kw)
|
105
|
+
|
106
|
+
def parse_interactive(self, text: Optional[str]=None, start=None):
|
107
|
+
# TODO BREAK - Change text from Optional[str] to text: str = ''.
|
108
|
+
# Would break behavior of exhaust_lexer(), which currently raises TypeError, and after the change would just return []
|
109
|
+
chosen_start = self._verify_start(start)
|
110
|
+
if self.parser_conf.parser_type != 'lalr':
|
111
|
+
raise ConfigurationError("parse_interactive() currently only works with parser='lalr' ")
|
112
|
+
stream = self._make_lexer_thread(text) # type: ignore[arg-type]
|
113
|
+
return self.parser.parse_interactive(stream, chosen_start)
|
114
|
+
|
115
|
+
|
116
|
+
def _validate_frontend_args(parser, lexer) -> None:
|
117
|
+
assert_config(parser, ('lalr', 'earley', 'cyk'))
|
118
|
+
if not isinstance(lexer, type): # not custom lexer?
|
119
|
+
expected = {
|
120
|
+
'lalr': ('basic', 'contextual'),
|
121
|
+
'earley': ('basic', 'dynamic', 'dynamic_complete'),
|
122
|
+
'cyk': ('basic', ),
|
123
|
+
}[parser]
|
124
|
+
assert_config(lexer, expected, 'Parser %r does not support lexer %%r, expected one of %%s' % parser)
|
125
|
+
|
126
|
+
|
127
|
+
def _get_lexer_callbacks(transformer, terminals):
|
128
|
+
result = {}
|
129
|
+
for terminal in terminals:
|
130
|
+
callback = getattr(transformer, terminal.name, None)
|
131
|
+
if callback is not None:
|
132
|
+
result[terminal.name] = callback
|
133
|
+
return result
|
134
|
+
|
135
|
+
class PostLexConnector:
|
136
|
+
def __init__(self, lexer, postlexer):
|
137
|
+
self.lexer = lexer
|
138
|
+
self.postlexer = postlexer
|
139
|
+
|
140
|
+
def lex(self, lexer_state, parser_state):
|
141
|
+
i = self.lexer.lex(lexer_state, parser_state)
|
142
|
+
return self.postlexer.process(i)
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
def create_basic_lexer(lexer_conf, parser, postlex, options) -> BasicLexer:
|
147
|
+
cls = (options and options._plugins.get('BasicLexer')) or BasicLexer
|
148
|
+
return cls(lexer_conf)
|
149
|
+
|
150
|
+
def create_contextual_lexer(lexer_conf: LexerConf, parser, postlex, options) -> ContextualLexer:
|
151
|
+
cls = (options and options._plugins.get('ContextualLexer')) or ContextualLexer
|
152
|
+
parse_table: ParseTableBase[int] = parser._parse_table
|
153
|
+
states: Dict[int, Collection[str]] = {idx:list(t.keys()) for idx, t in parse_table.states.items()}
|
154
|
+
always_accept: Collection[str] = postlex.always_accept if postlex else ()
|
155
|
+
return cls(lexer_conf, states, always_accept=always_accept)
|
156
|
+
|
157
|
+
def create_lalr_parser(lexer_conf: LexerConf, parser_conf: ParserConf, options=None) -> LALR_Parser:
|
158
|
+
debug = options.debug if options else False
|
159
|
+
strict = options.strict if options else False
|
160
|
+
cls = (options and options._plugins.get('LALR_Parser')) or LALR_Parser
|
161
|
+
return cls(parser_conf, debug=debug, strict=strict)
|
162
|
+
|
163
|
+
_parser_creators['lalr'] = create_lalr_parser
|
164
|
+
|
165
|
+
###}
|
166
|
+
|
167
|
+
class EarleyRegexpMatcher:
|
168
|
+
def __init__(self, lexer_conf):
|
169
|
+
self.regexps = {}
|
170
|
+
for t in lexer_conf.terminals:
|
171
|
+
regexp = t.pattern.to_regexp()
|
172
|
+
try:
|
173
|
+
width = get_regexp_width(regexp)[0]
|
174
|
+
except ValueError:
|
175
|
+
raise GrammarError("Bad regexp in token %s: %s" % (t.name, regexp))
|
176
|
+
else:
|
177
|
+
if width == 0:
|
178
|
+
raise GrammarError("Dynamic Earley doesn't allow zero-width regexps", t)
|
179
|
+
if lexer_conf.use_bytes:
|
180
|
+
regexp = regexp.encode('utf-8')
|
181
|
+
|
182
|
+
self.regexps[t.name] = lexer_conf.re_module.compile(regexp, lexer_conf.g_regex_flags)
|
183
|
+
|
184
|
+
def match(self, term, text, index=0):
|
185
|
+
return self.regexps[term.name].match(text, index)
|
186
|
+
|
187
|
+
|
188
|
+
def create_earley_parser__dynamic(lexer_conf: LexerConf, parser_conf: ParserConf, **kw):
|
189
|
+
if lexer_conf.callbacks:
|
190
|
+
raise GrammarError("Earley's dynamic lexer doesn't support lexer_callbacks.")
|
191
|
+
|
192
|
+
earley_matcher = EarleyRegexpMatcher(lexer_conf)
|
193
|
+
return xearley.Parser(lexer_conf, parser_conf, earley_matcher.match, **kw)
|
194
|
+
|
195
|
+
def _match_earley_basic(term, token):
|
196
|
+
return term.name == token.type
|
197
|
+
|
198
|
+
def create_earley_parser__basic(lexer_conf: LexerConf, parser_conf: ParserConf, **kw):
|
199
|
+
return earley.Parser(lexer_conf, parser_conf, _match_earley_basic, **kw)
|
200
|
+
|
201
|
+
def create_earley_parser(lexer_conf: LexerConf, parser_conf: ParserConf, options) -> earley.Parser:
|
202
|
+
resolve_ambiguity = options.ambiguity == 'resolve'
|
203
|
+
debug = options.debug if options else False
|
204
|
+
tree_class = options.tree_class or Tree if options.ambiguity != 'forest' else None
|
205
|
+
|
206
|
+
extra = {}
|
207
|
+
if lexer_conf.lexer_type == 'dynamic':
|
208
|
+
f = create_earley_parser__dynamic
|
209
|
+
elif lexer_conf.lexer_type == 'dynamic_complete':
|
210
|
+
extra['complete_lex'] = True
|
211
|
+
f = create_earley_parser__dynamic
|
212
|
+
else:
|
213
|
+
f = create_earley_parser__basic
|
214
|
+
|
215
|
+
return f(lexer_conf, parser_conf, resolve_ambiguity=resolve_ambiguity,
|
216
|
+
debug=debug, tree_class=tree_class, ordered_sets=options.ordered_sets, **extra)
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
class CYK_FrontEnd:
|
221
|
+
def __init__(self, lexer_conf, parser_conf, options=None):
|
222
|
+
self.parser = cyk.Parser(parser_conf.rules)
|
223
|
+
|
224
|
+
self.callbacks = parser_conf.callbacks
|
225
|
+
|
226
|
+
def parse(self, lexer_thread, start):
|
227
|
+
tokens = list(lexer_thread.lex(None))
|
228
|
+
tree = self.parser.parse(tokens, start)
|
229
|
+
return self._transform(tree)
|
230
|
+
|
231
|
+
def _transform(self, tree):
|
232
|
+
subtrees = list(tree.iter_subtrees())
|
233
|
+
for subtree in subtrees:
|
234
|
+
subtree.children = [self._apply_callback(c) if isinstance(c, Tree) else c for c in subtree.children]
|
235
|
+
|
236
|
+
return self._apply_callback(tree)
|
237
|
+
|
238
|
+
def _apply_callback(self, tree):
|
239
|
+
return self.callbacks[tree.rule](tree.children)
|
240
|
+
|
241
|
+
|
242
|
+
_parser_creators['earley'] = create_earley_parser
|
243
|
+
_parser_creators['cyk'] = CYK_FrontEnd
|
244
|
+
|
245
|
+
|
246
|
+
def _construct_parsing_frontend(
|
247
|
+
parser_type: _ParserArgType,
|
248
|
+
lexer_type: _LexerArgType,
|
249
|
+
lexer_conf,
|
250
|
+
parser_conf,
|
251
|
+
options
|
252
|
+
):
|
253
|
+
assert isinstance(lexer_conf, LexerConf)
|
254
|
+
assert isinstance(parser_conf, ParserConf)
|
255
|
+
parser_conf.parser_type = parser_type
|
256
|
+
lexer_conf.lexer_type = lexer_type
|
257
|
+
return ParsingFrontend(lexer_conf, parser_conf, options)
|
File without changes
|