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,508 @@
1
+ import json
2
+
3
+ import pytest
4
+
5
+ from xfintech.serde.common.dataformat import DataFormat
6
+ from xfintech.serde.common.error import (
7
+ SerialiserFailedError,
8
+ SerialiserInputTypeError,
9
+ SerialiserNotSupportedError,
10
+ )
11
+ from xfintech.serde.serialiser.python import PythonSerialiser
12
+
13
+ # ==================== Class Structure Tests ====================
14
+
15
+
16
+ def test_pythonserialiser_has_serialise_method():
17
+ """Test PythonSerialiser has serialise method"""
18
+ assert hasattr(PythonSerialiser, "serialise")
19
+ assert callable(PythonSerialiser.serialise)
20
+
21
+
22
+ def test_pythonserialiser_has_to_json_method():
23
+ """Test PythonSerialiser has to_json method"""
24
+ assert hasattr(PythonSerialiser, "to_json")
25
+ assert callable(PythonSerialiser.to_json)
26
+
27
+
28
+ def test_pythonserialiser_methods_are_static():
29
+ """Test all methods are static methods"""
30
+ assert isinstance(PythonSerialiser.__dict__["serialise"], staticmethod)
31
+ assert isinstance(PythonSerialiser.__dict__["to_json"], staticmethod)
32
+
33
+
34
+ # ==================== serialise() Method Tests ====================
35
+
36
+
37
+ def test_serialise_simple_dict():
38
+ """Test serialise with simple dictionary"""
39
+ data = {"key": "value", "number": 42}
40
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
41
+ assert isinstance(result, bytes)
42
+ assert b"key" in result and b"value" in result
43
+
44
+
45
+ def test_serialise_with_json_format_enum():
46
+ """Test serialise with JSON DataFormat enum"""
47
+ data = {"a": 1, "b": 2}
48
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
49
+ assert isinstance(result, bytes)
50
+
51
+
52
+ def test_serialise_with_json_format_string_lowercase():
53
+ """Test serialise with 'json' string"""
54
+ data = {"a": 1}
55
+ result = PythonSerialiser.serialise(data, "json")
56
+ assert isinstance(result, bytes)
57
+
58
+
59
+ def test_serialise_with_json_format_string_uppercase():
60
+ """Test serialise with 'JSON' string"""
61
+ data = {"a": 1}
62
+ result = PythonSerialiser.serialise(data, "JSON")
63
+ assert isinstance(result, bytes)
64
+
65
+
66
+ def test_serialise_with_json_format_string_mixed_case():
67
+ """Test serialise with 'Json' string"""
68
+ data = {"a": 1}
69
+ result = PythonSerialiser.serialise(data, "Json")
70
+ assert isinstance(result, bytes)
71
+
72
+
73
+ def test_serialise_returns_bytes():
74
+ """Test serialise always returns bytes"""
75
+ data = {"test": "data"}
76
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
77
+ assert isinstance(result, bytes)
78
+
79
+
80
+ def test_serialise_returns_valid_json():
81
+ """Test serialise returns valid JSON bytes"""
82
+ data = {"key1": "value1", "key2": 123}
83
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
84
+
85
+ # Verify it can be parsed back
86
+ parsed = json.loads(result.decode("utf-8"))
87
+ assert parsed == data
88
+
89
+
90
+ def test_serialise_nested_dict():
91
+ """Test serialise with nested dictionary"""
92
+ data = {"outer": {"inner": {"deep": "value"}}}
93
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
94
+ assert isinstance(result, bytes)
95
+ parsed = json.loads(result.decode("utf-8"))
96
+ assert parsed["outer"]["inner"]["deep"] == "value"
97
+
98
+
99
+ def test_serialise_dict_with_list():
100
+ """Test serialise with dictionary containing list"""
101
+ data = {"items": [1, 2, 3, 4, 5]}
102
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
103
+ assert isinstance(result, bytes)
104
+ parsed = json.loads(result.decode("utf-8"))
105
+ assert parsed["items"] == [1, 2, 3, 4, 5]
106
+
107
+
108
+ def test_serialise_dict_with_various_types():
109
+ """Test serialise with various data types"""
110
+ data = {
111
+ "string": "text",
112
+ "integer": 42,
113
+ "float": 3.14,
114
+ "boolean": True,
115
+ "null": None,
116
+ "list": [1, 2, 3],
117
+ "nested": {"key": "value"},
118
+ }
119
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
120
+ assert isinstance(result, bytes)
121
+ parsed = json.loads(result.decode("utf-8"))
122
+ assert parsed == data
123
+
124
+
125
+ def test_serialise_empty_dict():
126
+ """Test serialise with empty dictionary"""
127
+ data = {}
128
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
129
+ assert isinstance(result, bytes)
130
+ parsed = json.loads(result.decode("utf-8"))
131
+ assert parsed == {}
132
+
133
+
134
+ def test_serialise_large_dict():
135
+ """Test serialise with large dictionary"""
136
+ data = {f"key_{i}": i for i in range(1000)}
137
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
138
+ assert isinstance(result, bytes)
139
+ assert len(result) > 0
140
+
141
+
142
+ def test_serialise_raises_on_non_dict_list():
143
+ """Test serialise raises error for list input"""
144
+ with pytest.raises(SerialiserInputTypeError) as exc_info:
145
+ PythonSerialiser.serialise([1, 2, 3], DataFormat.JSON)
146
+ assert "expects dict" in str(exc_info.value)
147
+
148
+
149
+ def test_serialise_raises_on_non_dict_string():
150
+ """Test serialise raises error for string input"""
151
+ with pytest.raises(SerialiserInputTypeError):
152
+ PythonSerialiser.serialise("not a dict", DataFormat.JSON)
153
+
154
+
155
+ def test_serialise_raises_on_non_dict_int():
156
+ """Test serialise raises error for integer input"""
157
+ with pytest.raises(SerialiserInputTypeError):
158
+ PythonSerialiser.serialise(123, DataFormat.JSON)
159
+
160
+
161
+ def test_serialise_raises_on_non_dict_bytes():
162
+ """Test serialise raises error for bytes input"""
163
+ with pytest.raises(SerialiserInputTypeError):
164
+ PythonSerialiser.serialise(b"bytes", DataFormat.JSON)
165
+
166
+
167
+ def test_serialise_raises_on_none():
168
+ """Test serialise raises error for None input"""
169
+ with pytest.raises(SerialiserInputTypeError):
170
+ PythonSerialiser.serialise(None, DataFormat.JSON)
171
+
172
+
173
+ def test_serialise_raises_on_unsupported_format_parquet():
174
+ """Test serialise raises error for PARQUET format"""
175
+ data = {"a": 1}
176
+ with pytest.raises(SerialiserNotSupportedError) as exc_info:
177
+ PythonSerialiser.serialise(data, DataFormat.PARQUET)
178
+ assert "Unsupported DataFormat" in str(exc_info.value)
179
+
180
+
181
+ def test_serialise_raises_on_unsupported_format_csv():
182
+ """Test serialise raises error for CSV format"""
183
+ data = {"a": 1}
184
+ with pytest.raises(SerialiserNotSupportedError):
185
+ PythonSerialiser.serialise(data, DataFormat.CSV)
186
+
187
+
188
+ def test_serialise_raises_on_invalid_format_string():
189
+ """Test serialise raises error for invalid format string"""
190
+ data = {"a": 1}
191
+ with pytest.raises(ValueError) as exc_info:
192
+ PythonSerialiser.serialise(data, "xml")
193
+ assert "Unknown DataFormat" in str(exc_info.value)
194
+
195
+
196
+ # ==================== to_json() Method Tests ====================
197
+
198
+
199
+ def test_to_json_basic():
200
+ """Test to_json with basic dictionary"""
201
+ data = {"key": "value"}
202
+ result = PythonSerialiser.to_json(data)
203
+ assert isinstance(result, bytes)
204
+
205
+
206
+ def test_to_json_returns_bytes():
207
+ """Test to_json returns bytes type"""
208
+ data = {"test": "data"}
209
+ result = PythonSerialiser.to_json(data)
210
+ assert isinstance(result, bytes)
211
+
212
+
213
+ def test_to_json_returns_valid_json():
214
+ """Test to_json returns valid JSON"""
215
+ data = {"name": "test", "value": 123}
216
+ result = PythonSerialiser.to_json(data)
217
+
218
+ # Verify it's valid JSON
219
+ parsed = json.loads(result.decode("utf-8"))
220
+ assert parsed == data
221
+
222
+
223
+ def test_to_json_with_utf8_encoding():
224
+ """Test to_json with UTF-8 encoding (default)"""
225
+ data = {"text": "Hello 世界"}
226
+ result = PythonSerialiser.to_json(data)
227
+ assert isinstance(result, bytes)
228
+ parsed = json.loads(result.decode("utf-8"))
229
+ assert parsed["text"] == "Hello 世界"
230
+
231
+
232
+ def test_to_json_with_custom_encoding():
233
+ """Test to_json with custom encoding"""
234
+ data = {"text": "test"}
235
+ result = PythonSerialiser.to_json(data, encoding="utf-8")
236
+ assert isinstance(result, bytes)
237
+
238
+
239
+ def test_to_json_default_formatting():
240
+ """Test to_json uses default formatting (ensure_ascii=False, indent=4, sort_keys=True)"""
241
+ data = {"z": 1, "a": 2, "m": 3}
242
+ result = PythonSerialiser.to_json(data)
243
+ text = result.decode("utf-8")
244
+
245
+ # Check that keys are sorted (based on default sort_keys=True)
246
+ assert text.index('"a"') < text.index('"m"') < text.index('"z"')
247
+
248
+ # Check that it's indented (indent=4)
249
+ assert "\n" in text
250
+
251
+
252
+ def test_to_json_with_unicode_characters():
253
+ """Test to_json preserves Unicode (ensure_ascii=False by default)"""
254
+ data = {"chinese": "中文", "russian": "Русский", "arabic": "عربي"}
255
+ result = PythonSerialiser.to_json(data)
256
+ text = result.decode("utf-8")
257
+
258
+ # Verify Unicode is preserved (not escaped)
259
+ assert "中文" in text
260
+ assert "Русский" in text
261
+ assert "عربي" in text
262
+
263
+
264
+ def test_to_json_nested_structure():
265
+ """Test to_json with nested structure"""
266
+ data = {"level1": {"level2": {"level3": "deep value"}}}
267
+ result = PythonSerialiser.to_json(data)
268
+ assert isinstance(result, bytes)
269
+ parsed = json.loads(result.decode("utf-8"))
270
+ assert parsed["level1"]["level2"]["level3"] == "deep value"
271
+
272
+
273
+ def test_to_json_with_list_values():
274
+ """Test to_json with list values"""
275
+ data = {"numbers": [1, 2, 3, 4, 5], "strings": ["a", "b", "c"]}
276
+ result = PythonSerialiser.to_json(data)
277
+ parsed = json.loads(result.decode("utf-8"))
278
+ assert parsed["numbers"] == [1, 2, 3, 4, 5]
279
+ assert parsed["strings"] == ["a", "b", "c"]
280
+
281
+
282
+ def test_to_json_with_null_value():
283
+ """Test to_json with None/null value"""
284
+ data = {"key": None}
285
+ result = PythonSerialiser.to_json(data)
286
+ parsed = json.loads(result.decode("utf-8"))
287
+ assert parsed["key"] is None
288
+
289
+
290
+ def test_to_json_with_boolean_values():
291
+ """Test to_json with boolean values"""
292
+ data = {"true_val": True, "false_val": False}
293
+ result = PythonSerialiser.to_json(data)
294
+ parsed = json.loads(result.decode("utf-8"))
295
+ assert parsed["true_val"] is True
296
+ assert parsed["false_val"] is False
297
+
298
+
299
+ def test_to_json_with_numeric_values():
300
+ """Test to_json with various numeric types"""
301
+ data = {"int": 42, "float": 3.14159, "negative": -100, "zero": 0}
302
+ result = PythonSerialiser.to_json(data)
303
+ parsed = json.loads(result.decode("utf-8"))
304
+ assert parsed["int"] == 42
305
+ assert abs(parsed["float"] - 3.14159) < 0.00001
306
+ assert parsed["negative"] == -100
307
+ assert parsed["zero"] == 0
308
+
309
+
310
+ def test_to_json_empty_dict():
311
+ """Test to_json with empty dictionary"""
312
+ data = {}
313
+ result = PythonSerialiser.to_json(data)
314
+ parsed = json.loads(result.decode("utf-8"))
315
+ assert parsed == {}
316
+
317
+
318
+ def test_to_json_single_key():
319
+ """Test to_json with single key dictionary"""
320
+ data = {"only": "one"}
321
+ result = PythonSerialiser.to_json(data)
322
+ parsed = json.loads(result.decode("utf-8"))
323
+ assert parsed == data
324
+
325
+
326
+ def test_to_json_special_characters_in_values():
327
+ """Test to_json with special characters"""
328
+ data = {
329
+ "quotes": 'He said "hello"',
330
+ "newlines": "line1\nline2",
331
+ "tabs": "col1\tcol2",
332
+ "backslash": "path\\to\\file",
333
+ }
334
+ result = PythonSerialiser.to_json(data)
335
+ parsed = json.loads(result.decode("utf-8"))
336
+ assert parsed == data
337
+
338
+
339
+ def test_to_json_special_characters_in_keys():
340
+ """Test to_json with special characters in keys"""
341
+ data = {"key with spaces": "value1", "key-with-dashes": "value2", "key.with.dots": "value3"}
342
+ result = PythonSerialiser.to_json(data)
343
+ parsed = json.loads(result.decode("utf-8"))
344
+ assert parsed == data
345
+
346
+
347
+ def test_to_json_large_dict():
348
+ """Test to_json with large dictionary"""
349
+ data = {f"key_{i}": f"value_{i}" for i in range(1000)}
350
+ result = PythonSerialiser.to_json(data)
351
+ assert isinstance(result, bytes)
352
+ parsed = json.loads(result.decode("utf-8"))
353
+ assert len(parsed) == 1000
354
+
355
+
356
+ def test_to_json_deeply_nested():
357
+ """Test to_json with deeply nested structure"""
358
+ data = {"a": {"b": {"c": {"d": {"e": {"f": "deep"}}}}}}
359
+ result = PythonSerialiser.to_json(data)
360
+ parsed = json.loads(result.decode("utf-8"))
361
+ assert parsed["a"]["b"]["c"]["d"]["e"]["f"] == "deep"
362
+
363
+
364
+ def test_to_json_mixed_nesting():
365
+ """Test to_json with mixed nested structures"""
366
+ data = {
367
+ "list_of_dicts": [{"id": 1, "name": "first"}, {"id": 2, "name": "second"}],
368
+ "dict_of_lists": {"group1": [1, 2, 3], "group2": [4, 5, 6]},
369
+ }
370
+ result = PythonSerialiser.to_json(data)
371
+ parsed = json.loads(result.decode("utf-8"))
372
+ assert parsed == data
373
+
374
+
375
+ # ==================== Error Handling Tests ====================
376
+
377
+
378
+ def test_to_json_raises_on_non_serializable():
379
+ """Test to_json raises error for non-JSON-serializable objects"""
380
+ import datetime
381
+
382
+ data = {"date": datetime.datetime.now()}
383
+
384
+ with pytest.raises(SerialiserFailedError) as exc_info:
385
+ PythonSerialiser.to_json(data)
386
+ assert "Failed to serialize data" in str(exc_info.value)
387
+
388
+
389
+ def test_to_json_raises_on_circular_reference():
390
+ """Test to_json raises error for circular reference"""
391
+ data = {"key": "value"}
392
+ data["self"] = data # Create circular reference
393
+
394
+ with pytest.raises(SerialiserFailedError):
395
+ PythonSerialiser.to_json(data)
396
+
397
+
398
+ # ==================== Integration and Edge Case Tests ====================
399
+
400
+
401
+ def test_serialise_and_to_json_produce_same_result():
402
+ """Test serialise and to_json produce same result"""
403
+ data = {"a": 1, "b": 2}
404
+ result1 = PythonSerialiser.serialise(data, DataFormat.JSON)
405
+ result2 = PythonSerialiser.to_json(data)
406
+
407
+ # Parse both to compare (formatting might differ slightly)
408
+ parsed1 = json.loads(result1.decode("utf-8"))
409
+ parsed2 = json.loads(result2.decode("utf-8"))
410
+ assert parsed1 == parsed2
411
+
412
+
413
+ def test_serialise_same_dict_multiple_times():
414
+ """Test serialising same dict multiple times produces consistent results"""
415
+ data = {"key": "value", "number": 42}
416
+ result1 = PythonSerialiser.serialise(data, DataFormat.JSON)
417
+ result2 = PythonSerialiser.serialise(data, DataFormat.JSON)
418
+
419
+ # Parse to compare (accounting for potential ordering differences)
420
+ parsed1 = json.loads(result1.decode("utf-8"))
421
+ parsed2 = json.loads(result2.decode("utf-8"))
422
+ assert parsed1 == parsed2
423
+
424
+
425
+ def test_roundtrip_serialise_deserialise():
426
+ """Test data can be serialised and deserialised back"""
427
+ from xfintech.serde.deserialiser.python import PythonDeserialiser
428
+
429
+ original = {"name": "test", "value": 123, "nested": {"key": "value"}, "list": [1, 2, 3]}
430
+
431
+ # Serialise
432
+ bytes_data = PythonSerialiser.serialise(original, DataFormat.JSON)
433
+
434
+ # Deserialise
435
+ result = PythonDeserialiser.deserialise(bytes_data, DataFormat.JSON)
436
+
437
+ assert result == original
438
+
439
+
440
+ def test_dict_with_empty_strings():
441
+ """Test dict with empty string values"""
442
+ data = {"empty": "", "not_empty": "value"}
443
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
444
+ parsed = json.loads(result.decode("utf-8"))
445
+ assert parsed["empty"] == ""
446
+ assert parsed["not_empty"] == "value"
447
+
448
+
449
+ def test_dict_with_empty_lists():
450
+ """Test dict with empty list values"""
451
+ data = {"empty_list": [], "list": [1, 2]}
452
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
453
+ parsed = json.loads(result.decode("utf-8"))
454
+ assert parsed["empty_list"] == []
455
+ assert parsed["list"] == [1, 2]
456
+
457
+
458
+ def test_dict_with_empty_nested_dicts():
459
+ """Test dict with empty nested dictionaries"""
460
+ data = {"outer": {}, "another": {"inner": {}}}
461
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
462
+ parsed = json.loads(result.decode("utf-8"))
463
+ assert parsed["outer"] == {}
464
+ assert parsed["another"]["inner"] == {}
465
+
466
+
467
+ def test_dict_with_numeric_string_keys():
468
+ """Test dict with numeric string keys"""
469
+ data = {"1": "one", "2": "two", "10": "ten"}
470
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
471
+ parsed = json.loads(result.decode("utf-8"))
472
+ assert parsed["1"] == "one"
473
+ assert parsed["2"] == "two"
474
+
475
+
476
+ def test_dict_with_very_long_strings():
477
+ """Test dict with very long string values"""
478
+ long_string = "x" * 100000
479
+ data = {"long": long_string}
480
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
481
+ parsed = json.loads(result.decode("utf-8"))
482
+ assert parsed["long"] == long_string
483
+
484
+
485
+ def test_dict_with_multiple_unicode_scripts():
486
+ """Test dict with multiple Unicode scripts"""
487
+ data = {
488
+ "latin": "Hello",
489
+ "cyrillic": "Привет",
490
+ "arabic": "مرحبا",
491
+ "chinese": "你好",
492
+ "japanese": "こんにちは",
493
+ "korean": "안녕하세요",
494
+ "emoji": "👋🌍",
495
+ }
496
+ result = PythonSerialiser.serialise(data, DataFormat.JSON)
497
+ parsed = json.loads(result.decode("utf-8"))
498
+ assert parsed == data
499
+
500
+
501
+ def test_output_encoding_consistency():
502
+ """Test output is consistently UTF-8 encoded"""
503
+ data = {"text": "test"}
504
+ result = PythonSerialiser.to_json(data)
505
+
506
+ # Should decode without error
507
+ text = result.decode("utf-8")
508
+ assert isinstance(text, str)