arctrl 3.0.0a3__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 (456) hide show
  1. arctrl/__init__.py +18 -0
  2. arctrl/py/CWL/__init__.py +0 -0
  3. arctrl/py/CWL/cwltypes.py +150 -0
  4. arctrl/py/CWL/decode.py +973 -0
  5. arctrl/py/CWL/encode.py +1 -0
  6. arctrl/py/CWL/inputs.py +88 -0
  7. arctrl/py/CWL/outputs.py +85 -0
  8. arctrl/py/CWL/requirements.py +77 -0
  9. arctrl/py/CWL/tool_description.py +103 -0
  10. arctrl/py/CWL/workflow_description.py +104 -0
  11. arctrl/py/CWL/workflow_steps.py +113 -0
  12. arctrl/py/Contract/__init__.py +0 -0
  13. arctrl/py/Contract/arc.py +60 -0
  14. arctrl/py/Contract/arc_assay.py +125 -0
  15. arctrl/py/Contract/arc_investigation.py +88 -0
  16. arctrl/py/Contract/arc_run.py +125 -0
  17. arctrl/py/Contract/arc_study.py +126 -0
  18. arctrl/py/Contract/arc_workflow.py +125 -0
  19. arctrl/py/Contract/contract.py +153 -0
  20. arctrl/py/Contract/datamap.py +372 -0
  21. arctrl/py/Contract/git.py +118 -0
  22. arctrl/py/Contract/validation_packages_config.py +107 -0
  23. arctrl/py/ContractIO/__init__.py +0 -0
  24. arctrl/py/ContractIO/contract_io.py +344 -0
  25. arctrl/py/ContractIO/file_system_helper.py +264 -0
  26. arctrl/py/Core/Helper/__init__.py +0 -0
  27. arctrl/py/Core/Helper/collections_.py +438 -0
  28. arctrl/py/Core/Helper/date_time.py +26 -0
  29. arctrl/py/Core/Helper/hash_codes.py +60 -0
  30. arctrl/py/Core/Helper/identifier.py +248 -0
  31. arctrl/py/Core/Helper/orcid.py +42 -0
  32. arctrl/py/Core/Helper/printer.py +13 -0
  33. arctrl/py/Core/Helper/regex.py +554 -0
  34. arctrl/py/Core/Helper/sem_ver.py +71 -0
  35. arctrl/py/Core/Helper/url.py +148 -0
  36. arctrl/py/Core/Process/__init__.py +0 -0
  37. arctrl/py/Core/Process/column_index.py +280 -0
  38. arctrl/py/Core/Process/component.py +200 -0
  39. arctrl/py/Core/Process/factor.py +151 -0
  40. arctrl/py/Core/Process/factor_value.py +182 -0
  41. arctrl/py/Core/Process/material.py +74 -0
  42. arctrl/py/Core/Process/material_attribute.py +95 -0
  43. arctrl/py/Core/Process/material_attribute_value.py +184 -0
  44. arctrl/py/Core/Process/material_type.py +45 -0
  45. arctrl/py/Core/Process/process.py +477 -0
  46. arctrl/py/Core/Process/process_input.py +265 -0
  47. arctrl/py/Core/Process/process_output.py +235 -0
  48. arctrl/py/Core/Process/process_parameter_value.py +200 -0
  49. arctrl/py/Core/Process/process_sequence.py +435 -0
  50. arctrl/py/Core/Process/protocol.py +175 -0
  51. arctrl/py/Core/Process/protocol_parameter.py +98 -0
  52. arctrl/py/Core/Process/sample.py +82 -0
  53. arctrl/py/Core/Process/source.py +62 -0
  54. arctrl/py/Core/Table/__init__.py +0 -0
  55. arctrl/py/Core/Table/arc_table.py +1264 -0
  56. arctrl/py/Core/Table/arc_table_aux.py +575 -0
  57. arctrl/py/Core/Table/arc_tables.py +591 -0
  58. arctrl/py/Core/Table/composite_cell.py +319 -0
  59. arctrl/py/Core/Table/composite_column.py +73 -0
  60. arctrl/py/Core/Table/composite_header.py +739 -0
  61. arctrl/py/Core/__init__.py +0 -0
  62. arctrl/py/Core/arc_types.py +5064 -0
  63. arctrl/py/Core/comment.py +128 -0
  64. arctrl/py/Core/comment_list.py +127 -0
  65. arctrl/py/Core/conversion.py +1313 -0
  66. arctrl/py/Core/data.py +245 -0
  67. arctrl/py/Core/data_context.py +157 -0
  68. arctrl/py/Core/data_file.py +112 -0
  69. arctrl/py/Core/data_map.py +225 -0
  70. arctrl/py/Core/identifier_setters.py +31 -0
  71. arctrl/py/Core/iproperty_value.py +36 -0
  72. arctrl/py/Core/ontology_annotation.py +299 -0
  73. arctrl/py/Core/ontology_source_reference.py +114 -0
  74. arctrl/py/Core/person.py +259 -0
  75. arctrl/py/Core/publication.py +161 -0
  76. arctrl/py/Core/template.py +231 -0
  77. arctrl/py/Core/templates.py +148 -0
  78. arctrl/py/Core/uri.py +11 -0
  79. arctrl/py/Core/value.py +188 -0
  80. arctrl/py/FileSystem/__init__.py +0 -0
  81. arctrl/py/FileSystem/commit.py +21 -0
  82. arctrl/py/FileSystem/default_gitattributes.py +5 -0
  83. arctrl/py/FileSystem/default_gitignore.py +5 -0
  84. arctrl/py/FileSystem/file_system.py +58 -0
  85. arctrl/py/FileSystem/file_system_tree.py +426 -0
  86. arctrl/py/FileSystem/path.py +64 -0
  87. arctrl/py/Json/DataMap/__init__.py +0 -0
  88. arctrl/py/Json/DataMap/data_context.py +101 -0
  89. arctrl/py/Json/DataMap/data_map.py +53 -0
  90. arctrl/py/Json/Process/__init__.py +0 -0
  91. arctrl/py/Json/Process/assay_materials.py +46 -0
  92. arctrl/py/Json/Process/component.py +79 -0
  93. arctrl/py/Json/Process/factor.py +107 -0
  94. arctrl/py/Json/Process/factor_value.py +101 -0
  95. arctrl/py/Json/Process/material.py +226 -0
  96. arctrl/py/Json/Process/material_attribute.py +79 -0
  97. arctrl/py/Json/Process/material_attribute_value.py +101 -0
  98. arctrl/py/Json/Process/material_type.py +53 -0
  99. arctrl/py/Json/Process/process.py +296 -0
  100. arctrl/py/Json/Process/process_input.py +83 -0
  101. arctrl/py/Json/Process/process_output.py +67 -0
  102. arctrl/py/Json/Process/process_parameter_value.py +81 -0
  103. arctrl/py/Json/Process/protocol.py +354 -0
  104. arctrl/py/Json/Process/protocol_parameter.py +79 -0
  105. arctrl/py/Json/Process/sample.py +277 -0
  106. arctrl/py/Json/Process/source.py +214 -0
  107. arctrl/py/Json/Process/study_materials.py +52 -0
  108. arctrl/py/Json/Process/value.py +56 -0
  109. arctrl/py/Json/ROCrate/__init__.py +0 -0
  110. arctrl/py/Json/ROCrate/ldcontext.py +133 -0
  111. arctrl/py/Json/ROCrate/ldgraph.py +111 -0
  112. arctrl/py/Json/ROCrate/ldnode.py +290 -0
  113. arctrl/py/Json/ROCrate/ldref.py +44 -0
  114. arctrl/py/Json/ROCrate/ldvalue.py +102 -0
  115. arctrl/py/Json/Table/__init__.py +0 -0
  116. arctrl/py/Json/Table/arc_table.py +393 -0
  117. arctrl/py/Json/Table/cell_table.py +83 -0
  118. arctrl/py/Json/Table/composite_cell.py +136 -0
  119. arctrl/py/Json/Table/composite_header.py +67 -0
  120. arctrl/py/Json/Table/iotype.py +24 -0
  121. arctrl/py/Json/Table/oatable.py +82 -0
  122. arctrl/py/Json/Table/templates.py +281 -0
  123. arctrl/py/Json/__init__.py +0 -0
  124. arctrl/py/Json/assay.py +600 -0
  125. arctrl/py/Json/comment.py +206 -0
  126. arctrl/py/Json/context/rocrate/__init__.py +0 -0
  127. arctrl/py/Json/context/rocrate/isa_assay_context.py +101 -0
  128. arctrl/py/Json/context/rocrate/isa_comment_context.py +60 -0
  129. arctrl/py/Json/context/rocrate/isa_component_context.py +77 -0
  130. arctrl/py/Json/context/rocrate/isa_data_context.py +74 -0
  131. arctrl/py/Json/context/rocrate/isa_factor_context.py +74 -0
  132. arctrl/py/Json/context/rocrate/isa_factor_value_context.py +84 -0
  133. arctrl/py/Json/context/rocrate/isa_investigation_context.py +110 -0
  134. arctrl/py/Json/context/rocrate/isa_material_attribute_context.py +64 -0
  135. arctrl/py/Json/context/rocrate/isa_material_attribute_value_context.py +80 -0
  136. arctrl/py/Json/context/rocrate/isa_material_context.py +71 -0
  137. arctrl/py/Json/context/rocrate/isa_ontology_annotation_context.py +68 -0
  138. arctrl/py/Json/context/rocrate/isa_ontology_source_reference_context.py +75 -0
  139. arctrl/py/Json/context/rocrate/isa_organization_context.py +55 -0
  140. arctrl/py/Json/context/rocrate/isa_person_context.py +131 -0
  141. arctrl/py/Json/context/rocrate/isa_process_context.py +94 -0
  142. arctrl/py/Json/context/rocrate/isa_process_parameter_value_context.py +80 -0
  143. arctrl/py/Json/context/rocrate/isa_protocol_context.py +97 -0
  144. arctrl/py/Json/context/rocrate/isa_protocol_parameter_context.py +64 -0
  145. arctrl/py/Json/context/rocrate/isa_publication_context.py +78 -0
  146. arctrl/py/Json/context/rocrate/isa_sample_context.py +65 -0
  147. arctrl/py/Json/context/rocrate/isa_source_context.py +66 -0
  148. arctrl/py/Json/context/rocrate/isa_study_context.py +125 -0
  149. arctrl/py/Json/context/rocrate/property_value_context.py +73 -0
  150. arctrl/py/Json/context/rocrate/rocrate_context.py +81 -0
  151. arctrl/py/Json/converter_options.py +23 -0
  152. arctrl/py/Json/data.py +356 -0
  153. arctrl/py/Json/data_file.py +63 -0
  154. arctrl/py/Json/decode.py +155 -0
  155. arctrl/py/Json/encode.py +92 -0
  156. arctrl/py/Json/idtable.py +44 -0
  157. arctrl/py/Json/investigation.py +695 -0
  158. arctrl/py/Json/ontology_annotation.py +404 -0
  159. arctrl/py/Json/ontology_source_reference.py +255 -0
  160. arctrl/py/Json/person.py +658 -0
  161. arctrl/py/Json/property_value.py +359 -0
  162. arctrl/py/Json/publication.py +279 -0
  163. arctrl/py/Json/string_table.py +76 -0
  164. arctrl/py/Json/study.py +793 -0
  165. arctrl/py/JsonIO/DataMap/__init__.py +0 -0
  166. arctrl/py/JsonIO/DataMap/data_map.py +53 -0
  167. arctrl/py/JsonIO/Process/__init__.py +0 -0
  168. arctrl/py/JsonIO/Process/component.py +60 -0
  169. arctrl/py/JsonIO/Process/factor.py +36 -0
  170. arctrl/py/JsonIO/Process/factor_value.py +38 -0
  171. arctrl/py/JsonIO/Process/material.py +60 -0
  172. arctrl/py/JsonIO/Process/material_attribute.py +38 -0
  173. arctrl/py/JsonIO/Process/material_attribute_value.py +60 -0
  174. arctrl/py/JsonIO/Process/material_type.py +36 -0
  175. arctrl/py/JsonIO/Process/process.py +60 -0
  176. arctrl/py/JsonIO/Process/process_input.py +38 -0
  177. arctrl/py/JsonIO/Process/process_output.py +60 -0
  178. arctrl/py/JsonIO/Process/process_parameter_value.py +60 -0
  179. arctrl/py/JsonIO/Process/process_sequence.py +71 -0
  180. arctrl/py/JsonIO/Process/protocol.py +60 -0
  181. arctrl/py/JsonIO/Process/protocol_parameter.py +36 -0
  182. arctrl/py/JsonIO/Process/sample.py +60 -0
  183. arctrl/py/JsonIO/Process/source.py +60 -0
  184. arctrl/py/JsonIO/Process/study_materials.py +52 -0
  185. arctrl/py/JsonIO/Process/value.py +32 -0
  186. arctrl/py/JsonIO/Table/__init__.py +0 -0
  187. arctrl/py/JsonIO/Table/arc_table.py +121 -0
  188. arctrl/py/JsonIO/Table/composite_cell.py +36 -0
  189. arctrl/py/JsonIO/Table/composite_header.py +36 -0
  190. arctrl/py/JsonIO/Table/compression.py +85 -0
  191. arctrl/py/JsonIO/Table/iotype.py +36 -0
  192. arctrl/py/JsonIO/Table/templates.py +113 -0
  193. arctrl/py/JsonIO/__init__.py +0 -0
  194. arctrl/py/JsonIO/assay.py +113 -0
  195. arctrl/py/JsonIO/comment.py +80 -0
  196. arctrl/py/JsonIO/data.py +60 -0
  197. arctrl/py/JsonIO/data_file.py +58 -0
  198. arctrl/py/JsonIO/decode.py +9 -0
  199. arctrl/py/JsonIO/encode.py +1 -0
  200. arctrl/py/JsonIO/investigation.py +113 -0
  201. arctrl/py/JsonIO/ldobject.py +106 -0
  202. arctrl/py/JsonIO/ontology_annotation.py +80 -0
  203. arctrl/py/JsonIO/ontology_source_reference.py +80 -0
  204. arctrl/py/JsonIO/person.py +82 -0
  205. arctrl/py/JsonIO/publication.py +82 -0
  206. arctrl/py/JsonIO/study.py +114 -0
  207. arctrl/py/ROCrate/Generic/__init__.py +0 -0
  208. arctrl/py/ROCrate/Generic/comment.py +131 -0
  209. arctrl/py/ROCrate/Generic/dataset.py +817 -0
  210. arctrl/py/ROCrate/Generic/defined_term.py +131 -0
  211. arctrl/py/ROCrate/Generic/file.py +237 -0
  212. arctrl/py/ROCrate/Generic/lab_process.py +324 -0
  213. arctrl/py/ROCrate/Generic/lab_protocol.py +338 -0
  214. arctrl/py/ROCrate/Generic/organization.py +83 -0
  215. arctrl/py/ROCrate/Generic/person.py +484 -0
  216. arctrl/py/ROCrate/Generic/postal_address.py +195 -0
  217. arctrl/py/ROCrate/Generic/property_value.py +696 -0
  218. arctrl/py/ROCrate/Generic/sample.py +202 -0
  219. arctrl/py/ROCrate/Generic/scholarly_article.py +229 -0
  220. arctrl/py/ROCrate/ISAProfile/__init__.py +0 -0
  221. arctrl/py/ROCrate/ISAProfile/assay.py +70 -0
  222. arctrl/py/ROCrate/ISAProfile/data.py +65 -0
  223. arctrl/py/ROCrate/ISAProfile/dataset.py +24 -0
  224. arctrl/py/ROCrate/ISAProfile/investigation.py +73 -0
  225. arctrl/py/ROCrate/ISAProfile/lab_process.py +162 -0
  226. arctrl/py/ROCrate/ISAProfile/lab_protocol.py +37 -0
  227. arctrl/py/ROCrate/ISAProfile/person.py +72 -0
  228. arctrl/py/ROCrate/ISAProfile/property_value.py +98 -0
  229. arctrl/py/ROCrate/ISAProfile/sample.py +64 -0
  230. arctrl/py/ROCrate/ISAProfile/scholarly_article.py +98 -0
  231. arctrl/py/ROCrate/ISAProfile/study.py +74 -0
  232. arctrl/py/ROCrate/__init__.py +0 -0
  233. arctrl/py/ROCrate/arc_rocrate_metadata.py +39 -0
  234. arctrl/py/ROCrate/dyn_obj_extensions.py +1 -0
  235. arctrl/py/ROCrate/helper.py +8 -0
  236. arctrl/py/ROCrate/ldcontext.py +362 -0
  237. arctrl/py/ROCrate/ldobject.py +1247 -0
  238. arctrl/py/ROCrate/rocrate_context.py +51 -0
  239. arctrl/py/Spreadsheet/AnnotationTable/__init__.py +0 -0
  240. arctrl/py/Spreadsheet/AnnotationTable/arc_table.py +193 -0
  241. arctrl/py/Spreadsheet/AnnotationTable/composite_cell.py +78 -0
  242. arctrl/py/Spreadsheet/AnnotationTable/composite_column.py +210 -0
  243. arctrl/py/Spreadsheet/AnnotationTable/composite_header.py +623 -0
  244. arctrl/py/Spreadsheet/DataMapTable/__init__.py +0 -0
  245. arctrl/py/Spreadsheet/DataMapTable/data_map_column.py +114 -0
  246. arctrl/py/Spreadsheet/DataMapTable/data_map_header.py +618 -0
  247. arctrl/py/Spreadsheet/DataMapTable/data_map_table.py +119 -0
  248. arctrl/py/Spreadsheet/Metadata/__init__.py +0 -0
  249. arctrl/py/Spreadsheet/Metadata/assays.py +125 -0
  250. arctrl/py/Spreadsheet/Metadata/comment.py +77 -0
  251. arctrl/py/Spreadsheet/Metadata/contacts.py +134 -0
  252. arctrl/py/Spreadsheet/Metadata/conversions.py +190 -0
  253. arctrl/py/Spreadsheet/Metadata/design_descriptors.py +34 -0
  254. arctrl/py/Spreadsheet/Metadata/factors.py +107 -0
  255. arctrl/py/Spreadsheet/Metadata/ontology_annotation.py +88 -0
  256. arctrl/py/Spreadsheet/Metadata/ontology_source_reference.py +96 -0
  257. arctrl/py/Spreadsheet/Metadata/protocols.py +146 -0
  258. arctrl/py/Spreadsheet/Metadata/publication.py +122 -0
  259. arctrl/py/Spreadsheet/Metadata/run.py +122 -0
  260. arctrl/py/Spreadsheet/Metadata/sparse_table.py +508 -0
  261. arctrl/py/Spreadsheet/Metadata/study.py +312 -0
  262. arctrl/py/Spreadsheet/Metadata/workflow.py +151 -0
  263. arctrl/py/Spreadsheet/__init__.py +0 -0
  264. arctrl/py/Spreadsheet/arc_assay.py +233 -0
  265. arctrl/py/Spreadsheet/arc_investigation.py +418 -0
  266. arctrl/py/Spreadsheet/arc_run.py +190 -0
  267. arctrl/py/Spreadsheet/arc_study.py +144 -0
  268. arctrl/py/Spreadsheet/arc_workflow.py +176 -0
  269. arctrl/py/Spreadsheet/assembly_info.py +1 -0
  270. arctrl/py/Spreadsheet/collection_aux.py +167 -0
  271. arctrl/py/Spreadsheet/data_map.py +44 -0
  272. arctrl/py/Spreadsheet/template.py +460 -0
  273. arctrl/py/ValidationPackages/__init__.py +0 -0
  274. arctrl/py/ValidationPackages/validation_package.py +82 -0
  275. arctrl/py/ValidationPackages/validation_packages_config.py +132 -0
  276. arctrl/py/WebRequest/__init__.py +0 -0
  277. arctrl/py/WebRequest/web_request.py +9 -0
  278. arctrl/py/WebRequest/web_request_py.py +135 -0
  279. arctrl/py/Yaml/__init__.py +0 -0
  280. arctrl/py/Yaml/decode.py +1 -0
  281. arctrl/py/Yaml/encode.py +10 -0
  282. arctrl/py/Yaml/validation_package.py +77 -0
  283. arctrl/py/Yaml/validation_packages_config.py +86 -0
  284. arctrl/py/__init__.py +0 -0
  285. arctrl/py/arc.py +1400 -0
  286. arctrl/py/column_index.py +280 -0
  287. arctrl/py/conversion.py +2184 -0
  288. arctrl/py/cross_async.py +76 -0
  289. arctrl/py/fable_modules/dynamic_obj/__init__.py +0 -0
  290. arctrl/py/fable_modules/dynamic_obj/dyn_obj.py +136 -0
  291. arctrl/py/fable_modules/dynamic_obj/dynamic_obj.py +415 -0
  292. arctrl/py/fable_modules/dynamic_obj/fable_js.py +1 -0
  293. arctrl/py/fable_modules/dynamic_obj/fable_py.py +288 -0
  294. arctrl/py/fable_modules/dynamic_obj/hash_codes.py +82 -0
  295. arctrl/py/fable_modules/dynamic_obj/property_helper.py +25 -0
  296. arctrl/py/fable_modules/dynamic_obj/reflection_utils.py +87 -0
  297. arctrl/py/fable_modules/fable_library/__init__.py +0 -0
  298. arctrl/py/fable_modules/fable_library/array_.py +1528 -0
  299. arctrl/py/fable_modules/fable_library/async_.py +377 -0
  300. arctrl/py/fable_modules/fable_library/async_builder.py +379 -0
  301. arctrl/py/fable_modules/fable_library/big_int.py +330 -0
  302. arctrl/py/fable_modules/fable_library/bit_converter.py +131 -0
  303. arctrl/py/fable_modules/fable_library/boolean.py +26 -0
  304. arctrl/py/fable_modules/fable_library/char.py +237 -0
  305. arctrl/py/fable_modules/fable_library/choice.py +212 -0
  306. arctrl/py/fable_modules/fable_library/date.py +779 -0
  307. arctrl/py/fable_modules/fable_library/date_offset.py +79 -0
  308. arctrl/py/fable_modules/fable_library/decimal_.py +190 -0
  309. arctrl/py/fable_modules/fable_library/diagnostics.py +54 -0
  310. arctrl/py/fable_modules/fable_library/double.py +87 -0
  311. arctrl/py/fable_modules/fable_library/encoding.py +41 -0
  312. arctrl/py/fable_modules/fable_library/event.py +206 -0
  313. arctrl/py/fable_modules/fable_library/file.py +107 -0
  314. arctrl/py/fable_modules/fable_library/fsharp_collections.py +52 -0
  315. arctrl/py/fable_modules/fable_library/fsharp_core.py +123 -0
  316. arctrl/py/fable_modules/fable_library/global_.py +63 -0
  317. arctrl/py/fable_modules/fable_library/guid.py +41 -0
  318. arctrl/py/fable_modules/fable_library/int32.py +73 -0
  319. arctrl/py/fable_modules/fable_library/list.py +1788 -0
  320. arctrl/py/fable_modules/fable_library/long.py +240 -0
  321. arctrl/py/fable_modules/fable_library/mailbox_processor.py +179 -0
  322. arctrl/py/fable_modules/fable_library/map.py +1854 -0
  323. arctrl/py/fable_modules/fable_library/map_util.py +148 -0
  324. arctrl/py/fable_modules/fable_library/mutable_map.py +397 -0
  325. arctrl/py/fable_modules/fable_library/mutable_set.py +279 -0
  326. arctrl/py/fable_modules/fable_library/native.py +45 -0
  327. arctrl/py/fable_modules/fable_library/numeric.py +46 -0
  328. arctrl/py/fable_modules/fable_library/observable.py +222 -0
  329. arctrl/py/fable_modules/fable_library/option.py +128 -0
  330. arctrl/py/fable_modules/fable_library/path.py +62 -0
  331. arctrl/py/fable_modules/fable_library/range.py +117 -0
  332. arctrl/py/fable_modules/fable_library/reflection.py +463 -0
  333. arctrl/py/fable_modules/fable_library/reg_exp.py +137 -0
  334. arctrl/py/fable_modules/fable_library/resize_array.py +31 -0
  335. arctrl/py/fable_modules/fable_library/result.py +212 -0
  336. arctrl/py/fable_modules/fable_library/seq.py +1979 -0
  337. arctrl/py/fable_modules/fable_library/seq2.py +221 -0
  338. arctrl/py/fable_modules/fable_library/set.py +2414 -0
  339. arctrl/py/fable_modules/fable_library/singleton_local_time_zone.py +36 -0
  340. arctrl/py/fable_modules/fable_library/string_.py +573 -0
  341. arctrl/py/fable_modules/fable_library/system_collections_generic.py +462 -0
  342. arctrl/py/fable_modules/fable_library/system_text.py +237 -0
  343. arctrl/py/fable_modules/fable_library/task.py +116 -0
  344. arctrl/py/fable_modules/fable_library/task_builder.py +122 -0
  345. arctrl/py/fable_modules/fable_library/thread.py +5 -0
  346. arctrl/py/fable_modules/fable_library/time_span.py +283 -0
  347. arctrl/py/fable_modules/fable_library/timer.py +24 -0
  348. arctrl/py/fable_modules/fable_library/types.py +401 -0
  349. arctrl/py/fable_modules/fable_library/uri.py +109 -0
  350. arctrl/py/fable_modules/fable_library/util.py +2735 -0
  351. arctrl/py/fable_modules/fable_openpyxl/__init__.py +0 -0
  352. arctrl/py/fable_modules/fable_openpyxl/openpyxl.py +362 -0
  353. arctrl/py/fable_modules/fable_python/cognite-sdk/__init__.py +0 -0
  354. arctrl/py/fable_modules/fable_python/cognite-sdk/cognite_sdk.py +22 -0
  355. arctrl/py/fable_modules/fable_python/flask/__init__.py +0 -0
  356. arctrl/py/fable_modules/fable_python/flask/flask.py +34 -0
  357. arctrl/py/fable_modules/fable_python/jupyter/__init__.py +0 -0
  358. arctrl/py/fable_modules/fable_python/jupyter/ipy_widgets.py +47 -0
  359. arctrl/py/fable_modules/fable_python/jupyter/ipython.py +13 -0
  360. arctrl/py/fable_modules/fable_python/stdlib/__init__.py +0 -0
  361. arctrl/py/fable_modules/fable_python/stdlib/ast.py +1 -0
  362. arctrl/py/fable_modules/fable_python/stdlib/asyncio/__init__.py +0 -0
  363. arctrl/py/fable_modules/fable_python/stdlib/asyncio/events.py +17 -0
  364. arctrl/py/fable_modules/fable_python/stdlib/asyncio/futures.py +52 -0
  365. arctrl/py/fable_modules/fable_python/stdlib/asyncio/tasks.py +38 -0
  366. arctrl/py/fable_modules/fable_python/stdlib/base64_.py +1 -0
  367. arctrl/py/fable_modules/fable_python/stdlib/builtins_.py +38 -0
  368. arctrl/py/fable_modules/fable_python/stdlib/html.py +1 -0
  369. arctrl/py/fable_modules/fable_python/stdlib/json.py +1 -0
  370. arctrl/py/fable_modules/fable_python/stdlib/math_.py +1 -0
  371. arctrl/py/fable_modules/fable_python/stdlib/os_.py +1 -0
  372. arctrl/py/fable_modules/fable_python/stdlib/queue_.py +1 -0
  373. arctrl/py/fable_modules/fable_python/stdlib/string_.py +1 -0
  374. arctrl/py/fable_modules/fable_python/stdlib/sys_.py +30 -0
  375. arctrl/py/fable_modules/fable_python/stdlib/time_.py +1 -0
  376. arctrl/py/fable_modules/fable_python/stdlib/tk_inter.py +1 -0
  377. arctrl/py/fable_modules/fs_spreadsheet/Cells/__init__.py +0 -0
  378. arctrl/py/fable_modules/fs_spreadsheet/Cells/fs_cell.py +338 -0
  379. arctrl/py/fable_modules/fs_spreadsheet/Cells/fs_cells_collection.py +469 -0
  380. arctrl/py/fable_modules/fs_spreadsheet/DSL/__init__.py +0 -0
  381. arctrl/py/fable_modules/fs_spreadsheet/DSL/cell_builder.py +214 -0
  382. arctrl/py/fable_modules/fs_spreadsheet/DSL/column_builder.py +139 -0
  383. arctrl/py/fable_modules/fs_spreadsheet/DSL/dsl.py +50 -0
  384. arctrl/py/fable_modules/fs_spreadsheet/DSL/expression.py +65 -0
  385. arctrl/py/fable_modules/fs_spreadsheet/DSL/operators.py +9 -0
  386. arctrl/py/fable_modules/fs_spreadsheet/DSL/row_builder.py +139 -0
  387. arctrl/py/fable_modules/fs_spreadsheet/DSL/sheet_builder.py +118 -0
  388. arctrl/py/fable_modules/fs_spreadsheet/DSL/table_builder.py +122 -0
  389. arctrl/py/fable_modules/fs_spreadsheet/DSL/transform.py +464 -0
  390. arctrl/py/fable_modules/fs_spreadsheet/DSL/types.py +314 -0
  391. arctrl/py/fable_modules/fs_spreadsheet/DSL/workbook_builder.py +106 -0
  392. arctrl/py/fable_modules/fs_spreadsheet/Json/__init__.py +0 -0
  393. arctrl/py/fable_modules/fs_spreadsheet/Json/cell.py +103 -0
  394. arctrl/py/fable_modules/fs_spreadsheet/Json/column.py +70 -0
  395. arctrl/py/fable_modules/fs_spreadsheet/Json/row.py +70 -0
  396. arctrl/py/fable_modules/fs_spreadsheet/Json/table.py +57 -0
  397. arctrl/py/fable_modules/fs_spreadsheet/Json/value.py +93 -0
  398. arctrl/py/fable_modules/fs_spreadsheet/Json/workbook.py +71 -0
  399. arctrl/py/fable_modules/fs_spreadsheet/Json/worksheet.py +217 -0
  400. arctrl/py/fable_modules/fs_spreadsheet/Ranges/__init__.py +0 -0
  401. arctrl/py/fable_modules/fs_spreadsheet/Ranges/fs_range.py +47 -0
  402. arctrl/py/fable_modules/fs_spreadsheet/Ranges/fs_range_address.py +186 -0
  403. arctrl/py/fable_modules/fs_spreadsheet/Ranges/fs_range_base.py +90 -0
  404. arctrl/py/fable_modules/fs_spreadsheet/Ranges/fs_range_column.py +78 -0
  405. arctrl/py/fable_modules/fs_spreadsheet/Ranges/fs_range_row.py +48 -0
  406. arctrl/py/fable_modules/fs_spreadsheet/Tables/__init__.py +0 -0
  407. arctrl/py/fable_modules/fs_spreadsheet/Tables/fs_table.py +393 -0
  408. arctrl/py/fable_modules/fs_spreadsheet/Tables/fs_table_field.py +127 -0
  409. arctrl/py/fable_modules/fs_spreadsheet/Tables/fs_table_row.py +23 -0
  410. arctrl/py/fable_modules/fs_spreadsheet/__init__.py +0 -0
  411. arctrl/py/fable_modules/fs_spreadsheet/fs_address.py +218 -0
  412. arctrl/py/fable_modules/fs_spreadsheet/fs_column.py +172 -0
  413. arctrl/py/fable_modules/fs_spreadsheet/fs_row.py +183 -0
  414. arctrl/py/fable_modules/fs_spreadsheet/fs_workbook.py +180 -0
  415. arctrl/py/fable_modules/fs_spreadsheet/fs_worksheet.py +600 -0
  416. arctrl/py/fable_modules/fs_spreadsheet/sheet_builder.py +330 -0
  417. arctrl/py/fable_modules/fs_spreadsheet_py/__init__.py +0 -0
  418. arctrl/py/fable_modules/fs_spreadsheet_py/cell.py +63 -0
  419. arctrl/py/fable_modules/fs_spreadsheet_py/cell_type.py +50 -0
  420. arctrl/py/fable_modules/fs_spreadsheet_py/fs_extension.py +60 -0
  421. arctrl/py/fable_modules/fs_spreadsheet_py/json.py +47 -0
  422. arctrl/py/fable_modules/fs_spreadsheet_py/table.py +53 -0
  423. arctrl/py/fable_modules/fs_spreadsheet_py/workbook.py +40 -0
  424. arctrl/py/fable_modules/fs_spreadsheet_py/worksheet.py +54 -0
  425. arctrl/py/fable_modules/fs_spreadsheet_py/xlsx.py +37 -0
  426. arctrl/py/fable_modules/thoth_json_core/__init__.py +0 -0
  427. arctrl/py/fable_modules/thoth_json_core/decode.py +1588 -0
  428. arctrl/py/fable_modules/thoth_json_core/encode.py +261 -0
  429. arctrl/py/fable_modules/thoth_json_core/types.py +181 -0
  430. arctrl/py/fable_modules/thoth_json_python/__init__.py +0 -0
  431. arctrl/py/fable_modules/thoth_json_python/decode.py +112 -0
  432. arctrl/py/fable_modules/thoth_json_python/encode.py +72 -0
  433. arctrl/py/fable_modules/thoth_json_python/python.py +1 -0
  434. arctrl/py/fable_modules/yamlicious/Interop/__init__.py +0 -0
  435. arctrl/py/fable_modules/yamlicious/Interop/js_interop.py +1 -0
  436. arctrl/py/fable_modules/yamlicious/Interop/py_interop.py +7 -0
  437. arctrl/py/fable_modules/yamlicious/__init__.py +0 -0
  438. arctrl/py/fable_modules/yamlicious/decode.py +1784 -0
  439. arctrl/py/fable_modules/yamlicious/encode.py +84 -0
  440. arctrl/py/fable_modules/yamlicious/library.py +10 -0
  441. arctrl/py/fable_modules/yamlicious/persil.py +57 -0
  442. arctrl/py/fable_modules/yamlicious/preprocessing.py +99 -0
  443. arctrl/py/fable_modules/yamlicious/reader.py +665 -0
  444. arctrl/py/fable_modules/yamlicious/regex.py +21 -0
  445. arctrl/py/fable_modules/yamlicious/regex_active_patterns.py +256 -0
  446. arctrl/py/fable_modules/yamlicious/writer.py +175 -0
  447. arctrl/py/fable_modules/yamlicious/yamlicious_types.py +128 -0
  448. arctrl/py/json.py +213 -0
  449. arctrl/py/rocrate_io.py +72 -0
  450. arctrl/py/template_web.py +23 -0
  451. arctrl/py/xlsx.py +148 -0
  452. arctrl/rocrate.py +21 -0
  453. arctrl-3.0.0a3.dist-info/LICENSE +21 -0
  454. arctrl-3.0.0a3.dist-info/METADATA +119 -0
  455. arctrl-3.0.0a3.dist-info/RECORD +456 -0
  456. arctrl-3.0.0a3.dist-info/WHEEL +4 -0
@@ -0,0 +1,779 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from datetime import datetime, timedelta, timezone
5
+ from math import fmod
6
+ from typing import Any
7
+
8
+ from .singleton_local_time_zone import local_time_zone
9
+ from .time_span import TimeSpan, total_microseconds
10
+ from .time_span import create as create_time_span
11
+ from .types import FSharpRef
12
+ from .util import DateKind
13
+
14
+
15
+ # Some of the code in this file has been adapted from
16
+ # https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/mscorlib/system/globalization/datetimeformat.cs
17
+
18
+ short_days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
19
+
20
+ long_days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
21
+
22
+ short_months = [
23
+ "Jan",
24
+ "Feb",
25
+ "Mar",
26
+ "Apr",
27
+ "May",
28
+ "Jun",
29
+ "Jul",
30
+ "Aug",
31
+ "Sep",
32
+ "Oct",
33
+ "Nov",
34
+ "Dec",
35
+ ]
36
+
37
+ long_months = [
38
+ "January",
39
+ "February",
40
+ "March",
41
+ "April",
42
+ "May",
43
+ "June",
44
+ "July",
45
+ "August",
46
+ "September",
47
+ "October",
48
+ "November",
49
+ "December",
50
+ ]
51
+
52
+
53
+ def subtract(x: datetime, y: datetime | TimeSpan) -> datetime | TimeSpan:
54
+ if isinstance(y, datetime):
55
+ delta = x - y
56
+ # ts.microseconds only contains the microseconds provided to the constructor
57
+ # so we need to calculate the total microseconds ourselves
58
+ delta_microseconds = delta.days * (24 * 3600 * 10**6) + delta.seconds * 10**6 + delta.microseconds
59
+ return create_time_span(0, 0, 0, 0, 0, delta_microseconds)
60
+
61
+ return x - timedelta(microseconds=total_microseconds(y))
62
+
63
+
64
+ def op_subtraction(x: datetime, y: datetime | TimeSpan) -> datetime | TimeSpan:
65
+ return subtract(x, y)
66
+
67
+
68
+ def create(
69
+ year: int,
70
+ month: int,
71
+ day: int,
72
+ h: int = 0,
73
+ m: int = 0,
74
+ s: int = 0,
75
+ ms: int = 0,
76
+ mc: int = 0,
77
+ kind: DateKind | None = None,
78
+ ) -> datetime:
79
+ if kind == DateKind.UTC:
80
+ date = datetime(
81
+ year=year,
82
+ month=month,
83
+ day=day,
84
+ hour=h,
85
+ minute=m,
86
+ second=s,
87
+ microsecond=mc + ms * 1_000,
88
+ tzinfo=timezone.utc,
89
+ )
90
+ else:
91
+ date = datetime(year, month, day, h, m, s, mc + ms * 1_000)
92
+ if kind == DateKind.Local:
93
+ date = date.astimezone(local_time_zone)
94
+
95
+ return date
96
+
97
+
98
+ def year(d: datetime) -> int:
99
+ return d.year
100
+
101
+
102
+ def month(d: datetime) -> int:
103
+ return d.month
104
+
105
+
106
+ def day(d: datetime) -> int:
107
+ return d.day
108
+
109
+
110
+ def hour(d: datetime) -> int:
111
+ return d.hour
112
+
113
+
114
+ def minute(d: datetime) -> int:
115
+ return d.minute
116
+
117
+
118
+ def second(d: datetime) -> int:
119
+ return d.second
120
+
121
+
122
+ def millisecond(d: datetime) -> int:
123
+ return d.microsecond // 1_000
124
+
125
+
126
+ def microsecond(d: datetime) -> int:
127
+ return d.microsecond
128
+
129
+
130
+ def to_universal_time(d: datetime) -> datetime:
131
+ return d.astimezone(timezone.utc)
132
+
133
+
134
+ def day_of_week(d: datetime) -> int:
135
+ return (d.weekday() + 1) % 7
136
+
137
+
138
+ def day_of_year(d: datetime) -> int:
139
+ return d.timetuple().tm_yday
140
+
141
+
142
+ def to_short_date_string(date: datetime) -> str:
143
+ return datetime.strftime(date, "%m/%d/%Y")
144
+
145
+
146
+ def to_long_date_string(date: datetime) -> str:
147
+ return datetime.strftime(date, "%A, %d %B %Y")
148
+
149
+
150
+ def to_short_time_string(date: datetime) -> str:
151
+ return datetime.strftime(date, "%H:%M")
152
+
153
+
154
+ def to_long_time_string(date: datetime) -> str:
155
+ return datetime.strftime(date, "%H:%M:%S")
156
+
157
+
158
+ def parse_repeat_token(format: str, pos: int, pattern_char: str) -> int:
159
+ token_length = 0
160
+ internal_pos = pos
161
+ while internal_pos < len(format) and format[internal_pos] == pattern_char:
162
+ internal_pos += 1
163
+ token_length += 1
164
+
165
+ return token_length
166
+
167
+
168
+ # Get the next character at the index of 'pos' in the 'format' string.
169
+ # Return value of -1 means 'pos' is already at the end of the 'format' string.
170
+ # Otherwise, return value is the int value of the next character.
171
+ def parse_next_char(format: str, pos: int) -> int:
172
+ if pos >= len(format) - 1:
173
+ return -1
174
+
175
+ return ord(format[pos + 1])
176
+
177
+
178
+ def parse_quoted_string(format: str, pos: int) -> tuple[str, int]:
179
+ begin_pos = pos
180
+ format_length = len(format)
181
+ # Get the character used to quote the string
182
+ quote_char = format[pos]
183
+
184
+ result = ""
185
+ found_quote = False
186
+
187
+ while pos < format_length:
188
+ pos += 1
189
+ current_char = format[pos]
190
+ if current_char == quote_char:
191
+ found_quote = True
192
+ break
193
+ elif current_char == "\\":
194
+ if pos < format_length:
195
+ pos += 1
196
+ result += format[pos]
197
+ else:
198
+ # This means that '\'is the last character in the format string.
199
+ raise ValueError("Invalid string format")
200
+ else:
201
+ result += current_char
202
+
203
+ if not found_quote:
204
+ # We couldn't find the matching quote
205
+ raise ValueError(f"Invalid string format could not find matching quote for {quote_char}")
206
+
207
+ return (result, pos - begin_pos + 1)
208
+
209
+
210
+ def date_to_string_with_custom_format(date: datetime, format: str, utc: bool) -> str:
211
+ cursor_pos = 0
212
+ token_length = 0
213
+ result = ""
214
+ localized_date = date.astimezone(timezone.utc) if utc else date
215
+
216
+ while cursor_pos < len(format):
217
+ token = format[cursor_pos]
218
+
219
+ match token:
220
+ case "d":
221
+ token_length = parse_repeat_token(format, cursor_pos, "d")
222
+ cursor_pos += token_length
223
+ match token_length:
224
+ case 1:
225
+ result += str(localized_date.day)
226
+ case 2:
227
+ result += localized_date.strftime("%d")
228
+ case 3:
229
+ result += short_days[day_of_week(localized_date)]
230
+ case 4:
231
+ result += long_days[day_of_week(localized_date)]
232
+ case _:
233
+ pass
234
+ case "f":
235
+ token_length = parse_repeat_token(format, cursor_pos, "f")
236
+ cursor_pos += token_length
237
+ match token_length:
238
+ case 1 | 2 | 3 | 4 | 5 | 6:
239
+ precision = 10 ** (6 - token_length)
240
+ result += str(localized_date.microsecond // precision).zfill(token_length)
241
+ # Python datetime only support precision up to the microsecond
242
+ # so we need to fill the rest with 0
243
+ case 7:
244
+ result += str(localized_date.microsecond).zfill(6).ljust(token_length, "0")
245
+ case _:
246
+ pass
247
+ case "F":
248
+ token_length = parse_repeat_token(format, cursor_pos, "F")
249
+ cursor_pos += token_length
250
+ match token_length:
251
+ case 1 | 2 | 3 | 4 | 5 | 6:
252
+ precision = 10 ** (6 - token_length)
253
+ value = localized_date.microsecond // precision
254
+ if value != 0:
255
+ result += str(value).zfill(token_length)
256
+ # Python datetime only support precision up to the microsecond
257
+ # so we can't go further
258
+ # We alse need to pad start with 0 if the value is not 0
259
+ case 7:
260
+ value = localized_date.microsecond
261
+ if value != 0:
262
+ result += str(value).zfill(6).rstrip("0")
263
+ case _:
264
+ pass
265
+ case "g":
266
+ token_length = parse_repeat_token(format, cursor_pos, "g")
267
+ cursor_pos += token_length
268
+ match token_length:
269
+ case 1 | 2:
270
+ result += "A.D."
271
+ case _:
272
+ pass
273
+
274
+ case "h":
275
+ token_length = parse_repeat_token(format, cursor_pos, "h")
276
+ cursor_pos += token_length
277
+ match token_length:
278
+ case 1:
279
+ result += str(localized_date.hour % 12)
280
+ case 2:
281
+ result += localized_date.strftime("%I")
282
+ case _:
283
+ pass
284
+ case "H":
285
+ token_length = parse_repeat_token(format, cursor_pos, "H")
286
+ cursor_pos += token_length
287
+ match token_length:
288
+ case 1:
289
+ result += str(localized_date.hour)
290
+ case 2:
291
+ result += localized_date.strftime("%H")
292
+ case _:
293
+ pass
294
+ case "K":
295
+ token_length = parse_repeat_token(format, cursor_pos, "K")
296
+ cursor_pos += token_length
297
+ match token_length:
298
+ case 1:
299
+ match kind(date):
300
+ case DateKind.UTC:
301
+ result += "Z"
302
+ case DateKind.Local:
303
+ # %:z is not a perfect match for the .NET equivalent
304
+ # but it seems to do the job
305
+ # If needed we can probably compute the offset manually
306
+ # and format it ourselves
307
+ result += date.strftime("%:z")
308
+ case DateKind.Unspecified:
309
+ result += ""
310
+ case _:
311
+ pass
312
+ case "m":
313
+ token_length = parse_repeat_token(format, cursor_pos, "m")
314
+ cursor_pos += token_length
315
+ match token_length:
316
+ case 1:
317
+ result += str(localized_date.minute)
318
+ case 2:
319
+ result += localized_date.strftime("%M")
320
+ case _:
321
+ pass
322
+ case "M":
323
+ token_length = parse_repeat_token(format, cursor_pos, "M")
324
+ cursor_pos += token_length
325
+ match token_length:
326
+ case 1:
327
+ result += str(localized_date.month)
328
+ case 2:
329
+ result += localized_date.strftime("%m")
330
+ case 3:
331
+ result += short_months[month(localized_date) - 1]
332
+ case 4:
333
+ result += long_months[month(localized_date) - 1]
334
+ case _:
335
+ pass
336
+ case "s":
337
+ token_length = parse_repeat_token(format, cursor_pos, "s")
338
+ cursor_pos += token_length
339
+ match token_length:
340
+ case 1:
341
+ result += str(localized_date.second)
342
+ case 2:
343
+ result += localized_date.strftime("%S")
344
+ case _:
345
+ pass
346
+ case "t":
347
+ token_length = parse_repeat_token(format, cursor_pos, "t")
348
+ cursor_pos += token_length
349
+ match token_length:
350
+ case 1:
351
+ result += localized_date.strftime("%p")[:1]
352
+ case 2:
353
+ result += localized_date.strftime("%p")
354
+ case _:
355
+ pass
356
+ case "y":
357
+ token_length = parse_repeat_token(format, cursor_pos, "y")
358
+ cursor_pos += token_length
359
+ match token_length:
360
+ case 1:
361
+ result += str(localized_date.year % 100)
362
+ case 2:
363
+ result += str(localized_date.year)[-2:].zfill(2)
364
+ case length:
365
+ result += str(localized_date.year).zfill(length)
366
+ case "z":
367
+ token_length = parse_repeat_token(format, cursor_pos, "z")
368
+ cursor_pos += token_length
369
+
370
+ match kind(date):
371
+ case DateKind.UTC:
372
+ utc_offet_text = localized_date.strftime("%z")
373
+ case DateKind.Local:
374
+ utc_offet_text = localized_date.strftime("%z")
375
+ case DateKind.Unspecified:
376
+ utc_offet_text = to_local_time(date).strftime("%z")
377
+
378
+ sign = utc_offet_text[:1]
379
+ hours = int(utc_offet_text[1:3])
380
+ minutes = int(utc_offet_text[3:5])
381
+
382
+ match token_length:
383
+ case 1:
384
+ result += f"{sign}{hours}"
385
+ case 2:
386
+ result += f"{sign}{hours:02}"
387
+ case 3 | _:
388
+ result += f"{sign}{hours:02}:{minutes:02}"
389
+ case ":":
390
+ cursor_pos += 1
391
+ result += ":"
392
+ case "/":
393
+ cursor_pos += 1
394
+ result += "/"
395
+ case "'" | '"':
396
+ quoted_string, quoted_string_length = parse_quoted_string(format, cursor_pos)
397
+ cursor_pos += quoted_string_length
398
+ result += quoted_string
399
+ case "%":
400
+ next_char = parse_next_char(format, cursor_pos)
401
+ if next_char >= 0 and next_char != ord("%"):
402
+ cursor_pos += 2
403
+ result += date_to_string_with_custom_format(date, chr(next_char), utc)
404
+ else:
405
+ raise Exception("Invalid string format")
406
+ case "\\":
407
+ next_char = parse_next_char(format, cursor_pos)
408
+ if next_char >= 0:
409
+ result += chr(next_char)
410
+ cursor_pos += 2
411
+ else:
412
+ raise Exception("Invalid string format")
413
+ case _:
414
+ cursor_pos += 1
415
+ result += token
416
+ pass
417
+
418
+ return result
419
+
420
+
421
+ def date_to_string_with_offset(date: datetime, format: str | None = None) -> str:
422
+ utc = date.tzinfo == timezone.utc
423
+
424
+ match format:
425
+ case None:
426
+ raise NotImplementedError("date_to_string_with_offset")
427
+ case "O" | "o":
428
+ return date.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
429
+ case _ if len(format) == 1:
430
+ raise Exception("Unrecognized Date print format")
431
+ case _:
432
+ return date_to_string_with_custom_format(date, format, utc)
433
+
434
+
435
+ def date_to_string_with_kind(date: datetime, format: str | None = None) -> str:
436
+ utc = date.tzinfo == timezone.utc
437
+
438
+ if not format:
439
+ return date.isoformat() if utc else str(date)
440
+ elif len(format) == 1:
441
+ if format == "d":
442
+ return to_short_date_string(date)
443
+ elif format == "D":
444
+ return to_long_date_string(date)
445
+ elif format == "T":
446
+ return to_long_time_string(date)
447
+ elif format == "t":
448
+ return to_short_time_string(date)
449
+ elif format == "O" or format == "o":
450
+ return date.astimezone().isoformat(timespec="milliseconds")
451
+ else:
452
+ raise Exception("Unrecognized Date print format")
453
+
454
+ else:
455
+ return date_to_string_with_custom_format(date, format, utc)
456
+
457
+
458
+ def to_string(date: datetime, format: str | None = None, provider: Any | None = None) -> str:
459
+ if date.tzinfo:
460
+ return date_to_string_with_offset(date, format)
461
+
462
+ return date_to_string_with_kind(date, format)
463
+
464
+
465
+ def now() -> datetime:
466
+ return datetime.now()
467
+
468
+
469
+ def utc_now() -> datetime:
470
+ return datetime.utcnow()
471
+
472
+
473
+ def today() -> datetime:
474
+ return datetime.replace(now(), hour=0, minute=0, second=0, microsecond=0)
475
+
476
+
477
+ def to_local_time(date: datetime) -> datetime:
478
+ return date.astimezone().replace(tzinfo=local_time_zone)
479
+
480
+
481
+ def compare(x: datetime, y: datetime) -> int:
482
+ if x == y:
483
+ return 0
484
+
485
+ if x < y:
486
+ return -1
487
+
488
+ return 1
489
+
490
+
491
+ def equals(x: datetime, y: datetime) -> bool:
492
+ return x == y
493
+
494
+
495
+ def max_value() -> datetime:
496
+ return datetime.max
497
+
498
+
499
+ def min_value() -> datetime:
500
+ return datetime.min
501
+
502
+
503
+ def op_addition(x: datetime, y: TimeSpan) -> datetime:
504
+ return x + timedelta(microseconds=total_microseconds(y))
505
+
506
+
507
+ def add(x: datetime, y: TimeSpan) -> datetime:
508
+ return op_addition(x, y)
509
+
510
+
511
+ def parse(string: str) -> datetime:
512
+ try:
513
+ return datetime.fromisoformat(string).astimezone()
514
+ except ValueError:
515
+ pass
516
+
517
+ # For the time-only formats, needs a special treatment
518
+ # because in Python, they are set in 1900-01-01 while
519
+ # in F# they are set in the current date
520
+ hoursFormats = {
521
+ # Matches a time string in 24-hour format "HH:MM:SS"
522
+ r"^\d{1,2}:\d{1,2}:\d{2}$": "%H:%M:%S",
523
+ # Matches a time string in 12-hour format with AM/PM "HH:MM:SS AM" or "HH:MM:SS PM"
524
+ r"^(0?[1-9]|1[0-2]):([0-5][1-9]|0?[0-9]):([0-5][0-9]|0?[0-9]) [AP]M$": "%I:%M:%S %p",
525
+ r"^\d{1,2}:\d{1,2}:\d{2} [AP]M$": "%H:%M:%S %p",
526
+ }
527
+
528
+ for pattern, format in hoursFormats.items():
529
+ if re.fullmatch(pattern, string):
530
+ hourDate = datetime.strptime(string, format)
531
+
532
+ # If the hour is 0 PM, then in .NET it is 12 PM (python keeps it as 0)
533
+ hourOffset = 12 if hourDate.hour == 0 and string.endswith(" PM") else 0
534
+
535
+ return datetime.replace(
536
+ now(),
537
+ hour=hourDate.hour + hourOffset,
538
+ minute=hourDate.minute,
539
+ second=hourDate.second,
540
+ microsecond=0,
541
+ )
542
+
543
+ formats = {
544
+ # 9/10/2014 1:50:34 PM
545
+ r"^(0?[1-9]|1[0-2])\/(0?[1-9]|1[0-2])\/\d{4} ([0-9]|(0|1)[0-9]|2[0-4]):([0-5][0-9]|0?[0-9]):([0-5][0-9]|0?[0-9]) [AP]M$": "%m/%d/%Y %I:%M:%S %p",
546
+ # 9/10/2014 1:50:34
547
+ r"^(0?[1-9]|1[0-2])\/(0?[1-9]|1[0-2])\/\d{4} ([0-9]|(0|1)[0-9]|2[0-4]):([0-5][0-9]|0?[0-9]):([0-5][0-9]|0?[0-9])$": "%m/%d/%Y %H:%M:%S",
548
+ }
549
+
550
+ for pattern, format in formats.items():
551
+ if re.fullmatch(pattern, string):
552
+ return datetime.strptime(string, format)
553
+
554
+ # Matches a datetime string in the format "YYYY-MM-DDTHH:MM:SS.ffffff". This format usually parses with
555
+ # `fromisoformat`, but not with Python 3.10
556
+ iso_format_regex = r"(?P<header>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.)(?P<microseconds>\d{0,7})"
557
+
558
+ # In Python %f only supports exactly 6 digits so we need to adapt the string
559
+ # If microseconds has 7 digits, we remove the last one
560
+ # If microseconds has less than 6 digits, we pad it with 0
561
+ def adapt_microseconds(m: re.Match[str]) -> str:
562
+ microseconds = m.group("microseconds")
563
+ header_text = m.group("header")
564
+
565
+ if len(microseconds) == 7:
566
+ microseconds = microseconds[:-1]
567
+
568
+ return header_text + microseconds.ljust(6, "0")
569
+
570
+ if re.fullmatch(iso_format_regex, string):
571
+ adapted_string = re.sub(iso_format_regex, adapt_microseconds, string)
572
+ return datetime.strptime(adapted_string, "%Y-%m-%dT%H:%M:%S.%f")
573
+
574
+ raise ValueError("Unsupported format by Fable: %s" % (string))
575
+
576
+
577
+ def try_parse(string: str, def_value: FSharpRef[datetime]) -> bool:
578
+ try:
579
+ def_value.contents = parse(string)
580
+ return True
581
+ except Exception:
582
+ return False
583
+
584
+
585
+ def date(d: datetime) -> datetime:
586
+ return create(d.year, d.month, d.day, 0, 0, 0, 0, 0, kind(d))
587
+
588
+
589
+ def is_leap_year(year: int) -> bool:
590
+ return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
591
+
592
+
593
+ def days_in_month(year: int, month: int) -> int:
594
+ if month == 2:
595
+ return 29 if is_leap_year(year) else 28
596
+
597
+ if month in (4, 6, 9, 11):
598
+ return 30
599
+
600
+ return 31
601
+
602
+
603
+ def add_years(d: datetime, v: int) -> datetime:
604
+ new_month = month(d)
605
+ new_year = year(d) + v
606
+ _days_in_month = days_in_month(new_year, new_month)
607
+ new_day = min(_days_in_month, day(d))
608
+ return create(new_year, new_month, new_day, hour(d), minute(d), second(d), millisecond(d), microsecond(d), kind(d))
609
+
610
+
611
+ def add_months(d: datetime, v: int) -> datetime:
612
+ new_month = month(d) + v
613
+ new_month_ = 0
614
+ year_offset = 0
615
+ if new_month > 12:
616
+ new_month_ = int(fmod(new_month, 12))
617
+ year_offset = new_month // 12
618
+ new_month = new_month_
619
+ elif new_month < 1:
620
+ new_month_ = 12 + int(fmod(new_month, 12))
621
+ year_offset = new_month // 12 + (-1 if new_month_ == 12 else 0)
622
+ new_month = new_month_
623
+ new_year = year(d) + year_offset
624
+ _days_in_month = days_in_month(new_year, new_month)
625
+ new_day = min(_days_in_month, day(d))
626
+ return create(new_year, new_month, new_day, hour(d), minute(d), second(d), millisecond(d), microsecond(d), kind(d))
627
+
628
+
629
+ def add_days(d: datetime, v: int) -> datetime:
630
+ return d + timedelta(days=v)
631
+
632
+
633
+ def add_hours(d: datetime, v: int) -> datetime:
634
+ return d + timedelta(hours=v)
635
+
636
+
637
+ def add_minutes(d: datetime, v: int) -> datetime:
638
+ return d + timedelta(minutes=v)
639
+
640
+
641
+ def add_seconds(d: datetime, v: int) -> datetime:
642
+ return d + timedelta(seconds=v)
643
+
644
+
645
+ def add_milliseconds(d: datetime, v: int) -> datetime:
646
+ return d + timedelta(milliseconds=v)
647
+
648
+
649
+ def add_microseconds(d: datetime, v: int) -> datetime:
650
+ return d + timedelta(microseconds=v)
651
+
652
+
653
+ def kind(d: datetime) -> DateKind:
654
+ if d.tzinfo == timezone.utc:
655
+ return DateKind.UTC
656
+
657
+ elif d.tzinfo is None:
658
+ return DateKind.Unspecified
659
+
660
+ # Should we check that tzinfo is local_time_zone?
661
+ return DateKind.Local
662
+
663
+
664
+ def specify_kind(d: datetime, kind: DateKind) -> datetime:
665
+ return create(year(d), month(d), day(d), hour(d), minute(d), second(d), millisecond(d), microsecond(d), kind)
666
+
667
+
668
+ def ticks(d: datetime) -> int:
669
+ # Note: It can happens that Ticks differs a little bit from the .NET implementation
670
+ # because of some rounding/precision issues in Python
671
+ # DateTime(1, 1, 1, 0, 0, 0, 0, 99, DateTimeKind.Utc).Ticks should be 990
672
+ # but Python returns 1040
673
+ # because d.timestamp():
674
+ # - returns -62135596799.9999
675
+ # - instead of -62135596800000
676
+ # compute timestamp in microseconds
677
+ return unix_epoch_microseconds_to_ticks(int(d.timestamp() * 1_000_000), date_offset(d) * 1_000)
678
+
679
+
680
+ def unix_epoch_microseconds_to_ticks(us: int, offset: int) -> int:
681
+ return int(((us + 62135596800000000) + offset) * 10)
682
+
683
+
684
+ def ticks_to_unix_epoch_microseconds(ticks: int) -> int:
685
+ return int((ticks - 621355968000000000) // 10)
686
+
687
+
688
+ def date_offset(d: datetime) -> int:
689
+ if d.tzinfo == timezone.utc:
690
+ return 0
691
+ else:
692
+ utc_offset = d.utcoffset()
693
+
694
+ # Is it correct to force an offset to local time
695
+ # for DateKind.Unspecified?
696
+ if utc_offset is None:
697
+ forced_utc_offset = d.astimezone().utcoffset()
698
+ assert forced_utc_offset is not None
699
+ return int(forced_utc_offset.total_seconds() * 1_000)
700
+ else:
701
+ return int(utc_offset.total_seconds() * 1_000)
702
+
703
+ # return 0 if d.tzinfo == timezone.utc else
704
+
705
+
706
+ def create_from_epoch_microseconds(us: int, kind: DateKind | None = None) -> datetime:
707
+ if kind == DateKind.UTC:
708
+ date = datetime.fromtimestamp(us / 1_000_000, timezone.utc)
709
+ else:
710
+ date = datetime.fromtimestamp(us / 1_000_000)
711
+ if kind == DateKind.Local:
712
+ date = date.astimezone()
713
+
714
+ return date
715
+
716
+
717
+ def from_ticks(ticks: int, kind: DateKind | None = None) -> datetime:
718
+ # Better default than Unspecified
719
+ kind = kind or DateKind.Local
720
+ date = create_from_epoch_microseconds(ticks_to_unix_epoch_microseconds(ticks), kind)
721
+
722
+ # Ticks are local to offset (in this case, either UTC or Local/Unknown).
723
+ # If kind is anything but UTC, that means that the tick number was not
724
+ # in utc, thus getTime() cannot return UTC, and needs to be shifted.
725
+ if kind != DateKind.UTC:
726
+ date = create_from_epoch_microseconds(int(date.timestamp() * 1_000_000 - date_offset(date) * 1_000), kind)
727
+
728
+ return date
729
+
730
+
731
+ __all__ = [
732
+ "subtract",
733
+ "op_subtraction",
734
+ "create",
735
+ "year",
736
+ "month",
737
+ "day",
738
+ "hour",
739
+ "minute",
740
+ "second",
741
+ "millisecond",
742
+ "microsecond",
743
+ "to_universal_time",
744
+ "day_of_week",
745
+ "day_of_year",
746
+ "to_short_date_string",
747
+ "to_long_date_string",
748
+ "to_short_time_string",
749
+ "to_long_time_string",
750
+ "to_string",
751
+ "now",
752
+ "utc_now",
753
+ "today",
754
+ "to_local_time",
755
+ "compare",
756
+ "equals",
757
+ "max_value",
758
+ "min_value",
759
+ "op_addition",
760
+ "add",
761
+ "parse",
762
+ "try_parse",
763
+ "date",
764
+ "is_leap_year",
765
+ "days_in_month",
766
+ "add_years",
767
+ "add_months",
768
+ "add_days",
769
+ "add_hours",
770
+ "add_minutes",
771
+ "add_seconds",
772
+ "add_milliseconds",
773
+ "add_microseconds",
774
+ "kind",
775
+ "specify_kind",
776
+ "ticks",
777
+ "date_offset",
778
+ "from_ticks",
779
+ ]