lib-x17-fintech 2.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. lib_x17_fintech-2.1.3.dist-info/METADATA +633 -0
  2. lib_x17_fintech-2.1.3.dist-info/RECORD +282 -0
  3. lib_x17_fintech-2.1.3.dist-info/WHEEL +5 -0
  4. lib_x17_fintech-2.1.3.dist-info/licenses/LICENSE +1 -0
  5. lib_x17_fintech-2.1.3.dist-info/top_level.txt +1 -0
  6. xfintech/__init__.py +0 -0
  7. xfintech/connect/__init__.py +18 -0
  8. xfintech/connect/artifact/__init__.py +5 -0
  9. xfintech/connect/artifact/artifact.py +168 -0
  10. xfintech/connect/artifact/tests/__init__.py +3 -0
  11. xfintech/connect/artifact/tests/test_class_artifact_all.py +564 -0
  12. xfintech/connect/common/__init__.py +12 -0
  13. xfintech/connect/common/connect.py +49 -0
  14. xfintech/connect/common/connectref.py +119 -0
  15. xfintech/connect/common/error.py +62 -0
  16. xfintech/connect/common/tests/__init__.py +1 -0
  17. xfintech/connect/common/tests/test_class_connectlike_all.py +544 -0
  18. xfintech/connect/common/tests/test_class_connectref_all.py +586 -0
  19. xfintech/connect/common/tests/test_class_errors_all.py +524 -0
  20. xfintech/connect/instance/__init__.py +7 -0
  21. xfintech/connect/instance/macos.py +121 -0
  22. xfintech/connect/instance/s3.py +176 -0
  23. xfintech/connect/instance/tests/__init__.py +1 -0
  24. xfintech/connect/instance/tests/test_class_macosconnect_all.py +692 -0
  25. xfintech/connect/instance/tests/test_class_s3connect_all.py +603 -0
  26. xfintech/data/__init__.py +20 -0
  27. xfintech/data/common/__init__.py +15 -0
  28. xfintech/data/common/cache.py +186 -0
  29. xfintech/data/common/coolant.py +171 -0
  30. xfintech/data/common/metric.py +138 -0
  31. xfintech/data/common/paginate.py +132 -0
  32. xfintech/data/common/params.py +162 -0
  33. xfintech/data/common/retry.py +201 -0
  34. xfintech/data/common/tests/__init__.py +1 -0
  35. xfintech/data/common/tests/test_class_cache_all.py +681 -0
  36. xfintech/data/common/tests/test_class_coolant_all.py +534 -0
  37. xfintech/data/common/tests/test_class_metric_all.py +705 -0
  38. xfintech/data/common/tests/test_class_paginate_all.py +508 -0
  39. xfintech/data/common/tests/test_class_params_all.py +891 -0
  40. xfintech/data/common/tests/test_class_retry_all.py +714 -0
  41. xfintech/data/job/__init__.py +17 -0
  42. xfintech/data/job/errors.py +112 -0
  43. xfintech/data/job/house.py +156 -0
  44. xfintech/data/job/job.py +247 -0
  45. xfintech/data/job/joblike.py +47 -0
  46. xfintech/data/job/tests/__init__.py +1 -0
  47. xfintech/data/job/tests/test_class_errors_all.py +275 -0
  48. xfintech/data/job/tests/test_class_house_all.py +801 -0
  49. xfintech/data/job/tests/test_class_job_all.py +684 -0
  50. xfintech/data/job/tests/test_class_joblike_all.py +482 -0
  51. xfintech/data/relay/__init__.py +7 -0
  52. xfintech/data/relay/client.py +114 -0
  53. xfintech/data/relay/clientlike.py +45 -0
  54. xfintech/data/relay/tests/test_class_relayclient_all.py +484 -0
  55. xfintech/data/relay/tests/test_class_relayclientlike_all.py +500 -0
  56. xfintech/data/source/__init__.py +7 -0
  57. xfintech/data/source/baostock/__init__.py +21 -0
  58. xfintech/data/source/baostock/job/__init__.py +5 -0
  59. xfintech/data/source/baostock/job/job.py +217 -0
  60. xfintech/data/source/baostock/job/tests/__init__.py +0 -0
  61. xfintech/data/source/baostock/job/tests/test_class_baostockjob_all.py +547 -0
  62. xfintech/data/source/baostock/session/__init__.py +8 -0
  63. xfintech/data/source/baostock/session/relay.py +223 -0
  64. xfintech/data/source/baostock/session/session.py +241 -0
  65. xfintech/data/source/baostock/session/tests/__init__.py +0 -0
  66. xfintech/data/source/baostock/session/tests/test_class_relay_all.py +694 -0
  67. xfintech/data/source/baostock/session/tests/test_class_session_all.py +505 -0
  68. xfintech/data/source/baostock/stock/__init__.py +0 -0
  69. xfintech/data/source/baostock/stock/hs300stock/__init__.py +3 -0
  70. xfintech/data/source/baostock/stock/hs300stock/constant.py +49 -0
  71. xfintech/data/source/baostock/stock/hs300stock/hs300stock.py +133 -0
  72. xfintech/data/source/baostock/stock/hs300stock/tests/__init__.py +1 -0
  73. xfintech/data/source/baostock/stock/hs300stock/tests/test_class_hs300index_all.py +413 -0
  74. xfintech/data/source/baostock/stock/minuteline/__init__.py +19 -0
  75. xfintech/data/source/baostock/stock/minuteline/constant.py +89 -0
  76. xfintech/data/source/baostock/stock/minuteline/minuteline.py +163 -0
  77. xfintech/data/source/baostock/stock/minuteline/tests/__init__.py +0 -0
  78. xfintech/data/source/baostock/stock/minuteline/tests/test_class_minuteline_all.py +582 -0
  79. xfintech/data/source/baostock/stock/stock/__init__.py +19 -0
  80. xfintech/data/source/baostock/stock/stock/constant.py +55 -0
  81. xfintech/data/source/baostock/stock/stock/stock.py +149 -0
  82. xfintech/data/source/baostock/stock/stock/tests/__init__.py +0 -0
  83. xfintech/data/source/baostock/stock/stock/tests/test_class_stock_all.py +508 -0
  84. xfintech/data/source/baostock/stock/stockinfo/__init__.py +5 -0
  85. xfintech/data/source/baostock/stock/stockinfo/constant.py +66 -0
  86. xfintech/data/source/baostock/stock/stockinfo/stockinfo.py +176 -0
  87. xfintech/data/source/baostock/stock/stockinfo/tests/__init__.py +1 -0
  88. xfintech/data/source/baostock/stock/stockinfo/tests/test_class_stockinfo_all.py +617 -0
  89. xfintech/data/source/baostock/stock/sz50stock/__init__.py +3 -0
  90. xfintech/data/source/baostock/stock/sz50stock/constant.py +49 -0
  91. xfintech/data/source/baostock/stock/sz50stock/sz50stock.py +133 -0
  92. xfintech/data/source/baostock/stock/sz50stock/tests/__init__.py +1 -0
  93. xfintech/data/source/baostock/stock/sz50stock/tests/test_class_sz50stock_all.py +397 -0
  94. xfintech/data/source/baostock/stock/tradedate/__init__.py +19 -0
  95. xfintech/data/source/baostock/stock/tradedate/constant.py +72 -0
  96. xfintech/data/source/baostock/stock/tradedate/tests/__init__.py +0 -0
  97. xfintech/data/source/baostock/stock/tradedate/tests/test_class_tradedate_all.py +695 -0
  98. xfintech/data/source/baostock/stock/tradedate/tradedate.py +208 -0
  99. xfintech/data/source/baostock/stock/zz500stock/__init__.py +3 -0
  100. xfintech/data/source/baostock/stock/zz500stock/constant.py +55 -0
  101. xfintech/data/source/baostock/stock/zz500stock/tests/__init__.py +1 -0
  102. xfintech/data/source/baostock/stock/zz500stock/tests/test_class_zz500stock_all.py +421 -0
  103. xfintech/data/source/baostock/stock/zz500stock/zz500stock.py +133 -0
  104. xfintech/data/source/tushare/__init__.py +61 -0
  105. xfintech/data/source/tushare/job/__init__.py +5 -0
  106. xfintech/data/source/tushare/job/job.py +257 -0
  107. xfintech/data/source/tushare/job/tests/test_class_tusharejob_all.py +589 -0
  108. xfintech/data/source/tushare/session/__init__.py +5 -0
  109. xfintech/data/source/tushare/session/relay.py +231 -0
  110. xfintech/data/source/tushare/session/session.py +239 -0
  111. xfintech/data/source/tushare/session/tests/test_class_relay_all.py +719 -0
  112. xfintech/data/source/tushare/session/tests/test_class_session_all.py +705 -0
  113. xfintech/data/source/tushare/stock/__init__.py +55 -0
  114. xfintech/data/source/tushare/stock/adjfactor/__init__.py +19 -0
  115. xfintech/data/source/tushare/stock/adjfactor/adjfactor.py +150 -0
  116. xfintech/data/source/tushare/stock/adjfactor/constant.py +71 -0
  117. xfintech/data/source/tushare/stock/adjfactor/tests/__init__.py +0 -0
  118. xfintech/data/source/tushare/stock/adjfactor/tests/test_class_adjfactor_all.py +372 -0
  119. xfintech/data/source/tushare/stock/capflow/__init__.py +19 -0
  120. xfintech/data/source/tushare/stock/capflow/capflow.py +171 -0
  121. xfintech/data/source/tushare/stock/capflow/constant.py +105 -0
  122. xfintech/data/source/tushare/stock/capflow/tests/__init__.py +0 -0
  123. xfintech/data/source/tushare/stock/capflow/tests/test_class_capflow_all.py +589 -0
  124. xfintech/data/source/tushare/stock/capflowdc/__init__.py +19 -0
  125. xfintech/data/source/tushare/stock/capflowdc/capflowdc.py +167 -0
  126. xfintech/data/source/tushare/stock/capflowdc/constant.py +95 -0
  127. xfintech/data/source/tushare/stock/capflowdc/tests/__init__.py +0 -0
  128. xfintech/data/source/tushare/stock/capflowdc/tests/test_class_capflowdc_all.py +814 -0
  129. xfintech/data/source/tushare/stock/capflowths/__init__.py +19 -0
  130. xfintech/data/source/tushare/stock/capflowths/capflowths.py +173 -0
  131. xfintech/data/source/tushare/stock/capflowths/constant.py +92 -0
  132. xfintech/data/source/tushare/stock/capflowths/tests/__init__.py +0 -0
  133. xfintech/data/source/tushare/stock/capflowths/tests/test_class_capflowths_all.py +551 -0
  134. xfintech/data/source/tushare/stock/company/__init__.py +19 -0
  135. xfintech/data/source/tushare/stock/company/company.py +188 -0
  136. xfintech/data/source/tushare/stock/company/constant.py +92 -0
  137. xfintech/data/source/tushare/stock/company/tests/__init__.py +1 -0
  138. xfintech/data/source/tushare/stock/company/tests/test_class_company_all.py +829 -0
  139. xfintech/data/source/tushare/stock/companybusiness/__init__.py +21 -0
  140. xfintech/data/source/tushare/stock/companybusiness/companybusiness.py +183 -0
  141. xfintech/data/source/tushare/stock/companybusiness/constant.py +91 -0
  142. xfintech/data/source/tushare/stock/companybusiness/tests/__init__.py +0 -0
  143. xfintech/data/source/tushare/stock/companybusiness/tests/test_class_companybusiness_all.py +633 -0
  144. xfintech/data/source/tushare/stock/companycashflow/__init__.py +21 -0
  145. xfintech/data/source/tushare/stock/companycashflow/companycashflow.py +277 -0
  146. xfintech/data/source/tushare/stock/companycashflow/constant.py +293 -0
  147. xfintech/data/source/tushare/stock/companycashflow/tests/__init__.py +0 -0
  148. xfintech/data/source/tushare/stock/companycashflow/tests/test_class_companycashflow_all.py +619 -0
  149. xfintech/data/source/tushare/stock/companydebt/__init__.py +19 -0
  150. xfintech/data/source/tushare/stock/companydebt/companydebt.py +339 -0
  151. xfintech/data/source/tushare/stock/companydebt/constant.py +403 -0
  152. xfintech/data/source/tushare/stock/companydebt/tests/__init__.py +0 -0
  153. xfintech/data/source/tushare/stock/companydebt/tests/test_class_companydebt_all.py +655 -0
  154. xfintech/data/source/tushare/stock/companyoverview/__init__.py +21 -0
  155. xfintech/data/source/tushare/stock/companyoverview/companyoverview.py +214 -0
  156. xfintech/data/source/tushare/stock/companyoverview/constant.py +152 -0
  157. xfintech/data/source/tushare/stock/companyoverview/tests/__init__.py +0 -0
  158. xfintech/data/source/tushare/stock/companyoverview/tests/test_class_companyoverview_all.py +647 -0
  159. xfintech/data/source/tushare/stock/companyprofit/__init__.py +21 -0
  160. xfintech/data/source/tushare/stock/companyprofit/companyprofit.py +272 -0
  161. xfintech/data/source/tushare/stock/companyprofit/constant.py +259 -0
  162. xfintech/data/source/tushare/stock/companyprofit/tests/__init__.py +0 -0
  163. xfintech/data/source/tushare/stock/companyprofit/tests/test_class_companyprofit_all.py +635 -0
  164. xfintech/data/source/tushare/stock/conceptcapflowdc/__init__.py +21 -0
  165. xfintech/data/source/tushare/stock/conceptcapflowdc/conceptcapflowdc.py +175 -0
  166. xfintech/data/source/tushare/stock/conceptcapflowdc/constant.py +106 -0
  167. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/__init__.py +0 -0
  168. xfintech/data/source/tushare/stock/conceptcapflowdc/tests/test_class_conceptcapflowdc_all.py +568 -0
  169. xfintech/data/source/tushare/stock/conceptcapflowths/__init__.py +21 -0
  170. xfintech/data/source/tushare/stock/conceptcapflowths/conceptcapflowths.py +188 -0
  171. xfintech/data/source/tushare/stock/conceptcapflowths/constant.py +89 -0
  172. xfintech/data/source/tushare/stock/conceptcapflowths/tests/__init__.py +0 -0
  173. xfintech/data/source/tushare/stock/conceptcapflowths/tests/test_class_conceptcapflowths_all.py +516 -0
  174. xfintech/data/source/tushare/stock/dayline/__init__.py +19 -0
  175. xfintech/data/source/tushare/stock/dayline/constant.py +87 -0
  176. xfintech/data/source/tushare/stock/dayline/dayline.py +177 -0
  177. xfintech/data/source/tushare/stock/dayline/tests/__init__.py +0 -0
  178. xfintech/data/source/tushare/stock/dayline/tests/test_class_dayline_all.py +585 -0
  179. xfintech/data/source/tushare/stock/industrycapflowths/__init__.py +21 -0
  180. xfintech/data/source/tushare/stock/industrycapflowths/constant.py +89 -0
  181. xfintech/data/source/tushare/stock/industrycapflowths/industrycapflowths.py +192 -0
  182. xfintech/data/source/tushare/stock/industrycapflowths/tests/__init__.py +0 -0
  183. xfintech/data/source/tushare/stock/industrycapflowths/tests/test_class_industrycapflowths_all.py +683 -0
  184. xfintech/data/source/tushare/stock/marketindexcapflowdc/__init__.py +21 -0
  185. xfintech/data/source/tushare/stock/marketindexcapflowdc/constant.py +90 -0
  186. xfintech/data/source/tushare/stock/marketindexcapflowdc/marketindexcapflowdc.py +173 -0
  187. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/__init__.py +0 -0
  188. xfintech/data/source/tushare/stock/marketindexcapflowdc/tests/test_class_marketindexcapflowdc_all.py +793 -0
  189. xfintech/data/source/tushare/stock/monthline/__init__.py +19 -0
  190. xfintech/data/source/tushare/stock/monthline/constant.py +87 -0
  191. xfintech/data/source/tushare/stock/monthline/monthline.py +180 -0
  192. xfintech/data/source/tushare/stock/monthline/tests/__init__.py +0 -0
  193. xfintech/data/source/tushare/stock/monthline/tests/test_class_monthline_all.py +574 -0
  194. xfintech/data/source/tushare/stock/stock/__init__.py +19 -0
  195. xfintech/data/source/tushare/stock/stock/constant.py +105 -0
  196. xfintech/data/source/tushare/stock/stock/stock.py +193 -0
  197. xfintech/data/source/tushare/stock/stock/tests/__init__.py +0 -0
  198. xfintech/data/source/tushare/stock/stock/tests/test_class_stock_all.py +788 -0
  199. xfintech/data/source/tushare/stock/stockdividend/__init__.py +21 -0
  200. xfintech/data/source/tushare/stock/stockdividend/constant.py +111 -0
  201. xfintech/data/source/tushare/stock/stockdividend/stockdividend.py +180 -0
  202. xfintech/data/source/tushare/stock/stockdividend/tests/__init__.py +0 -0
  203. xfintech/data/source/tushare/stock/stockdividend/tests/test_class_stockdividend_all.py +725 -0
  204. xfintech/data/source/tushare/stock/stockinfo/__init__.py +19 -0
  205. xfintech/data/source/tushare/stock/stockinfo/constant.py +104 -0
  206. xfintech/data/source/tushare/stock/stockinfo/stockinfo.py +208 -0
  207. xfintech/data/source/tushare/stock/stockinfo/tests/__init__.py +0 -0
  208. xfintech/data/source/tushare/stock/stockinfo/tests/test_class_stockinfo_all.py +881 -0
  209. xfintech/data/source/tushare/stock/stockipo/__init__.py +19 -0
  210. xfintech/data/source/tushare/stock/stockipo/constant.py +90 -0
  211. xfintech/data/source/tushare/stock/stockipo/stockipo.py +234 -0
  212. xfintech/data/source/tushare/stock/stockipo/tests/__init__.py +1 -0
  213. xfintech/data/source/tushare/stock/stockipo/tests/test_class_stockipo_all.py +750 -0
  214. xfintech/data/source/tushare/stock/stockpledge/__init__.py +19 -0
  215. xfintech/data/source/tushare/stock/stockpledge/constant.py +72 -0
  216. xfintech/data/source/tushare/stock/stockpledge/stockpledge.py +158 -0
  217. xfintech/data/source/tushare/stock/stockpledge/tests/__init__.py +0 -0
  218. xfintech/data/source/tushare/stock/stockpledge/tests/test_class_stockpledge_all.py +664 -0
  219. xfintech/data/source/tushare/stock/stockpledgedetail/__init__.py +21 -0
  220. xfintech/data/source/tushare/stock/stockpledgedetail/constant.py +85 -0
  221. xfintech/data/source/tushare/stock/stockpledgedetail/stockpledgedetail.py +171 -0
  222. xfintech/data/source/tushare/stock/stockpledgedetail/tests/__init__.py +0 -0
  223. xfintech/data/source/tushare/stock/stockpledgedetail/tests/test_class_stockpledgedetail_all.py +112 -0
  224. xfintech/data/source/tushare/stock/stockst/__init__.py +19 -0
  225. xfintech/data/source/tushare/stock/stockst/constant.py +80 -0
  226. xfintech/data/source/tushare/stock/stockst/stockst.py +189 -0
  227. xfintech/data/source/tushare/stock/stockst/tests/__init__.py +0 -0
  228. xfintech/data/source/tushare/stock/stockst/tests/test_class_stockst_all.py +693 -0
  229. xfintech/data/source/tushare/stock/stocksuspend/__init__.py +21 -0
  230. xfintech/data/source/tushare/stock/stocksuspend/constant.py +75 -0
  231. xfintech/data/source/tushare/stock/stocksuspend/stocksuspend.py +151 -0
  232. xfintech/data/source/tushare/stock/stocksuspend/tests/__init__.py +0 -0
  233. xfintech/data/source/tushare/stock/stocksuspend/tests/test_class_stocksuspend_all.py +626 -0
  234. xfintech/data/source/tushare/stock/techindex/__init__.py +19 -0
  235. xfintech/data/source/tushare/stock/techindex/constant.py +600 -0
  236. xfintech/data/source/tushare/stock/techindex/techindex.py +314 -0
  237. xfintech/data/source/tushare/stock/techindex/tests/__init__.py +0 -0
  238. xfintech/data/source/tushare/stock/techindex/tests/test_class_techindex_all.py +576 -0
  239. xfintech/data/source/tushare/stock/tradedate/__init__.py +19 -0
  240. xfintech/data/source/tushare/stock/tradedate/constant.py +93 -0
  241. xfintech/data/source/tushare/stock/tradedate/tests/__init__.py +0 -0
  242. xfintech/data/source/tushare/stock/tradedate/tests/test_class_tradedate_all.py +947 -0
  243. xfintech/data/source/tushare/stock/tradedate/tradedate.py +234 -0
  244. xfintech/data/source/tushare/stock/weekline/__init__.py +19 -0
  245. xfintech/data/source/tushare/stock/weekline/constant.py +87 -0
  246. xfintech/data/source/tushare/stock/weekline/tests/__init__.py +0 -0
  247. xfintech/data/source/tushare/stock/weekline/tests/test_class_weekline_all.py +575 -0
  248. xfintech/data/source/tushare/stock/weekline/weekline.py +182 -0
  249. xfintech/fabric/__init__.py +18 -0
  250. xfintech/fabric/column/__init__.py +7 -0
  251. xfintech/fabric/column/info.py +202 -0
  252. xfintech/fabric/column/kind.py +102 -0
  253. xfintech/fabric/column/tests/__init__.py +0 -0
  254. xfintech/fabric/column/tests/test_class_info_all.py +207 -0
  255. xfintech/fabric/column/tests/test_class_kind_all.py +80 -0
  256. xfintech/fabric/table/__init__.py +5 -0
  257. xfintech/fabric/table/info.py +263 -0
  258. xfintech/fabric/table/tests/__init__.py +0 -0
  259. xfintech/fabric/table/tests/test_class_info_all.py +547 -0
  260. xfintech/serde/__init__.py +35 -0
  261. xfintech/serde/common/__init__.py +9 -0
  262. xfintech/serde/common/dataformat.py +78 -0
  263. xfintech/serde/common/deserialiserlike.py +38 -0
  264. xfintech/serde/common/error.py +182 -0
  265. xfintech/serde/common/serialiserlike.py +38 -0
  266. xfintech/serde/common/tests/__init__.py +1 -0
  267. xfintech/serde/common/tests/test_class_dataformat_all.py +694 -0
  268. xfintech/serde/common/tests/test_class_deserialiserlike_all.py +500 -0
  269. xfintech/serde/common/tests/test_class_errors_all.py +518 -0
  270. xfintech/serde/common/tests/test_class_serialiserlike_all.py +401 -0
  271. xfintech/serde/deserialiser/__init__.py +7 -0
  272. xfintech/serde/deserialiser/pandas.py +113 -0
  273. xfintech/serde/deserialiser/python.py +68 -0
  274. xfintech/serde/deserialiser/tests/__init__.py +1 -0
  275. xfintech/serde/deserialiser/tests/test_class_pandasdeserialiser_all.py +503 -0
  276. xfintech/serde/deserialiser/tests/test_class_pythondeserialiser_all.py +570 -0
  277. xfintech/serde/serialiser/__init__.py +7 -0
  278. xfintech/serde/serialiser/pandas.py +116 -0
  279. xfintech/serde/serialiser/python.py +71 -0
  280. xfintech/serde/serialiser/tests/__init__.py +1 -0
  281. xfintech/serde/serialiser/tests/test_class_pandasserialiser_all.py +474 -0
  282. xfintech/serde/serialiser/tests/test_class_pythonserialiser_all.py +508 -0
@@ -0,0 +1,500 @@
1
+ """
2
+ 描述:
3
+ - DeserialiserLike 协议的单元测试。
4
+ - 测试协议的结构、实现和运行时类型检查。
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+
11
+ from xfintech.serde.common.dataformat import DataFormat
12
+ from xfintech.serde.common.deserialiserlike import DeserialiserLike
13
+
14
+ # =============================================================================
15
+ # Protocol Structure Tests
16
+ # =============================================================================
17
+
18
+
19
+ def test_deserialiserlike_is_protocol():
20
+ """测试 DeserialiserLike 是一个协议类"""
21
+ from typing import Protocol
22
+
23
+ assert issubclass(DeserialiserLike.__class__, type(Protocol))
24
+
25
+
26
+ def test_deserialiserlike_has_deserialise_method():
27
+ """测试 DeserialiserLike 定义了 deserialise 方法"""
28
+ assert hasattr(DeserialiserLike, "deserialise")
29
+
30
+
31
+ def test_deserialiserlike_method_signature():
32
+ """测试 deserialise 方法签名"""
33
+ import inspect
34
+
35
+ sig = inspect.signature(DeserialiserLike.deserialise)
36
+ params = list(sig.parameters.keys())
37
+ assert "data" in params
38
+ assert "format" in params
39
+ assert "kwargs" in params
40
+
41
+
42
+ # =============================================================================
43
+ # Implementation Tests - Valid Implementations
44
+ # =============================================================================
45
+
46
+
47
+ def test_valid_implementation_with_staticmethod():
48
+ """测试使用 staticmethod 的有效实现"""
49
+
50
+ class ValidDeserialiser:
51
+ @staticmethod
52
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
53
+ return {"result": "test"}
54
+
55
+ instance = ValidDeserialiser()
56
+ assert isinstance(instance, DeserialiserLike)
57
+
58
+
59
+ def test_valid_implementation_with_classmethod():
60
+ """测试使用 classmethod 的有效实现"""
61
+
62
+ class ValidDeserialiser:
63
+ @classmethod
64
+ def deserialise(cls, data: Any, format: Any, **kwargs: Any) -> Any:
65
+ return {"result": "test"}
66
+
67
+ instance = ValidDeserialiser()
68
+ assert isinstance(instance, DeserialiserLike)
69
+
70
+
71
+ def test_valid_implementation_with_instance_method():
72
+ """测试使用实例方法的有效实现"""
73
+
74
+ class ValidDeserialiser:
75
+ def deserialise(self, data: Any, format: Any, **kwargs: Any) -> Any:
76
+ return {"result": "test"}
77
+
78
+ instance = ValidDeserialiser()
79
+ assert isinstance(instance, DeserialiserLike)
80
+
81
+
82
+ def test_valid_implementation_can_call_deserialise():
83
+ """测试有效实现可以调用 deserialise"""
84
+
85
+ class ValidDeserialiser:
86
+ @staticmethod
87
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
88
+ return {"deserialised": True}
89
+
90
+ deserialiser = ValidDeserialiser()
91
+ result = deserialiser.deserialise(b"data", DataFormat.JSON)
92
+ assert result == {"deserialised": True}
93
+
94
+
95
+ def test_valid_implementation_with_kwargs():
96
+ """测试有效实现支持 kwargs"""
97
+
98
+ class ValidDeserialiser:
99
+ @staticmethod
100
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
101
+ encoding = kwargs.get("encoding", "utf-8")
102
+ return {"encoding": encoding}
103
+
104
+ deserialiser = ValidDeserialiser()
105
+ result = deserialiser.deserialise(b"data", DataFormat.JSON, encoding="ascii")
106
+ assert result == {"encoding": "ascii"}
107
+
108
+
109
+ def test_valid_implementation_with_complex_logic():
110
+ """测试有效实现包含复杂逻辑"""
111
+ import json
112
+
113
+ class ComplexDeserialiser:
114
+ @staticmethod
115
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
116
+ if format == DataFormat.JSON:
117
+ return json.loads(data)
118
+ elif format == DataFormat.CSV:
119
+ return {"type": "csv"}
120
+ else:
121
+ return {"type": "unknown"}
122
+
123
+ deserialiser = ComplexDeserialiser()
124
+ assert isinstance(deserialiser, DeserialiserLike)
125
+ result = deserialiser.deserialise(b'{"key": "value"}', DataFormat.JSON)
126
+ assert result == {"key": "value"}
127
+
128
+
129
+ # =============================================================================
130
+ # Implementation Tests - Invalid Implementations
131
+ # =============================================================================
132
+
133
+
134
+ def test_invalid_implementation_missing_method():
135
+ """测试缺少 deserialise 方法的实现"""
136
+
137
+ class InvalidDeserialiser:
138
+ pass
139
+
140
+ instance = InvalidDeserialiser()
141
+ assert not isinstance(instance, DeserialiserLike)
142
+
143
+
144
+ def test_invalid_implementation_wrong_method_name():
145
+ """测试方法名错误的实现"""
146
+
147
+ class InvalidDeserialiser:
148
+ @staticmethod
149
+ def deserialize(data: Any, format: Any, **kwargs: Any) -> Any:
150
+ return {}
151
+
152
+ instance = InvalidDeserialiser()
153
+ assert not isinstance(instance, DeserialiserLike)
154
+
155
+
156
+ def test_property_implementation_is_valid():
157
+ """测试使用 property 的实现也是有效的"""
158
+
159
+ class PropertyDeserialiser:
160
+ @property
161
+ def deserialise(self):
162
+ return lambda data, format, **kwargs: {}
163
+
164
+ instance = PropertyDeserialiser()
165
+ # Python's Protocol accepts properties with callable values
166
+ assert isinstance(instance, DeserialiserLike)
167
+
168
+
169
+ # =============================================================================
170
+ # Type Checking Tests
171
+ # =============================================================================
172
+
173
+
174
+ def test_isinstance_with_valid_class():
175
+ """测试 isinstance 检查有效类"""
176
+
177
+ class MyDeserialiser:
178
+ @staticmethod
179
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
180
+ return {}
181
+
182
+ assert isinstance(MyDeserialiser(), DeserialiserLike)
183
+
184
+
185
+ def test_isinstance_with_invalid_class():
186
+ """测试 isinstance 检查无效类"""
187
+
188
+ class NotDeserialiser:
189
+ def other_method(self):
190
+ pass
191
+
192
+ assert not isinstance(NotDeserialiser(), DeserialiserLike)
193
+
194
+
195
+ def test_isinstance_with_builtin_types():
196
+ """测试 isinstance 检查内置类型"""
197
+ assert not isinstance(str(), DeserialiserLike)
198
+ assert not isinstance(int(), DeserialiserLike)
199
+ assert not isinstance(list(), DeserialiserLike)
200
+ assert not isinstance(dict(), DeserialiserLike)
201
+
202
+
203
+ def test_isinstance_with_none():
204
+ """测试 isinstance 检查 None"""
205
+ assert not isinstance(None, DeserialiserLike)
206
+
207
+
208
+ # =============================================================================
209
+ # Inheritance Tests
210
+ # =============================================================================
211
+
212
+
213
+ def test_can_inherit_from_protocol():
214
+ """测试可以继承协议"""
215
+
216
+ class BaseDeserialiser(DeserialiserLike):
217
+ @staticmethod
218
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
219
+ return {"base": True}
220
+
221
+ instance = BaseDeserialiser()
222
+ assert isinstance(instance, DeserialiserLike)
223
+
224
+
225
+ def test_inherited_class_can_override():
226
+ """测试继承类可以重写方法"""
227
+
228
+ class BaseDeserialiser(DeserialiserLike):
229
+ @staticmethod
230
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
231
+ return {"base": True}
232
+
233
+ class DerivedDeserialiser(BaseDeserialiser):
234
+ @staticmethod
235
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
236
+ return {"derived": True}
237
+
238
+ derived = DerivedDeserialiser()
239
+ assert isinstance(derived, DeserialiserLike)
240
+ assert derived.deserialise(b"", DataFormat.JSON) == {"derived": True}
241
+
242
+
243
+ # =============================================================================
244
+ # Return Type Tests
245
+ # =============================================================================
246
+
247
+
248
+ def test_can_return_dict():
249
+ """测试可以返回字典"""
250
+
251
+ class DictDeserialiser:
252
+ @staticmethod
253
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
254
+ return {"key": "value"}
255
+
256
+ deserialiser = DictDeserialiser()
257
+ result = deserialiser.deserialise(b"", DataFormat.JSON)
258
+ assert isinstance(result, dict)
259
+
260
+
261
+ def test_can_return_dataframe():
262
+ """测试可以返回 DataFrame(模拟)"""
263
+
264
+ class DataFrameDeserialiser:
265
+ @staticmethod
266
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
267
+ # Return a mock DataFrame-like object
268
+ class MockDataFrame:
269
+ pass
270
+
271
+ return MockDataFrame()
272
+
273
+ deserialiser = DataFrameDeserialiser()
274
+ assert isinstance(deserialiser, DeserialiserLike)
275
+
276
+
277
+ def test_can_return_list():
278
+ """测试可以返回列表"""
279
+
280
+ class ListDeserialiser:
281
+ @staticmethod
282
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
283
+ return [1, 2, 3]
284
+
285
+ deserialiser = ListDeserialiser()
286
+ result = deserialiser.deserialise(b"", DataFormat.CSV)
287
+ assert isinstance(result, list)
288
+
289
+
290
+ def test_can_return_none():
291
+ """测试可以返回 None"""
292
+
293
+ class NoneDeserialiser:
294
+ @staticmethod
295
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
296
+ return None
297
+
298
+ deserialiser = NoneDeserialiser()
299
+ result = deserialiser.deserialise(b"", DataFormat.JSON)
300
+ assert result is None
301
+
302
+
303
+ # =============================================================================
304
+ # Edge Cases Tests
305
+ # =============================================================================
306
+
307
+
308
+ def test_implementation_with_default_arguments():
309
+ """测试带默认参数的实现"""
310
+
311
+ class DeserialiserWithDefaults:
312
+ @staticmethod
313
+ def deserialise(data: Any, format: Any = DataFormat.JSON, **kwargs: Any) -> Any:
314
+ return {"default": True}
315
+
316
+ deserialiser = DeserialiserWithDefaults()
317
+ assert isinstance(deserialiser, DeserialiserLike)
318
+
319
+
320
+ def test_implementation_with_extra_methods():
321
+ """测试包含额外方法的实现"""
322
+
323
+ class RichDeserialiser:
324
+ @staticmethod
325
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
326
+ return {}
327
+
328
+ @staticmethod
329
+ def validate(data: Any) -> bool:
330
+ return True
331
+
332
+ deserialiser = RichDeserialiser()
333
+ assert isinstance(deserialiser, DeserialiserLike)
334
+
335
+
336
+ def test_implementation_with_attributes():
337
+ """测试包含属性的实现"""
338
+
339
+ class DeserialiserWithState:
340
+ def __init__(self):
341
+ self.counter = 0
342
+
343
+ def deserialise(self, data: Any, format: Any, **kwargs: Any) -> Any:
344
+ self.counter += 1
345
+ return {"count": self.counter}
346
+
347
+ deserialiser = DeserialiserWithState()
348
+ assert isinstance(deserialiser, DeserialiserLike)
349
+
350
+
351
+ def test_callable_object_as_implementation():
352
+ """测试可调用对象作为实现"""
353
+
354
+ class CallableDeserialiser:
355
+ def deserialise(self, data: Any, format: Any, **kwargs: Any) -> Any:
356
+ return {"callable": True}
357
+
358
+ instance = CallableDeserialiser()
359
+ assert isinstance(instance, DeserialiserLike)
360
+
361
+
362
+ # =============================================================================
363
+ # Real-World Usage Tests
364
+ # =============================================================================
365
+
366
+
367
+ def test_parquet_deserialiser_implementation():
368
+ """测试 Parquet 反序列化器实现"""
369
+
370
+ class ParquetDeserialiser:
371
+ @staticmethod
372
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
373
+ if format != DataFormat.PARQUET:
374
+ raise ValueError(f"Unsupported format: {format}")
375
+ # Simulate parquet deserialization
376
+ return {"parquet": "data"}
377
+
378
+ deserialiser = ParquetDeserialiser()
379
+ assert isinstance(deserialiser, DeserialiserLike)
380
+ result = deserialiser.deserialise(b"parquet_bytes", DataFormat.PARQUET)
381
+ assert result == {"parquet": "data"}
382
+
383
+
384
+ def test_csv_deserialiser_implementation():
385
+ """测试 CSV 反序列化器实现"""
386
+
387
+ class CSVDeserialiser:
388
+ @staticmethod
389
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
390
+ if format != DataFormat.CSV:
391
+ raise ValueError(f"Unsupported format: {format}")
392
+ # Simulate CSV deserialization
393
+ return [["col1", "col2"], ["val1", "val2"]]
394
+
395
+ deserialiser = CSVDeserialiser()
396
+ assert isinstance(deserialiser, DeserialiserLike)
397
+ result = deserialiser.deserialise(b"csv_bytes", DataFormat.CSV)
398
+ assert result == [["col1", "col2"], ["val1", "val2"]]
399
+
400
+
401
+ def test_json_deserialiser_implementation():
402
+ """测试 JSON 反序列化器实现"""
403
+ import json
404
+
405
+ class JSONDeserialiser:
406
+ @staticmethod
407
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
408
+ if format != DataFormat.JSON:
409
+ raise ValueError(f"Unsupported format: {format}")
410
+ if isinstance(data, bytes):
411
+ data = data.decode("utf-8")
412
+ return json.loads(data)
413
+
414
+ deserialiser = JSONDeserialiser()
415
+ assert isinstance(deserialiser, DeserialiserLike)
416
+ result = deserialiser.deserialise(b'{"test": 123}', DataFormat.JSON)
417
+ assert result == {"test": 123}
418
+
419
+
420
+ def test_multi_format_deserialiser():
421
+ """测试多格式反序列化器"""
422
+ import json
423
+
424
+ class MultiFormatDeserialiser:
425
+ @staticmethod
426
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
427
+ if format == DataFormat.JSON:
428
+ if isinstance(data, bytes):
429
+ data = data.decode("utf-8")
430
+ return json.loads(data)
431
+ elif format == DataFormat.CSV:
432
+ return {"type": "csv"}
433
+ elif format == DataFormat.PARQUET:
434
+ return {"type": "parquet"}
435
+ else:
436
+ raise ValueError(f"Unsupported format: {format}")
437
+
438
+ deserialiser = MultiFormatDeserialiser()
439
+ assert isinstance(deserialiser, DeserialiserLike)
440
+
441
+ # Test each format
442
+ json_result = deserialiser.deserialise(b'{"key": "value"}', DataFormat.JSON)
443
+ assert json_result == {"key": "value"}
444
+
445
+ csv_result = deserialiser.deserialise(b"csv_data", DataFormat.CSV)
446
+ assert csv_result == {"type": "csv"}
447
+
448
+ parquet_result = deserialiser.deserialise(b"parquet_data", DataFormat.PARQUET)
449
+ assert parquet_result == {"type": "parquet"}
450
+
451
+
452
+ def test_deserialiser_with_encoding_option():
453
+ """测试支持编码选项的反序列化器"""
454
+
455
+ class EncodingDeserialiser:
456
+ @staticmethod
457
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
458
+ encoding = kwargs.get("encoding", "utf-8")
459
+ if isinstance(data, bytes):
460
+ return data.decode(encoding)
461
+ return data
462
+
463
+ deserialiser = EncodingDeserialiser()
464
+ result = deserialiser.deserialise(b"test", DataFormat.CSV, encoding="utf-8")
465
+ assert result == "test"
466
+
467
+
468
+ def test_deserialiser_with_error_handling():
469
+ """测试包含错误处理的反序列化器"""
470
+
471
+ class SafeDeserialiser:
472
+ @staticmethod
473
+ def deserialise(data: Any, format: Any, **kwargs: Any) -> Any:
474
+ try:
475
+ if format == DataFormat.JSON:
476
+ import json
477
+
478
+ return json.loads(data)
479
+ return None
480
+ except Exception:
481
+ return {"error": "deserialization failed"}
482
+
483
+ deserialiser = SafeDeserialiser()
484
+ result = deserialiser.deserialise(b"invalid json", DataFormat.JSON)
485
+ assert result == {"error": "deserialization failed"}
486
+
487
+
488
+ # =============================================================================
489
+ # Protocol Attribute Tests
490
+ # =============================================================================
491
+
492
+
493
+ def test_protocol_module():
494
+ """测试协议所属模块"""
495
+ assert DeserialiserLike.__module__ == "xfintech.serde.common.deserialiserlike"
496
+
497
+
498
+ def test_protocol_name():
499
+ """测试协议名称"""
500
+ assert DeserialiserLike.__name__ == "DeserialiserLike"