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.
- 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 +3205 -937
- 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 +1525 -573
- 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 +223 -97
- 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 +639 -323
- ccxt/async_support/digifinex.py +465 -233
- ccxt/async_support/ellipx.py +1887 -0
- ccxt/async_support/exmo.py +317 -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 +433 -178
- ccxt/async_support/hollaex.py +207 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +178 -56
- ccxt/async_support/hyperliquid.py +1678 -292
- ccxt/async_support/idex.py +219 -95
- ccxt/async_support/independentreserve.py +300 -31
- ccxt/async_support/indodax.py +226 -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 +198 -107
- ccxt/async_support/latoken.py +199 -79
- ccxt/async_support/lbank.py +360 -113
- ccxt/async_support/luno.py +185 -62
- ccxt/async_support/lykke.py +168 -55
- ccxt/async_support/mercado.py +101 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +53 -0
- ccxt/async_support/ndax.py +234 -82
- ccxt/async_support/novadax.py +195 -75
- ccxt/async_support/oceanex.py +244 -59
- ccxt/async_support/okcoin.py +301 -165
- ccxt/async_support/okx.py +1776 -454
- ccxt/async_support/onetrading.py +198 -414
- ccxt/async_support/oxfun.py +2898 -0
- ccxt/async_support/p2b.py +142 -52
- ccxt/async_support/paradex.py +2085 -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 +3205 -937
- 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 +1525 -573
- 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 +223 -97
- 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 +639 -323
- ccxt/digifinex.py +465 -233
- ccxt/ellipx.py +1887 -0
- ccxt/exmo.py +317 -128
- ccxt/gate.py +1472 -463
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +433 -178
- ccxt/hollaex.py +207 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +178 -56
- ccxt/hyperliquid.py +1677 -292
- ccxt/idex.py +219 -95
- ccxt/independentreserve.py +299 -31
- ccxt/indodax.py +226 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +917 -357
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +198 -107
- ccxt/latoken.py +199 -79
- ccxt/lbank.py +360 -113
- ccxt/luno.py +185 -62
- ccxt/lykke.py +168 -55
- ccxt/mercado.py +101 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +53 -0
- ccxt/ndax.py +234 -82
- ccxt/novadax.py +195 -75
- ccxt/oceanex.py +244 -59
- ccxt/okcoin.py +301 -165
- ccxt/okx.py +1776 -454
- ccxt/onetrading.py +198 -414
- ccxt/oxfun.py +2897 -0
- ccxt/p2b.py +142 -52
- ccxt/paradex.py +2085 -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 +143 -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.49.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.49.dist-info/METADATA +646 -0
- ccxt-4.4.49.dist-info/RECORD +669 -0
- {ccxt-4.2.77.dist-info → ccxt-4.4.49.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.49.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
"""Abstract base classes.
|
2
|
+
|
3
|
+
These are necessary to avoid circular imports between schema.py and fields.py.
|
4
|
+
|
5
|
+
.. warning::
|
6
|
+
|
7
|
+
This module is treated as private API.
|
8
|
+
Users should not need to use this module directly.
|
9
|
+
"""
|
10
|
+
|
11
|
+
from __future__ import annotations
|
12
|
+
|
13
|
+
from abc import ABC, abstractmethod
|
14
|
+
|
15
|
+
|
16
|
+
class FieldABC(ABC):
|
17
|
+
"""Abstract base class from which all Field classes inherit."""
|
18
|
+
|
19
|
+
parent = None
|
20
|
+
name = None
|
21
|
+
root = None
|
22
|
+
|
23
|
+
@abstractmethod
|
24
|
+
def serialize(self, attr, obj, accessor=None):
|
25
|
+
pass
|
26
|
+
|
27
|
+
@abstractmethod
|
28
|
+
def deserialize(self, value):
|
29
|
+
pass
|
30
|
+
|
31
|
+
@abstractmethod
|
32
|
+
def _serialize(self, value, attr, obj, **kwargs):
|
33
|
+
pass
|
34
|
+
|
35
|
+
@abstractmethod
|
36
|
+
def _deserialize(self, value, attr, data, **kwargs):
|
37
|
+
pass
|
38
|
+
|
39
|
+
|
40
|
+
class SchemaABC(ABC):
|
41
|
+
"""Abstract base class from which all Schemas inherit."""
|
42
|
+
|
43
|
+
@abstractmethod
|
44
|
+
def dump(self, obj, *, many: bool | None = None):
|
45
|
+
pass
|
46
|
+
|
47
|
+
@abstractmethod
|
48
|
+
def dumps(self, obj, *, many: bool | None = None):
|
49
|
+
pass
|
50
|
+
|
51
|
+
@abstractmethod
|
52
|
+
def load(self, data, *, many: bool | None = None, partial=None, unknown=None):
|
53
|
+
pass
|
54
|
+
|
55
|
+
@abstractmethod
|
56
|
+
def loads(
|
57
|
+
self,
|
58
|
+
json_data,
|
59
|
+
*,
|
60
|
+
many: bool | None = None,
|
61
|
+
partial=None,
|
62
|
+
unknown=None,
|
63
|
+
**kwargs,
|
64
|
+
):
|
65
|
+
pass
|
@@ -0,0 +1,94 @@
|
|
1
|
+
"""A registry of :class:`Schema <marshmallow.Schema>` classes. This allows for string
|
2
|
+
lookup of schemas, which may be used with
|
3
|
+
class:`fields.Nested <marshmallow.fields.Nested>`.
|
4
|
+
|
5
|
+
.. warning::
|
6
|
+
|
7
|
+
This module is treated as private API.
|
8
|
+
Users should not need to use this module directly.
|
9
|
+
"""
|
10
|
+
|
11
|
+
from __future__ import annotations
|
12
|
+
|
13
|
+
import typing
|
14
|
+
|
15
|
+
from .exceptions import RegistryError
|
16
|
+
|
17
|
+
if typing.TYPE_CHECKING:
|
18
|
+
from . import Schema
|
19
|
+
|
20
|
+
SchemaType = typing.Type[Schema]
|
21
|
+
|
22
|
+
# {
|
23
|
+
# <class_name>: <list of class objects>
|
24
|
+
# <module_path_to_class>: <list of class objects>
|
25
|
+
# }
|
26
|
+
_registry = {} # type: dict[str, list[SchemaType]]
|
27
|
+
|
28
|
+
|
29
|
+
def register(classname: str, cls: SchemaType) -> None:
|
30
|
+
"""Add a class to the registry of serializer classes. When a class is
|
31
|
+
registered, an entry for both its classname and its full, module-qualified
|
32
|
+
path are added to the registry.
|
33
|
+
|
34
|
+
Example: ::
|
35
|
+
|
36
|
+
class MyClass:
|
37
|
+
pass
|
38
|
+
|
39
|
+
|
40
|
+
register("MyClass", MyClass)
|
41
|
+
# Registry:
|
42
|
+
# {
|
43
|
+
# 'MyClass': [path.to.MyClass],
|
44
|
+
# 'path.to.MyClass': [path.to.MyClass],
|
45
|
+
# }
|
46
|
+
|
47
|
+
"""
|
48
|
+
# Module where the class is located
|
49
|
+
module = cls.__module__
|
50
|
+
# Full module path to the class
|
51
|
+
# e.g. user.schemas.UserSchema
|
52
|
+
fullpath = ".".join([module, classname])
|
53
|
+
# If the class is already registered; need to check if the entries are
|
54
|
+
# in the same module as cls to avoid having multiple instances of the same
|
55
|
+
# class in the registry
|
56
|
+
if classname in _registry and not any(
|
57
|
+
each.__module__ == module for each in _registry[classname]
|
58
|
+
):
|
59
|
+
_registry[classname].append(cls)
|
60
|
+
elif classname not in _registry:
|
61
|
+
_registry[classname] = [cls]
|
62
|
+
|
63
|
+
# Also register the full path
|
64
|
+
if fullpath not in _registry:
|
65
|
+
_registry.setdefault(fullpath, []).append(cls)
|
66
|
+
else:
|
67
|
+
# If fullpath does exist, replace existing entry
|
68
|
+
_registry[fullpath] = [cls]
|
69
|
+
return None
|
70
|
+
|
71
|
+
|
72
|
+
def get_class(classname: str, all: bool = False) -> list[SchemaType] | SchemaType:
|
73
|
+
"""Retrieve a class from the registry.
|
74
|
+
|
75
|
+
:raises: marshmallow.exceptions.RegistryError if the class cannot be found
|
76
|
+
or if there are multiple entries for the given class name.
|
77
|
+
"""
|
78
|
+
try:
|
79
|
+
classes = _registry[classname]
|
80
|
+
except KeyError as error:
|
81
|
+
raise RegistryError(
|
82
|
+
f"Class with name {classname!r} was not found. You may need "
|
83
|
+
"to import the class."
|
84
|
+
) from error
|
85
|
+
if len(classes) > 1:
|
86
|
+
if all:
|
87
|
+
return _registry[classname]
|
88
|
+
raise RegistryError(
|
89
|
+
f"Multiple classes with name {classname!r} "
|
90
|
+
"were found. Please use the full, "
|
91
|
+
"module-qualified path."
|
92
|
+
)
|
93
|
+
else:
|
94
|
+
return _registry[classname][0]
|
@@ -0,0 +1,231 @@
|
|
1
|
+
"""Decorators for registering schema pre-processing and post-processing methods.
|
2
|
+
These should be imported from the top-level `marshmallow` module.
|
3
|
+
|
4
|
+
Methods decorated with
|
5
|
+
`pre_load <marshmallow.decorators.pre_load>`, `post_load <marshmallow.decorators.post_load>`,
|
6
|
+
`pre_dump <marshmallow.decorators.pre_dump>`, `post_dump <marshmallow.decorators.post_dump>`,
|
7
|
+
and `validates_schema <marshmallow.decorators.validates_schema>` receive
|
8
|
+
``many`` as a keyword argument. In addition, `pre_load <marshmallow.decorators.pre_load>`,
|
9
|
+
`post_load <marshmallow.decorators.post_load>`,
|
10
|
+
and `validates_schema <marshmallow.decorators.validates_schema>` receive
|
11
|
+
``partial``. If you don't need these arguments, add ``**kwargs`` to your method
|
12
|
+
signature.
|
13
|
+
|
14
|
+
|
15
|
+
Example: ::
|
16
|
+
|
17
|
+
from . import (
|
18
|
+
Schema,
|
19
|
+
pre_load,
|
20
|
+
pre_dump,
|
21
|
+
post_load,
|
22
|
+
validates_schema,
|
23
|
+
validates,
|
24
|
+
fields,
|
25
|
+
ValidationError,
|
26
|
+
)
|
27
|
+
|
28
|
+
|
29
|
+
class UserSchema(Schema):
|
30
|
+
email = fields.Str(required=True)
|
31
|
+
age = fields.Integer(required=True)
|
32
|
+
|
33
|
+
@post_load
|
34
|
+
def lowerstrip_email(self, item, many, **kwargs):
|
35
|
+
item["email"] = item["email"].lower().strip()
|
36
|
+
return item
|
37
|
+
|
38
|
+
@pre_load(pass_many=True)
|
39
|
+
def remove_envelope(self, data, many, **kwargs):
|
40
|
+
namespace = "results" if many else "result"
|
41
|
+
return data[namespace]
|
42
|
+
|
43
|
+
@post_dump(pass_many=True)
|
44
|
+
def add_envelope(self, data, many, **kwargs):
|
45
|
+
namespace = "results" if many else "result"
|
46
|
+
return {namespace: data}
|
47
|
+
|
48
|
+
@validates_schema
|
49
|
+
def validate_email(self, data, **kwargs):
|
50
|
+
if len(data["email"]) < 3:
|
51
|
+
raise ValidationError("Email must be more than 3 characters", "email")
|
52
|
+
|
53
|
+
@validates("age")
|
54
|
+
def validate_age(self, data, **kwargs):
|
55
|
+
if data < 14:
|
56
|
+
raise ValidationError("Too young!")
|
57
|
+
|
58
|
+
.. note::
|
59
|
+
These decorators only work with instance methods. Class and static
|
60
|
+
methods are not supported.
|
61
|
+
|
62
|
+
.. warning::
|
63
|
+
The invocation order of decorated methods of the same type is not guaranteed.
|
64
|
+
If you need to guarantee order of different processing steps, you should put
|
65
|
+
them in the same processing method.
|
66
|
+
"""
|
67
|
+
|
68
|
+
from __future__ import annotations
|
69
|
+
|
70
|
+
import functools
|
71
|
+
from typing import Any, Callable, cast
|
72
|
+
|
73
|
+
PRE_DUMP = "pre_dump"
|
74
|
+
POST_DUMP = "post_dump"
|
75
|
+
PRE_LOAD = "pre_load"
|
76
|
+
POST_LOAD = "post_load"
|
77
|
+
VALIDATES = "validates"
|
78
|
+
VALIDATES_SCHEMA = "validates_schema"
|
79
|
+
|
80
|
+
|
81
|
+
class MarshmallowHook:
|
82
|
+
__marshmallow_hook__: dict[tuple[str, bool] | str, Any] | None = None
|
83
|
+
|
84
|
+
|
85
|
+
def validates(field_name: str) -> Callable[..., Any]:
|
86
|
+
"""Register a field validator.
|
87
|
+
|
88
|
+
:param str field_name: Name of the field that the method validates.
|
89
|
+
"""
|
90
|
+
return set_hook(None, VALIDATES, field_name=field_name)
|
91
|
+
|
92
|
+
|
93
|
+
def validates_schema(
|
94
|
+
fn: Callable[..., Any] | None = None,
|
95
|
+
pass_many: bool = False,
|
96
|
+
pass_original: bool = False,
|
97
|
+
skip_on_field_errors: bool = True,
|
98
|
+
) -> Callable[..., Any]:
|
99
|
+
"""Register a schema-level validator.
|
100
|
+
|
101
|
+
By default it receives a single object at a time, transparently handling the ``many``
|
102
|
+
argument passed to the `Schema`'s :func:`~marshmallow.Schema.validate` call.
|
103
|
+
If ``pass_many=True``, the raw data (which may be a collection) is passed.
|
104
|
+
|
105
|
+
If ``pass_original=True``, the original data (before unmarshalling) will be passed as
|
106
|
+
an additional argument to the method.
|
107
|
+
|
108
|
+
If ``skip_on_field_errors=True``, this validation method will be skipped whenever
|
109
|
+
validation errors have been detected when validating fields.
|
110
|
+
|
111
|
+
.. versionchanged:: 3.0.0b1
|
112
|
+
``skip_on_field_errors`` defaults to `True`.
|
113
|
+
|
114
|
+
.. versionchanged:: 3.0.0
|
115
|
+
``partial`` and ``many`` are always passed as keyword arguments to
|
116
|
+
the decorated method.
|
117
|
+
"""
|
118
|
+
return set_hook(
|
119
|
+
fn,
|
120
|
+
(VALIDATES_SCHEMA, pass_many),
|
121
|
+
pass_original=pass_original,
|
122
|
+
skip_on_field_errors=skip_on_field_errors,
|
123
|
+
)
|
124
|
+
|
125
|
+
|
126
|
+
def pre_dump(
|
127
|
+
fn: Callable[..., Any] | None = None, pass_many: bool = False
|
128
|
+
) -> Callable[..., Any]:
|
129
|
+
"""Register a method to invoke before serializing an object. The method
|
130
|
+
receives the object to be serialized and returns the processed object.
|
131
|
+
|
132
|
+
By default it receives a single object at a time, transparently handling the ``many``
|
133
|
+
argument passed to the `Schema`'s :func:`~marshmallow.Schema.dump` call.
|
134
|
+
If ``pass_many=True``, the raw data (which may be a collection) is passed.
|
135
|
+
|
136
|
+
.. versionchanged:: 3.0.0
|
137
|
+
``many`` is always passed as a keyword arguments to the decorated method.
|
138
|
+
"""
|
139
|
+
return set_hook(fn, (PRE_DUMP, pass_many))
|
140
|
+
|
141
|
+
|
142
|
+
def post_dump(
|
143
|
+
fn: Callable[..., Any] | None = None,
|
144
|
+
pass_many: bool = False,
|
145
|
+
pass_original: bool = False,
|
146
|
+
) -> Callable[..., Any]:
|
147
|
+
"""Register a method to invoke after serializing an object. The method
|
148
|
+
receives the serialized object and returns the processed object.
|
149
|
+
|
150
|
+
By default it receives a single object at a time, transparently handling the ``many``
|
151
|
+
argument passed to the `Schema`'s :func:`~marshmallow.Schema.dump` call.
|
152
|
+
If ``pass_many=True``, the raw data (which may be a collection) is passed.
|
153
|
+
|
154
|
+
If ``pass_original=True``, the original data (before serializing) will be passed as
|
155
|
+
an additional argument to the method.
|
156
|
+
|
157
|
+
.. versionchanged:: 3.0.0
|
158
|
+
``many`` is always passed as a keyword arguments to the decorated method.
|
159
|
+
"""
|
160
|
+
return set_hook(fn, (POST_DUMP, pass_many), pass_original=pass_original)
|
161
|
+
|
162
|
+
|
163
|
+
def pre_load(
|
164
|
+
fn: Callable[..., Any] | None = None, pass_many: bool = False
|
165
|
+
) -> Callable[..., Any]:
|
166
|
+
"""Register a method to invoke before deserializing an object. The method
|
167
|
+
receives the data to be deserialized and returns the processed data.
|
168
|
+
|
169
|
+
By default it receives a single object at a time, transparently handling the ``many``
|
170
|
+
argument passed to the `Schema`'s :func:`~marshmallow.Schema.load` call.
|
171
|
+
If ``pass_many=True``, the raw data (which may be a collection) is passed.
|
172
|
+
|
173
|
+
.. versionchanged:: 3.0.0
|
174
|
+
``partial`` and ``many`` are always passed as keyword arguments to
|
175
|
+
the decorated method.
|
176
|
+
"""
|
177
|
+
return set_hook(fn, (PRE_LOAD, pass_many))
|
178
|
+
|
179
|
+
|
180
|
+
def post_load(
|
181
|
+
fn: Callable[..., Any] | None = None,
|
182
|
+
pass_many: bool = False,
|
183
|
+
pass_original: bool = False,
|
184
|
+
) -> Callable[..., Any]:
|
185
|
+
"""Register a method to invoke after deserializing an object. The method
|
186
|
+
receives the deserialized data and returns the processed data.
|
187
|
+
|
188
|
+
By default it receives a single object at a time, transparently handling the ``many``
|
189
|
+
argument passed to the `Schema`'s :func:`~marshmallow.Schema.load` call.
|
190
|
+
If ``pass_many=True``, the raw data (which may be a collection) is passed.
|
191
|
+
|
192
|
+
If ``pass_original=True``, the original data (before deserializing) will be passed as
|
193
|
+
an additional argument to the method.
|
194
|
+
|
195
|
+
.. versionchanged:: 3.0.0
|
196
|
+
``partial`` and ``many`` are always passed as keyword arguments to
|
197
|
+
the decorated method.
|
198
|
+
"""
|
199
|
+
return set_hook(fn, (POST_LOAD, pass_many), pass_original=pass_original)
|
200
|
+
|
201
|
+
|
202
|
+
def set_hook(
|
203
|
+
fn: Callable[..., Any] | None, key: tuple[str, bool] | str, **kwargs: Any
|
204
|
+
) -> Callable[..., Any]:
|
205
|
+
"""Mark decorated function as a hook to be picked up later.
|
206
|
+
You should not need to use this method directly.
|
207
|
+
|
208
|
+
.. note::
|
209
|
+
Currently only works with functions and instance methods. Class and
|
210
|
+
static methods are not supported.
|
211
|
+
|
212
|
+
:return: Decorated function if supplied, else this decorator with its args
|
213
|
+
bound.
|
214
|
+
"""
|
215
|
+
# Allow using this as either a decorator or a decorator factory.
|
216
|
+
if fn is None:
|
217
|
+
return functools.partial(set_hook, key=key, **kwargs)
|
218
|
+
|
219
|
+
# Set a __marshmallow_hook__ attribute instead of wrapping in some class,
|
220
|
+
# because I still want this to end up as a normal (unbound) method.
|
221
|
+
function = cast(MarshmallowHook, fn)
|
222
|
+
try:
|
223
|
+
hook_config = function.__marshmallow_hook__
|
224
|
+
except AttributeError:
|
225
|
+
function.__marshmallow_hook__ = hook_config = {}
|
226
|
+
# Also save the kwargs for the tagged function on
|
227
|
+
# __marshmallow_hook__, keyed by (<tag>, <pass_many>)
|
228
|
+
if hook_config is not None:
|
229
|
+
hook_config[key] = kwargs
|
230
|
+
|
231
|
+
return fn
|
@@ -0,0 +1,60 @@
|
|
1
|
+
"""Utilities for storing collections of error messages.
|
2
|
+
|
3
|
+
.. warning::
|
4
|
+
|
5
|
+
This module is treated as private API.
|
6
|
+
Users should not need to use this module directly.
|
7
|
+
"""
|
8
|
+
|
9
|
+
from .exceptions import SCHEMA
|
10
|
+
|
11
|
+
|
12
|
+
class ErrorStore:
|
13
|
+
def __init__(self):
|
14
|
+
#: Dictionary of errors stored during serialization
|
15
|
+
self.errors = {}
|
16
|
+
|
17
|
+
def store_error(self, messages, field_name=SCHEMA, index=None):
|
18
|
+
# field error -> store/merge error messages under field name key
|
19
|
+
# schema error -> if string or list, store/merge under _schema key
|
20
|
+
# -> if dict, store/merge with other top-level keys
|
21
|
+
if field_name != SCHEMA or not isinstance(messages, dict):
|
22
|
+
messages = {field_name: messages}
|
23
|
+
if index is not None:
|
24
|
+
messages = {index: messages}
|
25
|
+
self.errors = merge_errors(self.errors, messages)
|
26
|
+
|
27
|
+
|
28
|
+
def merge_errors(errors1, errors2):
|
29
|
+
"""Deeply merge two error messages.
|
30
|
+
|
31
|
+
The format of ``errors1`` and ``errors2`` matches the ``message``
|
32
|
+
parameter of :exc:`marshmallow.exceptions.ValidationError`.
|
33
|
+
"""
|
34
|
+
if not errors1:
|
35
|
+
return errors2
|
36
|
+
if not errors2:
|
37
|
+
return errors1
|
38
|
+
if isinstance(errors1, list):
|
39
|
+
if isinstance(errors2, list):
|
40
|
+
return errors1 + errors2
|
41
|
+
if isinstance(errors2, dict):
|
42
|
+
return dict(errors2, **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))})
|
43
|
+
return errors1 + [errors2]
|
44
|
+
if isinstance(errors1, dict):
|
45
|
+
if isinstance(errors2, list):
|
46
|
+
return dict(errors1, **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)})
|
47
|
+
if isinstance(errors2, dict):
|
48
|
+
errors = dict(errors1)
|
49
|
+
for key, val in errors2.items():
|
50
|
+
if key in errors:
|
51
|
+
errors[key] = merge_errors(errors[key], val)
|
52
|
+
else:
|
53
|
+
errors[key] = val
|
54
|
+
return errors
|
55
|
+
return dict(errors1, **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)})
|
56
|
+
if isinstance(errors2, list):
|
57
|
+
return [errors1] + errors2
|
58
|
+
if isinstance(errors2, dict):
|
59
|
+
return dict(errors2, **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))})
|
60
|
+
return [errors1, errors2]
|
@@ -0,0 +1,71 @@
|
|
1
|
+
"""Exception classes for marshmallow-related errors."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import typing
|
6
|
+
|
7
|
+
# Key used for schema-level validation errors
|
8
|
+
SCHEMA = "_schema"
|
9
|
+
|
10
|
+
|
11
|
+
class MarshmallowError(Exception):
|
12
|
+
"""Base class for all marshmallow-related errors."""
|
13
|
+
|
14
|
+
|
15
|
+
class ValidationError(MarshmallowError):
|
16
|
+
"""Raised when validation fails on a field or schema.
|
17
|
+
|
18
|
+
Validators and custom fields should raise this exception.
|
19
|
+
|
20
|
+
:param message: An error message, list of error messages, or dict of
|
21
|
+
error messages. If a dict, the keys are subitems and the values are error messages.
|
22
|
+
:param field_name: Field name to store the error on.
|
23
|
+
If `None`, the error is stored as schema-level error.
|
24
|
+
:param data: Raw input data.
|
25
|
+
:param valid_data: Valid (de)serialized data.
|
26
|
+
"""
|
27
|
+
|
28
|
+
def __init__(
|
29
|
+
self,
|
30
|
+
message: str | list | dict,
|
31
|
+
field_name: str = SCHEMA,
|
32
|
+
data: typing.Mapping[str, typing.Any]
|
33
|
+
| typing.Iterable[typing.Mapping[str, typing.Any]]
|
34
|
+
| None = None,
|
35
|
+
valid_data: list[dict[str, typing.Any]] | dict[str, typing.Any] | None = None,
|
36
|
+
**kwargs,
|
37
|
+
):
|
38
|
+
self.messages = [message] if isinstance(message, (str, bytes)) else message
|
39
|
+
self.field_name = field_name
|
40
|
+
self.data = data
|
41
|
+
self.valid_data = valid_data
|
42
|
+
self.kwargs = kwargs
|
43
|
+
super().__init__(message)
|
44
|
+
|
45
|
+
def normalized_messages(self):
|
46
|
+
if self.field_name == SCHEMA and isinstance(self.messages, dict):
|
47
|
+
return self.messages
|
48
|
+
return {self.field_name: self.messages}
|
49
|
+
|
50
|
+
@property
|
51
|
+
def messages_dict(self) -> dict[str, typing.Any]:
|
52
|
+
if not isinstance(self.messages, dict):
|
53
|
+
raise TypeError(
|
54
|
+
"cannot access 'messages_dict' when 'messages' is of type "
|
55
|
+
+ type(self.messages).__name__
|
56
|
+
)
|
57
|
+
return self.messages
|
58
|
+
|
59
|
+
|
60
|
+
class RegistryError(NameError):
|
61
|
+
"""Raised when an invalid operation is performed on the serializer
|
62
|
+
class registry.
|
63
|
+
"""
|
64
|
+
|
65
|
+
|
66
|
+
class StringNotCollectionError(MarshmallowError, TypeError):
|
67
|
+
"""Raised when a string is passed when a list of strings is expected."""
|
68
|
+
|
69
|
+
|
70
|
+
class FieldInstanceResolutionError(MarshmallowError, TypeError):
|
71
|
+
"""Raised when schema to instantiate is neither a Schema class nor an instance."""
|