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,547 @@
1
+ import pytest
2
+
3
+ from xfintech.fabric.column.info import ColumnInfo
4
+ from xfintech.fabric.column.kind import ColumnKind
5
+ from xfintech.fabric.table.info import TableInfo
6
+
7
+
8
+ def test_tableinfo_basic_init():
9
+ table = TableInfo(
10
+ name="daily_market",
11
+ desc=" 日线行情表 ",
12
+ meta={"source": "tushare"},
13
+ columns=[
14
+ ColumnInfo(name="price", kind="Float", desc="收盘价"),
15
+ ColumnInfo(name="volume", kind="Integer", desc="成交量"),
16
+ ],
17
+ )
18
+ assert table.name == "daily_market"
19
+ assert table.desc == "日线行情表"
20
+ assert table.meta == {"source": "tushare"}
21
+ assert len(table.columns) == 2
22
+ assert "price" in table.columns
23
+ assert "volume" in table.columns
24
+
25
+
26
+ def test_tableinfo_name_must_be_valid():
27
+ with pytest.raises(ValueError):
28
+ TableInfo(name="1invalid")
29
+
30
+
31
+ def test_tableinfo_name_is_lowercase():
32
+ table = TableInfo(name="MyTable")
33
+ assert table.name == "mytable"
34
+
35
+
36
+ def test_tableinfo_name_empty_when_none():
37
+ table = TableInfo(name=None)
38
+ assert table.name == ""
39
+
40
+
41
+ def test_tableinfo_name_accepts_underscore_hyphen():
42
+ table1 = TableInfo(name="my_table")
43
+ assert table1.name == "my_table"
44
+
45
+ table2 = TableInfo(name="my-table")
46
+ assert table2.name == "my-table"
47
+
48
+ table3 = TableInfo(name="_private_table")
49
+ assert table3.name == "_private_table"
50
+
51
+
52
+ def test_tableinfo_desc_strip():
53
+ table = TableInfo(
54
+ name="test",
55
+ desc=" Something Here ",
56
+ )
57
+ assert table.desc == "Something Here"
58
+
59
+
60
+ def test_tableinfo_desc_empty_when_none():
61
+ table = TableInfo(name="test", desc=None)
62
+ assert table.desc == ""
63
+
64
+
65
+ def test_tableinfo_meta_bytes_to_str():
66
+ table = TableInfo(
67
+ name="test",
68
+ meta={
69
+ b"bin": b"yes",
70
+ "code": b"ok",
71
+ },
72
+ )
73
+ assert table.meta == {"bin": "yes", "code": "ok"}
74
+
75
+
76
+ def test_tableinfo_meta_str_normal():
77
+ table = TableInfo(name="test", meta={"x": 1, "y": "value"})
78
+ assert table.meta == {"x": 1, "y": "value"}
79
+
80
+
81
+ def test_tableinfo_meta_none():
82
+ table = TableInfo(name="test", meta=None)
83
+ assert table.meta is None
84
+
85
+
86
+ def test_tableinfo_columns_from_columninfo_list():
87
+ table = TableInfo(
88
+ name="test",
89
+ columns=[
90
+ ColumnInfo(name="price", kind="Float"),
91
+ ColumnInfo(name="volume", kind="Integer"),
92
+ ],
93
+ )
94
+ assert len(table.columns) == 2
95
+ assert table.columns["price"].kind == ColumnKind.FLOAT
96
+ assert table.columns["volume"].kind == ColumnKind.INTEGER
97
+
98
+
99
+ def test_tableinfo_columns_from_dict_list():
100
+ table = TableInfo(
101
+ name="test",
102
+ columns=[
103
+ {"name": "price", "kind": "Float"},
104
+ {"name": "volume", "kind": "Integer"},
105
+ ],
106
+ )
107
+ assert len(table.columns) == 2
108
+ assert table.columns["price"].kind == ColumnKind.FLOAT
109
+ assert table.columns["volume"].kind == ColumnKind.INTEGER
110
+
111
+
112
+ def test_tableinfo_columns_mixed_types():
113
+ table = TableInfo(
114
+ name="test",
115
+ columns=[
116
+ ColumnInfo(name="price", kind="Float"),
117
+ {"name": "volume", "kind": "Integer"},
118
+ ],
119
+ )
120
+ assert len(table.columns) == 2
121
+ assert isinstance(table.columns["price"], ColumnInfo)
122
+ assert isinstance(table.columns["volume"], ColumnInfo)
123
+
124
+
125
+ def test_tableinfo_columns_invalid_type():
126
+ with pytest.raises(TypeError):
127
+ TableInfo(
128
+ name="test",
129
+ columns=["invalid"],
130
+ )
131
+
132
+
133
+ def test_tableinfo_columns_none():
134
+ table = TableInfo(name="test", columns=None)
135
+ assert table.columns == {}
136
+
137
+
138
+ def test_tableinfo_get_column():
139
+ table = TableInfo(
140
+ name="test",
141
+ columns=[
142
+ ColumnInfo(name="price", kind="Float"),
143
+ ColumnInfo(name="volume", kind="Integer"),
144
+ ],
145
+ )
146
+ col = table.get_column("price")
147
+ assert col is not None
148
+ assert col.name == "price"
149
+ assert col.kind == ColumnKind.FLOAT
150
+
151
+
152
+ def test_tableinfo_get_column_case_insensitive():
153
+ table = TableInfo(
154
+ name="test",
155
+ columns=[
156
+ ColumnInfo(name="price", kind="Float"),
157
+ ],
158
+ )
159
+ col = table.get_column("PRICE")
160
+ assert col is not None
161
+ assert col.name == "price"
162
+
163
+
164
+ def test_tableinfo_get_column_not_exists():
165
+ table = TableInfo(name="test", columns=[])
166
+ col = table.get_column("nonexistent")
167
+ assert col is None
168
+
169
+
170
+ def test_tableinfo_add_column():
171
+ table = TableInfo(name="test")
172
+ table.add_column(ColumnInfo(name="price", kind="Float"))
173
+
174
+ assert len(table.columns) == 1
175
+ assert "price" in table.columns
176
+ assert table.columns["price"].kind == ColumnKind.FLOAT
177
+
178
+
179
+ def test_tableinfo_add_column_from_dict():
180
+ table = TableInfo(name="test")
181
+ table.add_column({"name": "price", "kind": "Float"})
182
+
183
+ assert len(table.columns) == 1
184
+ assert "price" in table.columns
185
+ assert table.columns["price"].kind == ColumnKind.FLOAT
186
+
187
+
188
+ def test_tableinfo_remove_column():
189
+ table = TableInfo(
190
+ name="test",
191
+ columns=[
192
+ ColumnInfo(name="price", kind="Float"),
193
+ ColumnInfo(name="volume", kind="Integer"),
194
+ ],
195
+ )
196
+ table.remove_column("price")
197
+
198
+ assert len(table.columns) == 1
199
+ assert "price" not in table.columns
200
+ assert "volume" in table.columns
201
+
202
+
203
+ def test_tableinfo_remove_column_case_insensitive():
204
+ table = TableInfo(
205
+ name="test",
206
+ columns=[
207
+ ColumnInfo(name="price", kind="Float"),
208
+ ],
209
+ )
210
+ table.remove_column("PRICE")
211
+
212
+ assert len(table.columns) == 0
213
+
214
+
215
+ def test_tableinfo_remove_column_not_exists():
216
+ table = TableInfo(
217
+ name="test",
218
+ columns=[
219
+ ColumnInfo(name="price", kind="Float"),
220
+ ],
221
+ )
222
+ table.remove_column("nonexistent")
223
+
224
+ assert len(table.columns) == 1
225
+
226
+
227
+ def test_tableinfo_update_column_kind_desc_meta():
228
+ table = TableInfo(
229
+ name="test",
230
+ columns=[
231
+ ColumnInfo(
232
+ name="price",
233
+ kind="Float",
234
+ desc="old",
235
+ meta={"unit": "CNY"},
236
+ ),
237
+ ],
238
+ )
239
+ table.update_column(
240
+ "price",
241
+ kind="Integer",
242
+ desc="new-desc",
243
+ meta={"precision": 2},
244
+ )
245
+
246
+ col = table.get_column("price")
247
+ assert col.kind == ColumnKind.INTEGER
248
+ assert col.desc == "new-desc"
249
+ assert col.meta == {"unit": "CNY", "precision": 2}
250
+
251
+
252
+ def test_tableinfo_update_column_rename():
253
+ table = TableInfo(
254
+ name="test",
255
+ columns=[
256
+ ColumnInfo(name="price", kind="Float"),
257
+ ],
258
+ )
259
+ table.update_column("price", new="new_price")
260
+
261
+ assert "price" not in table.columns
262
+ assert "new_price" in table.columns
263
+ assert table.columns["new_price"].kind == ColumnKind.FLOAT
264
+
265
+
266
+ def test_tableinfo_update_column_not_exists():
267
+ table = TableInfo(
268
+ name="test",
269
+ columns=[
270
+ ColumnInfo(name="price", kind="Float"),
271
+ ],
272
+ )
273
+ table.update_column("nonexistent", desc="new")
274
+
275
+ assert len(table.columns) == 1
276
+ assert table.columns["price"].desc == ""
277
+
278
+
279
+ def test_tableinfo_rename_column():
280
+ table = TableInfo(
281
+ name="test",
282
+ columns=[
283
+ ColumnInfo(name="old_name", kind="Float"),
284
+ ],
285
+ )
286
+ table.rename_column("old_name", "new_name")
287
+
288
+ assert "old_name" not in table.columns
289
+ assert "new_name" in table.columns
290
+ assert table.columns["new_name"].name == "new_name"
291
+
292
+
293
+ def test_tableinfo_rename_column_case_insensitive():
294
+ table = TableInfo(
295
+ name="test",
296
+ columns=[
297
+ ColumnInfo(name="old_name", kind="Float"),
298
+ ],
299
+ )
300
+ table.rename_column("OLD_NAME", "new_name")
301
+
302
+ assert "old_name" not in table.columns
303
+ assert "new_name" in table.columns
304
+
305
+
306
+ def test_tableinfo_rename_column_not_exists():
307
+ table = TableInfo(
308
+ name="test",
309
+ columns=[
310
+ ColumnInfo(name="price", kind="Float"),
311
+ ],
312
+ )
313
+ table.rename_column("nonexistent", "new_name")
314
+
315
+ assert len(table.columns) == 1
316
+ assert "new_name" not in table.columns
317
+
318
+
319
+ def test_tableinfo_list_columns():
320
+ table = TableInfo(
321
+ name="test",
322
+ columns=[
323
+ ColumnInfo(name="price", kind="Float"),
324
+ ColumnInfo(name="volume", kind="Integer"),
325
+ ],
326
+ )
327
+ cols = table.list_columns()
328
+
329
+ assert len(cols) == 2
330
+ assert all(isinstance(c, ColumnInfo) for c in cols)
331
+ names = [c.name for c in cols]
332
+ assert "price" in names
333
+ assert "volume" in names
334
+
335
+
336
+ def test_tableinfo_list_columns_empty():
337
+ table = TableInfo(name="test")
338
+ cols = table.list_columns()
339
+
340
+ assert cols == []
341
+
342
+
343
+ def test_tableinfo_full_describe():
344
+ table = TableInfo(
345
+ name="test",
346
+ desc="Test table",
347
+ meta={"source": "tushare"},
348
+ columns=[
349
+ ColumnInfo(name="price", kind="Float", desc="Price"),
350
+ ],
351
+ )
352
+ d = table.describe()
353
+
354
+ assert d["name"] == "test"
355
+ assert d["desc"] == "Test table"
356
+ assert d["meta"] == {"source": "tushare"}
357
+ assert len(d["columns"]) == 1
358
+ assert d["columns"][0]["name"] == "price"
359
+
360
+
361
+ def test_tableinfo_partial_describe():
362
+ table = TableInfo(name="test")
363
+ d = table.describe()
364
+ assert "name" in d
365
+ assert "desc" not in d
366
+ assert "meta" not in d
367
+ assert "columns" not in d
368
+
369
+
370
+ def test_tableinfo_full_to_dict():
371
+ table = TableInfo(
372
+ name="test",
373
+ desc="Test table",
374
+ meta={"source": "tushare"},
375
+ columns=[
376
+ ColumnInfo(name="price", kind="Float", desc="Price"),
377
+ ],
378
+ )
379
+ d = table.to_dict()
380
+
381
+ assert "identifier" in d
382
+ assert d["name"] == "test"
383
+ assert d["desc"] == "Test table"
384
+ assert d["meta"] == {"source": "tushare"}
385
+ assert len(d["columns"]) == 1
386
+
387
+
388
+ def test_tableinfo_from_dict():
389
+ data = {
390
+ "name": "test",
391
+ "desc": "Test table",
392
+ "meta": {"source": "tushare"},
393
+ "columns": [
394
+ {"name": "price", "kind": "Float"},
395
+ {"name": "volume", "kind": "Integer"},
396
+ ],
397
+ }
398
+ table = TableInfo.from_dict(data)
399
+
400
+ assert table.name == "test"
401
+ assert table.desc == "Test table"
402
+ assert table.meta == {"source": "tushare"}
403
+ assert len(table.columns) == 2
404
+
405
+
406
+ def test_tableinfo_from_dict_minimal():
407
+ data = {}
408
+ table = TableInfo.from_dict(data)
409
+
410
+ assert table.name == ""
411
+ assert table.desc == ""
412
+ assert table.meta is None
413
+ assert table.columns == {}
414
+
415
+
416
+ def test_tableinfo_str():
417
+ table = TableInfo(
418
+ name="test",
419
+ columns=[
420
+ ColumnInfo(name="price", kind="Float"),
421
+ ],
422
+ )
423
+ s = str(table)
424
+ assert "price" in s
425
+
426
+
427
+ def test_tableinfo_repr():
428
+ table = TableInfo(name="test")
429
+ r = repr(table)
430
+ assert "TableInfo" in r
431
+ assert "test" in r
432
+
433
+
434
+ def test_tableinfo_identifier_is_deterministic():
435
+ table1 = TableInfo(
436
+ name="test",
437
+ desc="Test table",
438
+ meta={"source": "tushare"},
439
+ columns=[
440
+ ColumnInfo(name="price", kind="Float"),
441
+ ColumnInfo(name="volume", kind="Integer"),
442
+ ],
443
+ )
444
+ table2 = TableInfo(
445
+ name="test",
446
+ desc="Test table",
447
+ meta={"source": "tushare"},
448
+ columns=[
449
+ ColumnInfo(name="price", kind="Float"),
450
+ ColumnInfo(name="volume", kind="Integer"),
451
+ ],
452
+ )
453
+ assert table1.identifier == table2.identifier
454
+
455
+
456
+ def test_tableinfo_identifier_not_change_with_meta():
457
+ table1 = TableInfo(
458
+ name="test",
459
+ desc="Test table",
460
+ meta={"source": "tushare"},
461
+ columns=[
462
+ ColumnInfo(name="price", kind="Float"),
463
+ ],
464
+ )
465
+ table2 = TableInfo(
466
+ name="test",
467
+ desc="Test table",
468
+ meta={"source": "yahoo"},
469
+ columns=[
470
+ ColumnInfo(name="price", kind="Float"),
471
+ ],
472
+ )
473
+ assert table1.identifier == table2.identifier
474
+
475
+
476
+ def test_tableinfo_identifier_changes_with_name():
477
+ table1 = TableInfo(
478
+ name="test1",
479
+ desc="Test table",
480
+ columns=[
481
+ ColumnInfo(name="price", kind="Float"),
482
+ ],
483
+ )
484
+ table2 = TableInfo(
485
+ name="test2",
486
+ desc="Test table",
487
+ columns=[
488
+ ColumnInfo(name="price", kind="Float"),
489
+ ],
490
+ )
491
+ assert table1.identifier != table2.identifier
492
+
493
+
494
+ def test_tableinfo_identifier_changes_with_desc():
495
+ table1 = TableInfo(
496
+ name="test",
497
+ desc="Desc1",
498
+ columns=[
499
+ ColumnInfo(name="price", kind="Float"),
500
+ ],
501
+ )
502
+ table2 = TableInfo(
503
+ name="test",
504
+ desc="Desc2",
505
+ columns=[
506
+ ColumnInfo(name="price", kind="Float"),
507
+ ],
508
+ )
509
+ assert table1.identifier != table2.identifier
510
+
511
+
512
+ def test_tableinfo_identifier_changes_with_columns():
513
+ table1 = TableInfo(
514
+ name="test",
515
+ desc="Test table",
516
+ columns=[
517
+ ColumnInfo(name="price", kind="Float"),
518
+ ],
519
+ )
520
+ table2 = TableInfo(
521
+ name="test",
522
+ desc="Test table",
523
+ columns=[
524
+ ColumnInfo(name="volume", kind="Integer"),
525
+ ],
526
+ )
527
+ assert table1.identifier != table2.identifier
528
+
529
+
530
+ def test_tableinfo_identifier_column_order_independent():
531
+ table1 = TableInfo(
532
+ name="test",
533
+ desc="Test table",
534
+ columns=[
535
+ ColumnInfo(name="price", kind="Float"),
536
+ ColumnInfo(name="volume", kind="Integer"),
537
+ ],
538
+ )
539
+ table2 = TableInfo(
540
+ name="test",
541
+ desc="Test table",
542
+ columns=[
543
+ ColumnInfo(name="volume", kind="Integer"),
544
+ ColumnInfo(name="price", kind="Float"),
545
+ ],
546
+ )
547
+ assert table1.identifier == table2.identifier
@@ -0,0 +1,35 @@
1
+ from .common.dataformat import DataFormat
2
+ from .common.deserialiserlike import DeserialiserLike
3
+ from .common.error import (
4
+ DeserialiserFailedError,
5
+ DeserialiserImportError,
6
+ DeserialiserInputTypeError,
7
+ DeserialiserNotSupportedError,
8
+ SerialiserFailedError,
9
+ SerialiserImportError,
10
+ SerialiserInputTypeError,
11
+ SerialiserNotSupportedError,
12
+ )
13
+ from .common.serialiserlike import SerialiserLike
14
+ from .deserialiser.pandas import PandasDeserialiser
15
+ from .deserialiser.python import PythonDeserialiser
16
+ from .serialiser.pandas import PandasSerialiser
17
+ from .serialiser.python import PythonSerialiser
18
+
19
+ __all__ = [
20
+ "DataFormat",
21
+ "DeserialiserLike",
22
+ "SerialiserLike",
23
+ "PandasDeserialiser",
24
+ "PythonDeserialiser",
25
+ "PandasSerialiser",
26
+ "PythonSerialiser",
27
+ "DeserialiserFailedError",
28
+ "DeserialiserImportError",
29
+ "DeserialiserInputTypeError",
30
+ "DeserialiserNotSupportedError",
31
+ "SerialiserFailedError",
32
+ "SerialiserImportError",
33
+ "SerialiserInputTypeError",
34
+ "SerialiserNotSupportedError",
35
+ ]
@@ -0,0 +1,9 @@
1
+ from .dataformat import DataFormat
2
+ from .deserialiserlike import DeserialiserLike
3
+ from .serialiserlike import SerialiserLike
4
+
5
+ __all__ = [
6
+ "DataFormat",
7
+ "SerialiserLike",
8
+ "DeserialiserLike",
9
+ ]
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class DataFormat(str, Enum):
7
+ """
8
+ 描述:
9
+ - 序列化和反序列化格式枚举类。
10
+ - 定义支持的数据格式:Parquet、CSV 和 JSON。
11
+ - 继承自 str 和 Enum,可以直接与字符串比较。
12
+
13
+ 属性:
14
+ - PARQUET: Parquet 格式 ("parquet")
15
+ - CSV: CSV 格式 ("csv")
16
+ - JSON: JSON 格式 ("json")
17
+
18
+ 方法:
19
+ - from_str(string): 从字符串创建 DataFormat 实例(不区分大小写)。
20
+ - from_any(value): 从 DataFormat 实例或字符串创建 DataFormat 实例。
21
+ - list_all(): 列出所有支持的 DataFormat 实例。
22
+ - __str__(): 返回格式的字符串值。
23
+ - __repr__(): 返回格式的表示形式。
24
+
25
+ 例子:
26
+ ```python
27
+ from xfintech.serde.common.dataformat import DataFormat
28
+
29
+ # 使用枚举值
30
+ fmt = DataFormat.PARQUET
31
+ print(fmt) # parquet
32
+ print(repr(fmt)) # DataFormat.PARQUET
33
+
34
+ # 从字符串创建(不区分大小写)
35
+ fmt = DataFormat.from_str("csv")
36
+ print(fmt) # csv
37
+
38
+ fmt = DataFormat.from_str("JSON")
39
+ print(fmt) # json
40
+
41
+ # 字符串比较
42
+ if DataFormat.PARQUET == "parquet":
43
+ print("Matched!") # 输出: Matched!
44
+
45
+ # 无效格式会抛出 ValueError
46
+ try:
47
+ DataFormat.from_str("xml")
48
+ except ValueError as e:
49
+ print(f"Error: {e}") # Error: Unknown DataFormat: xml
50
+ ```
51
+ """
52
+
53
+ PARQUET = "parquet"
54
+ CSV = "csv"
55
+ JSON = "json"
56
+
57
+ @classmethod
58
+ def from_str(cls, value: str) -> DataFormat:
59
+ for fmt in DataFormat:
60
+ if fmt.value.lower() == value.lower():
61
+ return fmt
62
+ raise ValueError(f"Unknown DataFormat: {value}")
63
+
64
+ @classmethod
65
+ def from_any(cls, value: DataFormat | str) -> DataFormat:
66
+ if isinstance(value, DataFormat):
67
+ return value
68
+ return cls.from_str(value)
69
+
70
+ @classmethod
71
+ def list_all(cls) -> list[DataFormat]:
72
+ return [fmt for fmt in cls]
73
+
74
+ def __str__(self) -> str:
75
+ return self.value
76
+
77
+ def __repr__(self) -> str:
78
+ return f"{self.__class__.__name__}.{self.name}"
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Protocol, runtime_checkable
4
+
5
+
6
+ @runtime_checkable
7
+ class DeserialiserLike(Protocol):
8
+ """
9
+ 描述:
10
+ - 通用反序列化接口协议。
11
+ - 定义反序列化方法的签名,适用于各种数据格式。
12
+ - 将字节流转换为数据对象(如 DataFrame)。
13
+
14
+ 方法:
15
+ - deserialise(data, format, **kwargs): 通用反序列化方法,返回数据对象。
16
+
17
+ 例子:
18
+ ```python
19
+ from xfintech.serde.common.deserialiserlike import DeserialiserLike
20
+ import pandas as pd
21
+
22
+ class MyDeserialiser:
23
+ @staticmethod
24
+ def deserialise(data, format, **kwargs):
25
+ # 实现反序列化逻辑
26
+ return pd.DataFrame()
27
+
28
+ # 检查是否符合协议
29
+ assert isinstance(MyDeserialiser(), DeserialiserLike)
30
+ ```
31
+ """
32
+
33
+ @staticmethod
34
+ def deserialise(
35
+ data: Any,
36
+ format: Any,
37
+ **kwargs: Any,
38
+ ) -> Any: ...