arelle-release 2.17.1__py3-none-any.whl → 2.37.71__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 (893) hide show
  1. arelle/Aspect.py +6 -3
  2. arelle/BetaFeatures.py +3 -0
  3. arelle/Cntlr.py +117 -413
  4. arelle/CntlrCmdLine.py +364 -227
  5. arelle/CntlrQuickBooks.py +4 -2
  6. arelle/CntlrWebMain.py +179 -119
  7. arelle/CntlrWinMain.py +342 -124
  8. arelle/DialogAbout.py +1 -1
  9. arelle/DialogArcroleGroup.py +1 -1
  10. arelle/DialogFind.py +1 -1
  11. arelle/DialogFormulaParameters.py +2 -2
  12. arelle/DialogLanguage.py +45 -36
  13. arelle/DialogNewFactItem.py +1 -1
  14. arelle/DialogOpenArchive.py +30 -34
  15. arelle/DialogPackageManager.py +11 -8
  16. arelle/DialogPluginManager.py +43 -89
  17. arelle/DialogRssWatch.py +2 -2
  18. arelle/DialogURL.py +1 -1
  19. arelle/DialogUserPassword.py +1 -1
  20. arelle/DisclosureSystem.py +69 -1
  21. arelle/ErrorManager.py +321 -0
  22. arelle/FileSource.py +201 -99
  23. arelle/FunctionFn.py +44 -5
  24. arelle/FunctionIxt.py +16 -13
  25. arelle/FunctionUtil.py +1 -1
  26. arelle/FunctionXfi.py +68 -24
  27. arelle/FunctionXs.py +1 -1
  28. arelle/HtmlUtil.py +5 -4
  29. arelle/LeiUtil.py +63 -43
  30. arelle/LinkbaseType.py +94 -0
  31. arelle/LocalViewer.py +8 -2
  32. arelle/Locale.py +239 -79
  33. arelle/ModelDocument.py +180 -48
  34. arelle/ModelDtsObject.py +32 -27
  35. arelle/ModelFormulaObject.py +14 -6
  36. arelle/ModelInstanceObject.py +43 -14
  37. arelle/ModelManager.py +6 -1
  38. arelle/ModelObject.py +12 -8
  39. arelle/ModelObjectFactory.py +18 -2
  40. arelle/ModelRelationshipSet.py +46 -3
  41. arelle/ModelRenderingObject.py +899 -951
  42. arelle/ModelRssItem.py +2 -4
  43. arelle/ModelTestcaseObject.py +41 -4
  44. arelle/ModelValue.py +42 -14
  45. arelle/ModelVersReport.py +1 -1
  46. arelle/ModelXbrl.py +133 -273
  47. arelle/PackageManager.py +202 -176
  48. arelle/PluginManager.py +551 -239
  49. arelle/PluginUtils.py +54 -0
  50. arelle/PrototypeInstanceObject.py +53 -12
  51. arelle/PythonUtil.py +166 -25
  52. arelle/RuntimeOptions.py +32 -18
  53. arelle/SocketUtils.py +3 -0
  54. arelle/SystemInfo.py +1 -1
  55. arelle/TkTableWrapper.py +33 -5
  56. arelle/UITkTable.py +27 -21
  57. arelle/Updater.py +7 -3
  58. arelle/UrlUtil.py +6 -2
  59. arelle/Validate.py +596 -402
  60. arelle/ValidateDuplicateFacts.py +584 -0
  61. arelle/ValidateFileSource.py +38 -0
  62. arelle/ValidateFilingText.py +46 -29
  63. arelle/ValidateInfoset.py +104 -32
  64. arelle/ValidateUtr.py +31 -4
  65. arelle/ValidateXbrl.py +144 -120
  66. arelle/ValidateXbrlCalcs.py +51 -66
  67. arelle/ValidateXbrlDTS.py +98 -29
  68. arelle/Version.py +2 -7
  69. arelle/ViewFile.py +2 -0
  70. arelle/ViewFileDTS.py +7 -2
  71. arelle/ViewFileFactList.py +1 -1
  72. arelle/ViewFileFactTable.py +4 -4
  73. arelle/ViewFileRelationshipSet.py +36 -19
  74. arelle/ViewFileRenderedGrid.py +164 -753
  75. arelle/ViewFileRenderedLayout.py +174 -0
  76. arelle/ViewFileRenderedStructure.py +108 -0
  77. arelle/ViewWinDTS.py +4 -1
  78. arelle/ViewWinFactList.py +1 -1
  79. arelle/ViewWinFactTable.py +1 -1
  80. arelle/ViewWinRelationshipSet.py +14 -8
  81. arelle/ViewWinRenderedGrid.py +397 -287
  82. arelle/ViewWinRssFeed.py +4 -0
  83. arelle/ViewWinTree.py +15 -9
  84. arelle/ViewWinXml.py +1 -1
  85. arelle/WebCache.py +510 -272
  86. arelle/XbrlConst.py +202 -196
  87. arelle/XbrlUtil.py +2 -1
  88. arelle/XhtmlValidate.py +9 -23
  89. arelle/XmlUtil.py +24 -19
  90. arelle/XmlValidate.py +95 -67
  91. arelle/XmlValidateParticles.py +4 -4
  92. arelle/_version.py +33 -3
  93. arelle/api/Session.py +183 -0
  94. arelle/config/creationSoftwareNames.json +24 -10
  95. arelle/config/disclosuresystems.xml +1 -1
  96. arelle/config/disclosuresystems.xsd +3 -0
  97. arelle/config/sbr-text-formatting.xsd +737 -0
  98. arelle/conformance/CSVTestcaseLoader.py +102 -0
  99. arelle/formula/FactAspectsCache.py +10 -4
  100. arelle/formula/ValidateFormula.py +82 -194
  101. arelle/formula/XPathContext.py +42 -28
  102. arelle/formula/XPathParser.py +15 -9
  103. arelle/locale/ar_EG/LC_MESSAGES/ar_EG.po +3 -4
  104. arelle/locale/messages.pot +1 -2
  105. arelle/locale/ru/LC_MESSAGES/ru.po +2 -2
  106. arelle/logging/formatters/LogFormatter.py +47 -0
  107. arelle/logging/handlers/LogHandlerWithXml.py +94 -0
  108. arelle/logging/handlers/LogToBufferHandler.py +20 -0
  109. arelle/logging/handlers/LogToPrintHandler.py +41 -0
  110. arelle/logging/handlers/LogToXmlHandler.py +244 -0
  111. arelle/logging/handlers/StructuredMessageLogHandler.py +74 -0
  112. arelle/model/CommentBase.py +3 -0
  113. arelle/model/ElementBase.py +3 -0
  114. arelle/model/PIBase.py +3 -0
  115. arelle/model/__init__.py +3 -0
  116. arelle/oim/Load.py +2869 -0
  117. arelle/oim/Validate.py +155 -0
  118. arelle/oim/xml/Save.py +21 -0
  119. arelle/packages/PackageConst.py +7 -0
  120. arelle/packages/PackageType.py +13 -0
  121. arelle/packages/PackageUtils.py +22 -0
  122. arelle/packages/PackageValidation.py +200 -0
  123. arelle/packages/report/DetectReportPackage.py +13 -0
  124. arelle/packages/report/ReportPackage.py +265 -0
  125. arelle/packages/report/ReportPackageConst.py +79 -0
  126. arelle/packages/report/ReportPackageValidator.py +207 -0
  127. arelle/plugin/EdgarRendererAllReports.py +12 -12
  128. arelle/plugin/OimTaxonomy/ModelValueMore.py +15 -0
  129. arelle/plugin/OimTaxonomy/ValidateDTS.py +484 -0
  130. arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +239 -0
  131. arelle/plugin/OimTaxonomy/XbrlAbstract.py +16 -0
  132. arelle/plugin/OimTaxonomy/XbrlConcept.py +68 -0
  133. arelle/plugin/OimTaxonomy/XbrlConst.py +261 -0
  134. arelle/plugin/OimTaxonomy/XbrlCube.py +91 -0
  135. arelle/plugin/OimTaxonomy/XbrlDimension.py +38 -0
  136. arelle/plugin/OimTaxonomy/XbrlDts.py +152 -0
  137. arelle/plugin/OimTaxonomy/XbrlEntity.py +16 -0
  138. arelle/plugin/OimTaxonomy/XbrlGroup.py +22 -0
  139. arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +22 -0
  140. arelle/plugin/OimTaxonomy/XbrlLabel.py +31 -0
  141. arelle/plugin/OimTaxonomy/XbrlNetwork.py +100 -0
  142. arelle/plugin/OimTaxonomy/XbrlProperty.py +28 -0
  143. arelle/plugin/OimTaxonomy/XbrlReference.py +33 -0
  144. arelle/plugin/OimTaxonomy/XbrlReport.py +24 -0
  145. arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +35 -0
  146. arelle/plugin/OimTaxonomy/XbrlTaxonomy.py +93 -0
  147. arelle/plugin/OimTaxonomy/XbrlTaxonomyObject.py +154 -0
  148. arelle/plugin/OimTaxonomy/XbrlTransform.py +17 -0
  149. arelle/plugin/OimTaxonomy/XbrlTypes.py +23 -0
  150. arelle/plugin/OimTaxonomy/XbrlUnit.py +17 -0
  151. arelle/plugin/OimTaxonomy/__init__.py +1037 -0
  152. arelle/plugin/OimTaxonomy/resources/iso4217.json +4479 -0
  153. arelle/plugin/OimTaxonomy/resources/oim-taxonomy-schema.json +935 -0
  154. arelle/plugin/OimTaxonomy/resources/ref.json +333 -0
  155. arelle/plugin/OimTaxonomy/resources/transform-types.json +2481 -0
  156. arelle/plugin/OimTaxonomy/resources/types.json +727 -0
  157. arelle/plugin/OimTaxonomy/resources/utr.json +3046 -0
  158. arelle/plugin/OimTaxonomy/resources/xbrlSpec.json +1082 -0
  159. arelle/plugin/formulaLoader.py +3 -3
  160. arelle/plugin/formulaSaver.py +4 -4
  161. arelle/plugin/inlineXbrlDocumentSet.py +331 -102
  162. arelle/plugin/internet/proxyNTLM/HTTPNtlmAuthHandler.py +1 -1
  163. arelle/plugin/loadFromExcel.py +13 -10
  164. arelle/plugin/loadFromOIM.py +16 -3096
  165. arelle/plugin/logging/saveMessages.py +1 -1
  166. arelle/plugin/saveHtmlEBAtables.py +293 -213
  167. arelle/plugin/saveLoadableOIM.py +652 -361
  168. arelle/plugin/saveOIMTaxonomy.py +311 -0
  169. arelle/plugin/streamingExtensions.py +1 -1
  170. arelle/plugin/systemInfo.py +46 -0
  171. arelle/plugin/transforms/tester.py +4 -4
  172. arelle/plugin/validate/CIPC/Const.py +18 -0
  173. arelle/plugin/validate/CIPC/__init__.py +34 -13
  174. arelle/plugin/validate/DBA/DisclosureSystems.py +12 -0
  175. arelle/plugin/validate/DBA/PluginValidationDataExtension.py +165 -0
  176. arelle/plugin/validate/DBA/ValidationPluginExtension.py +545 -0
  177. arelle/plugin/validate/DBA/__init__.py +49 -0
  178. arelle/plugin/validate/DBA/resources/config.xml +21 -0
  179. arelle/plugin/validate/DBA/rules/__init__.py +323 -0
  180. arelle/plugin/validate/DBA/rules/fr.py +1377 -0
  181. arelle/plugin/validate/DBA/rules/tc.py +45 -0
  182. arelle/plugin/validate/DBA/rules/th.py +172 -0
  183. arelle/plugin/validate/DBA/rules/tm.py +351 -0
  184. arelle/plugin/validate/DBA/rules/tr.py +373 -0
  185. arelle/plugin/validate/EBA/__init__.py +11 -12
  186. arelle/plugin/validate/EDINET/Constants.py +208 -0
  187. arelle/plugin/validate/EDINET/ContextRequirement.py +58 -0
  188. arelle/plugin/validate/EDINET/ControllerPluginData.py +298 -0
  189. arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
  190. arelle/plugin/validate/EDINET/DeiRequirements.py +118 -0
  191. arelle/plugin/validate/EDINET/DisclosureSystems.py +1 -0
  192. arelle/plugin/validate/EDINET/FilingFormat.py +275 -0
  193. arelle/plugin/validate/EDINET/FormType.py +134 -0
  194. arelle/plugin/validate/EDINET/ManifestInstance.py +236 -0
  195. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +640 -0
  196. arelle/plugin/validate/EDINET/ReportFolderType.py +162 -0
  197. arelle/plugin/validate/EDINET/Statement.py +139 -0
  198. arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +493 -0
  199. arelle/plugin/validate/EDINET/UploadContents.py +48 -0
  200. arelle/plugin/validate/EDINET/ValidationPluginExtension.py +64 -0
  201. arelle/plugin/validate/EDINET/__init__.py +109 -0
  202. arelle/plugin/validate/EDINET/resources/config.xml +22 -0
  203. arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
  204. arelle/plugin/validate/EDINET/resources/dei-requirements.csv +27 -0
  205. arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +62 -0
  206. arelle/plugin/validate/EDINET/rules/contexts.py +547 -0
  207. arelle/plugin/validate/EDINET/rules/edinet.py +1991 -0
  208. arelle/plugin/validate/EDINET/rules/frta.py +301 -0
  209. arelle/plugin/validate/EDINET/rules/gfm.py +2394 -0
  210. arelle/plugin/validate/EDINET/rules/manifests.py +88 -0
  211. arelle/plugin/validate/EDINET/rules/upload.py +1370 -0
  212. arelle/plugin/validate/ESEF/Const.py +16 -75
  213. arelle/plugin/validate/ESEF/Dimensions.py +2 -2
  214. arelle/plugin/validate/ESEF/ESEF_2021/DTS.py +6 -1
  215. arelle/plugin/validate/ESEF/ESEF_2021/Image.py +7 -4
  216. arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +80 -57
  217. arelle/plugin/validate/ESEF/ESEF_Current/DTS.py +60 -22
  218. arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +272 -133
  219. arelle/plugin/validate/ESEF/Util.py +5 -19
  220. arelle/plugin/validate/ESEF/__init__.py +61 -46
  221. arelle/plugin/validate/ESEF/resources/authority-validations.json +120 -10
  222. arelle/plugin/validate/ESEF/resources/config.xml +44 -3
  223. arelle/plugin/validate/FERC/__init__.py +31 -18
  224. arelle/plugin/validate/FERC/config.xml +18 -18
  225. arelle/plugin/validate/NL/DisclosureSystems.py +19 -3
  226. arelle/plugin/validate/NL/PluginValidationDataExtension.py +710 -7
  227. arelle/plugin/validate/NL/ValidationPluginExtension.py +117 -12
  228. arelle/plugin/validate/NL/__init__.py +21 -10
  229. arelle/plugin/validate/NL/resources/config.xml +27 -6
  230. arelle/plugin/validate/NL/rules/br_kvk.py +81 -21
  231. arelle/plugin/validate/NL/rules/fg_nl.py +292 -0
  232. arelle/plugin/validate/NL/rules/fr_kvk.py +60 -7
  233. arelle/plugin/validate/NL/rules/fr_nl.py +705 -24
  234. arelle/plugin/validate/NL/rules/nl_kvk.py +2182 -0
  235. arelle/plugin/validate/ROS/DisclosureSystems.py +1 -0
  236. arelle/plugin/validate/ROS/PluginValidationDataExtension.py +109 -0
  237. arelle/plugin/validate/ROS/ValidationPluginExtension.py +27 -0
  238. arelle/plugin/validate/ROS/__init__.py +28 -341
  239. arelle/plugin/validate/ROS/resources/config.xml +20 -0
  240. arelle/plugin/validate/ROS/rules/__init__.py +56 -0
  241. arelle/plugin/validate/ROS/rules/ros.py +393 -0
  242. arelle/plugin/validate/UK/ValidateUK.py +1372 -0
  243. arelle/plugin/validate/{HMRC → UK}/__init__.py +195 -189
  244. arelle/plugin/validate/{HMRC → UK}/config.xml +1 -1
  245. arelle/plugin/xbrlDB/SqlDb.py +1 -1
  246. arelle/plugin/xbrlDB/XbrlOpenSqlDB.py +5 -5
  247. arelle/plugin/xbrlDB/XbrlPublicPostgresDB.py +1 -1
  248. arelle/plugin/xbrlDB/XbrlSemanticJsonDB.py +1 -1
  249. arelle/plugin/xbrlDB/XbrlSemanticRdfDB.py +1 -1
  250. arelle/plugin/xbrlDB/__init__.py +4 -1
  251. arelle/{RenderingEvaluator.py → rendering/RenderingEvaluator.py} +120 -99
  252. arelle/rendering/RenderingLayout.py +476 -0
  253. arelle/rendering/RenderingResolution.py +814 -0
  254. arelle/resources/cache/http/www.eurofiling.info/eu/fr/xbrl/ext/filing-indicators.xsd +20 -0
  255. arelle/resources/cache/http/www.w3.org/2001/03/xml.xsd +117 -0
  256. arelle/resources/cache/http/www.w3.org/2001/XMLSchema.xsd +2534 -0
  257. arelle/resources/cache/http/www.w3.org/2001/xml.xsd +287 -0
  258. arelle/resources/cache/http/www.xbrl.org/2003/xbrl-instance-2003-12-31.xsd +779 -0
  259. arelle/resources/cache/http/www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd +486 -0
  260. arelle/resources/cache/http/www.xbrl.org/2003/xl-2003-12-31.xsd +251 -0
  261. arelle/resources/cache/http/www.xbrl.org/2003/xlink-2003-12-31.xsd +121 -0
  262. arelle/resources/cache/http/www.xbrl.org/2004/ref-2004-08-10.xsd +129 -0
  263. arelle/resources/cache/http/www.xbrl.org/2005/xbrldt-2005.xsd +53 -0
  264. arelle/resources/cache/http/www.xbrl.org/2006/ref-2006-02-27.xsd +120 -0
  265. arelle/resources/cache/http/www.xbrl.org/2006/xbrldi-2006.xsd +41 -0
  266. arelle/resources/cache/http/www.xbrl.org/2008/boolean-filter.xsd +51 -0
  267. arelle/resources/cache/http/www.xbrl.org/2008/concept-filter.xsd +127 -0
  268. arelle/resources/cache/http/www.xbrl.org/2008/conformance.xsd +116 -0
  269. arelle/resources/cache/http/www.xbrl.org/2008/conformanceFunction.xsd +51 -0
  270. arelle/resources/cache/http/www.xbrl.org/2008/consistency-assertion.xsd +66 -0
  271. arelle/resources/cache/http/www.xbrl.org/2008/dimension-filter.xsd +86 -0
  272. arelle/resources/cache/http/www.xbrl.org/2008/entity-filter.xsd +92 -0
  273. arelle/resources/cache/http/www.xbrl.org/2008/existence-assertion.xsd +44 -0
  274. arelle/resources/cache/http/www.xbrl.org/2008/formula.xsd +261 -0
  275. arelle/resources/cache/http/www.xbrl.org/2008/function.xsd +90 -0
  276. arelle/resources/cache/http/www.xbrl.org/2008/general-filter.xsd +38 -0
  277. arelle/resources/cache/http/www.xbrl.org/2008/generic-label.xsd +80 -0
  278. arelle/resources/cache/http/www.xbrl.org/2008/generic-link.xsd +81 -0
  279. arelle/resources/cache/http/www.xbrl.org/2008/generic-reference.xsd +63 -0
  280. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
  281. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
  282. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xl-2003-12-31.xsd +248 -0
  283. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xlink-2003-12-31.xsd +117 -0
  284. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xframes-1.xsd +166 -0
  285. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-applet-1.xsd +66 -0
  286. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-attribs-1.xsd +72 -0
  287. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-base-1.xsd +36 -0
  288. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-form-1.xsd +195 -0
  289. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-table-1.xsd +169 -0
  290. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-model-1.xsd +376 -0
  291. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
  292. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-modules-1.xsd +259 -0
  293. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10.xsd +98 -0
  294. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-bdo-1.xsd +78 -0
  295. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkphras-1.xsd +161 -0
  296. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkpres-1.xsd +37 -0
  297. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkstruct-1.xsd +49 -0
  298. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-charent-1.xsd +38 -0
  299. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-copyright-1.xsd +29 -0
  300. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-csismap-1.xsd +96 -0
  301. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-datatypes-1.xsd +128 -0
  302. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-edit-1.xsd +39 -0
  303. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-events-1.xsd +130 -0
  304. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-form-1.xsd +326 -0
  305. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-frames-1.xsd +113 -0
  306. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-framework-1.xsd +66 -0
  307. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-hypertext-1.xsd +47 -0
  308. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-iframe-1.xsd +68 -0
  309. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-image-1.xsd +45 -0
  310. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlphras-1.xsd +163 -0
  311. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlpres-1.xsd +39 -0
  312. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstruct-1.xsd +50 -0
  313. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstyle-1.xsd +27 -0
  314. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-legacy-1.xsd +97 -0
  315. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-link-1.xsd +45 -0
  316. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-list-1.xsd +99 -0
  317. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-meta-1.xsd +42 -0
  318. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-misc-1.xsd +441 -0
  319. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-nameident-1.xsd +63 -0
  320. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-notations-1.xsd +69 -0
  321. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-object-1.xsd +76 -0
  322. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-param-1.xsd +51 -0
  323. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-pres-1.xsd +51 -0
  324. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-1.xsd +171 -0
  325. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-basic-1.xsd +89 -0
  326. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-script-1.xsd +70 -0
  327. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ssismap-1.xsd +43 -0
  328. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-struct-1.xsd +112 -0
  329. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-style-1.xsd +52 -0
  330. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-table-1.xsd +272 -0
  331. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-target-1.xsd +53 -0
  332. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-text-1.xsd +67 -0
  333. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-model-1.xsd +677 -0
  334. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-module-redefines-1.xsd +335 -0
  335. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-modules-1.xsd +528 -0
  336. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11.xsd +104 -0
  337. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml2.xsd +21 -0
  338. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-1.xsd +73 -0
  339. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-2.xsd +74 -0
  340. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-1.xsd +73 -0
  341. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-2.xsd +75 -0
  342. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-1.xsd +34 -0
  343. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-2.xsd +34 -0
  344. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-handlers-2.xsd +98 -0
  345. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-definitions.xsd +225 -0
  346. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-model.xsd +681 -0
  347. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-modules.xsd +535 -0
  348. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0.xsd +40 -0
  349. arelle/resources/cache/http/www.xbrl.org/2008/match-filter.xsd +94 -0
  350. arelle/resources/cache/http/www.xbrl.org/2008/period-filter.xsd +86 -0
  351. arelle/resources/cache/http/www.xbrl.org/2008/registry.xsd +145 -0
  352. arelle/resources/cache/http/www.xbrl.org/2008/relative-filter.xsd +38 -0
  353. arelle/resources/cache/http/www.xbrl.org/2008/segment-scenario-filter.xsd +41 -0
  354. arelle/resources/cache/http/www.xbrl.org/2008/tuple-filter.xsd +83 -0
  355. arelle/resources/cache/http/www.xbrl.org/2008/unit-filter.xsd +58 -0
  356. arelle/resources/cache/http/www.xbrl.org/2008/validation.xsd +78 -0
  357. arelle/resources/cache/http/www.xbrl.org/2008/value-assertion.xsd +43 -0
  358. arelle/resources/cache/http/www.xbrl.org/2008/value-filter.xsd +43 -0
  359. arelle/resources/cache/http/www.xbrl.org/2008/variable.xsd +240 -0
  360. arelle/resources/cache/http/www.xbrl.org/2010/aspect-cover-filter.xsd +67 -0
  361. arelle/resources/cache/http/www.xbrl.org/2010/concept-relation-filter.xsd +108 -0
  362. arelle/resources/cache/http/www.xbrl.org/2010/custom-function-implementation.xsd +71 -0
  363. arelle/resources/cache/http/www.xbrl.org/2010/generic-message.xsd +68 -0
  364. arelle/resources/cache/http/www.xbrl.org/2010/validation-message.xsd +50 -0
  365. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
  366. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
  367. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xl-2003-12-31.xsd +248 -0
  368. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xlink-2003-12-31.xsd +117 -0
  369. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xframes-1.xsd +166 -0
  370. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-applet-1.xsd +66 -0
  371. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-attribs-1.xsd +72 -0
  372. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-base-1.xsd +36 -0
  373. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-form-1.xsd +195 -0
  374. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-table-1.xsd +169 -0
  375. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-model-1.xsd +376 -0
  376. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
  377. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-modules-1.xsd +259 -0
  378. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10.xsd +98 -0
  379. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-bdo-1.xsd +78 -0
  380. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkphras-1.xsd +161 -0
  381. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkpres-1.xsd +37 -0
  382. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkstruct-1.xsd +49 -0
  383. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-charent-1.xsd +38 -0
  384. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-copyright-1.xsd +29 -0
  385. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-csismap-1.xsd +96 -0
  386. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-datatypes-1.xsd +128 -0
  387. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-edit-1.xsd +39 -0
  388. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-events-1.xsd +130 -0
  389. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-form-1.xsd +326 -0
  390. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-frames-1.xsd +113 -0
  391. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-framework-1.xsd +66 -0
  392. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-hypertext-1.xsd +47 -0
  393. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-iframe-1.xsd +68 -0
  394. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-image-1.xsd +45 -0
  395. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlphras-1.xsd +163 -0
  396. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlpres-1.xsd +39 -0
  397. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstruct-1.xsd +50 -0
  398. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstyle-1.xsd +27 -0
  399. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-legacy-1.xsd +97 -0
  400. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-link-1.xsd +45 -0
  401. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-list-1.xsd +99 -0
  402. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-meta-1.xsd +42 -0
  403. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-misc-1.xsd +441 -0
  404. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-nameident-1.xsd +63 -0
  405. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-notations-1.xsd +69 -0
  406. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-object-1.xsd +76 -0
  407. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-param-1.xsd +51 -0
  408. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-pres-1.xsd +51 -0
  409. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-1.xsd +171 -0
  410. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-basic-1.xsd +89 -0
  411. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-script-1.xsd +70 -0
  412. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ssismap-1.xsd +43 -0
  413. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-struct-1.xsd +112 -0
  414. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-style-1.xsd +52 -0
  415. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-table-1.xsd +272 -0
  416. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-target-1.xsd +53 -0
  417. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-text-1.xsd +67 -0
  418. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-model-1.xsd +677 -0
  419. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-module-redefines-1.xsd +335 -0
  420. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-modules-1.xsd +528 -0
  421. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11.xsd +104 -0
  422. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml2.xsd +21 -0
  423. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-1.xsd +73 -0
  424. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-2.xsd +74 -0
  425. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-1.xsd +73 -0
  426. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-2.xsd +75 -0
  427. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-1.xsd +34 -0
  428. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-2.xsd +34 -0
  429. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-handlers-2.xsd +98 -0
  430. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-definitions.xsd +252 -0
  431. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-model.xsd +681 -0
  432. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-modules.xsd +535 -0
  433. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1.xsd +40 -0
  434. arelle/resources/cache/http/www.xbrl.org/2013/match-filter.xsd +94 -0
  435. arelle/resources/cache/http/www.xbrl.org/2013/preferred-label.xsd +12 -0
  436. arelle/resources/cache/http/www.xbrl.org/2013/versioning-base.xsd +142 -0
  437. arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-details.xsd +143 -0
  438. arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-use.xsd +64 -0
  439. arelle/resources/cache/http/www.xbrl.org/2013/versioning-dimensions.xsd +162 -0
  440. arelle/resources/cache/http/www.xbrl.org/2014/extensible-enumerations.xsd +27 -0
  441. arelle/resources/cache/http/www.xbrl.org/2014/table.xsd +356 -0
  442. arelle/resources/cache/http/www.xbrl.org/2014/tablemodel.xsd +156 -0
  443. arelle/resources/cache/http/www.xbrl.org/2016/assertion-severity.xsd +29 -0
  444. arelle/resources/cache/http/www.xbrl.org/2016/severities.xml +21 -0
  445. arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package-catalog.xsd +38 -0
  446. arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package.xsd +154 -0
  447. arelle/resources/cache/http/www.xbrl.org/2022/assertion-severity.xsd +43 -0
  448. arelle/resources/cache/http/www.xbrl.org/2022/severities.xml +21 -0
  449. arelle/resources/cache/http/www.xbrl.org/dtr/type/nonNumeric-2009-12-16.xsd +76 -0
  450. arelle/resources/cache/http/www.xbrl.org/dtr/type/numeric-2009-12-16.xsd +78 -0
  451. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/accounting-arcrole-2023-01-04.xsd +39 -0
  452. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/deprecated-2009-12-16.xsd +29 -0
  453. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/esma-arcrole-2018-11-21.xsd +14 -0
  454. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/factExplanatory-2009-12-16.xsd +13 -0
  455. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/jpfr-arcrole-2007-11-07.xsd +27 -0
  456. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/parent-child-2013-09-19.xsd +12 -0
  457. arelle/resources/cache/http/www.xbrl.org/lrr/role/deprecated-2009-12-16.xsd +17 -0
  458. arelle/resources/cache/http/www.xbrl.org/lrr/role/jpfr-role-2007-11-07.xsd +47 -0
  459. arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2008-03-31.xsd +30 -0
  460. arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2009-12-16.xsd +33 -0
  461. arelle/resources/cache/http/www.xbrl.org/lrr/role/negative-2009-12-16.xsd +25 -0
  462. arelle/resources/cache/http/www.xbrl.org/lrr/role/net-2009-12-16.xsd +13 -0
  463. arelle/resources/cache/http/www.xbrl.org/lrr/role/positive-2009-12-16.xsd +25 -0
  464. arelle/resources/cache/http/www.xbrl.org/lrr/role/property-2022-09-28.xsd +15 -0
  465. arelle/resources/cache/http/www.xbrl.org/lrr/role/reference-2009-12-16.xsd +21 -0
  466. arelle/resources/cache/http/www.xbrl.org/lrr/role/restated-2006-02-21.xsd +19 -0
  467. arelle/resources/cache/http/www.xbrl.org/utr/2012-01-30/utr.xml +4543 -0
  468. arelle/resources/cache/http/www.xbrl.org/utr/2012-10-31/utr.xml +4510 -0
  469. arelle/resources/cache/http/www.xbrl.org/utr/2012-11-30/utr.xml +4567 -0
  470. arelle/resources/cache/http/www.xbrl.org/utr/2013-02-28/utr.xml +5180 -0
  471. arelle/resources/cache/http/www.xbrl.org/utr/2013-05-17/utr.xml +5349 -0
  472. arelle/resources/cache/http/www.xbrl.org/utr/2016-08-10/utr.xml +5363 -0
  473. arelle/resources/cache/http/www.xbrl.org/utr/2017-07-12/utr.xml +6164 -0
  474. arelle/resources/cache/http/www.xbrl.org/utr/2021-02-16/utr.xml +6370 -0
  475. arelle/resources/cache/http/www.xbrl.org/utr/2021-12-08/utr.xml +6493 -0
  476. arelle/resources/cache/http/www.xbrl.org/utr/2022-02-16/utr.xml +6551 -0
  477. arelle/resources/cache/http/www.xbrl.org/utr/2022-07-20/utr.xml +6638 -0
  478. arelle/resources/cache/http/www.xbrl.org/utr/2023-12-20/utr.xml +6680 -0
  479. arelle/resources/cache/http/www.xbrl.org/utr/2024-01-31/utr.xml +6680 -0
  480. arelle/resources/cache/http/www.xbrl.org/utr/2024-10-22/utr.xml +6693 -0
  481. arelle/resources/cache/http/www.xbrl.org/utr/utr.xml +6693 -0
  482. arelle/resources/cache/https/www.xbrl.org/2005/conformance.xsd +87 -0
  483. arelle/resources/cache/https/www.xbrl.org/2020/extensible-enumerations-2.0.xsd +51 -0
  484. arelle/resources/cache/https/www.xbrl.org/2023/calculation-1.1.xsd +27 -0
  485. arelle/resources/cache/https/www.xbrl.org/dtr/type/2020-01-21/types.xsd +812 -0
  486. arelle/resources/cache/https/www.xbrl.org/dtr/type/2022-03-31/types.xsd +847 -0
  487. arelle/resources/cache/https/www.xbrl.org/dtr/type/2024-01-31/types.xsd +897 -0
  488. arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-def.xml +68 -0
  489. arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-label.xml +84 -0
  490. arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators.xsd +67 -0
  491. arelle/resources/libs/Tktable2.11/linux-x86_64/README.txt +149 -0
  492. arelle/resources/libs/Tktable2.11/linux-x86_64/html/tkTable.html +2039 -0
  493. arelle/resources/libs/Tktable2.11/linux-x86_64/libTktable2.11.so +0 -0
  494. arelle/resources/libs/Tktable2.11/linux-x86_64/license.txt +51 -0
  495. arelle/resources/libs/Tktable2.11/linux-x86_64/pkgIndex.tcl +3 -0
  496. arelle/resources/libs/Tktable2.11/linux-x86_64/tkTable.tcl +825 -0
  497. arelle/resources/libs/Tktable2.11/linux-x86_64/tktable.py +674 -0
  498. arelle/resources/libs/Tktable2.11/macos-arm64/README.txt +149 -0
  499. arelle/resources/libs/Tktable2.11/macos-arm64/html/tkTable.html +2039 -0
  500. arelle/resources/libs/Tktable2.11/macos-arm64/libTktable2.11.dylib +0 -0
  501. arelle/resources/libs/Tktable2.11/macos-arm64/license.txt +51 -0
  502. arelle/resources/libs/Tktable2.11/macos-arm64/pkgIndex.tcl +2 -0
  503. arelle/resources/libs/Tktable2.11/macos-arm64/tkTable.tcl +825 -0
  504. arelle/resources/libs/Tktable2.11/macos-arm64/tktable.py +674 -0
  505. arelle/resources/libs/Tktable2.11/macos-x86_64/README.txt +149 -0
  506. arelle/resources/libs/Tktable2.11/macos-x86_64/html/tkTable.html +2039 -0
  507. arelle/resources/libs/Tktable2.11/macos-x86_64/libTktable2.11.dylib +0 -0
  508. arelle/resources/libs/Tktable2.11/macos-x86_64/license.txt +51 -0
  509. arelle/resources/libs/Tktable2.11/macos-x86_64/pkgIndex.tcl +2 -0
  510. arelle/resources/libs/Tktable2.11/macos-x86_64/tkTable.tcl +825 -0
  511. arelle/resources/libs/Tktable2.11/macos-x86_64/tktable.py +674 -0
  512. arelle/resources/libs/Tktable2.11/win-x86_64/Tktable.dll +0 -0
  513. arelle/resources/libs/Tktable2.11/win-x86_64/pkgIndex.tcl +2 -0
  514. arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl +825 -0
  515. arelle/typing.py +9 -4
  516. arelle/utils/Contexts.py +38 -0
  517. arelle/utils/EntryPointDetection.py +139 -0
  518. arelle/utils/Equivalence.py +22 -0
  519. arelle/utils/{validate/PluginValidationData.py → PluginData.py} +5 -2
  520. arelle/utils/PluginHooks.py +256 -5
  521. arelle/utils/Units.py +36 -0
  522. arelle/utils/validate/Decorator.py +5 -3
  523. arelle/utils/validate/DetectScriptsInXhtml.py +99 -0
  524. arelle/utils/validate/ESEFImage.py +283 -0
  525. arelle/utils/validate/Validation.py +9 -1
  526. arelle/utils/validate/ValidationPlugin.py +74 -11
  527. arelle/utils/validate/ValidationUtil.py +55 -0
  528. arelle/webserver/bottle.py +5 -4424
  529. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/METADATA +51 -42
  530. arelle_release-2.37.71.dist-info/RECORD +697 -0
  531. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/WHEEL +1 -1
  532. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info/licenses}/LICENSE.md +1 -4
  533. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/top_level.txt +0 -1
  534. arelle/DialogOpenTaxonomyPackage.py +0 -1
  535. arelle/RenderingResolver.py +0 -624
  536. arelle/examples/.pydevproject +0 -5
  537. arelle/examples/CustomLogger.py +0 -43
  538. arelle/examples/LoadEFMvalidate.py +0 -32
  539. arelle/examples/LoadSavePreLbCsv.py +0 -26
  540. arelle/examples/LoadValidate.cs +0 -31
  541. arelle/examples/LoadValidate.py +0 -36
  542. arelle/examples/LoadValidateCmdLine.java +0 -69
  543. arelle/examples/LoadValidatePostedZip.java +0 -57
  544. arelle/examples/LoadValidateWebService.java +0 -34
  545. arelle/examples/SaveTableToExelle.py +0 -140
  546. arelle/examples/TR3toTR4.py +0 -88
  547. arelle/examples/plugin/bigInstance.py +0 -394
  548. arelle/examples/plugin/cmdWebServerExtension.py +0 -42
  549. arelle/examples/plugin/crashTest.py +0 -38
  550. arelle/examples/plugin/formulaSuiteConverter.py +0 -212
  551. arelle/examples/plugin/functionsCustom.py +0 -59
  552. arelle/examples/plugin/hello_dolly.py +0 -64
  553. arelle/examples/plugin/hello_i18n.pot +0 -26
  554. arelle/examples/plugin/hello_i18n.py +0 -32
  555. arelle/examples/plugin/importTestChild1.py +0 -21
  556. arelle/examples/plugin/importTestChild2.py +0 -22
  557. arelle/examples/plugin/importTestGrandchild1.py +0 -21
  558. arelle/examples/plugin/importTestGrandchild2.py +0 -21
  559. arelle/examples/plugin/importTestImported1.py +0 -23
  560. arelle/examples/plugin/importTestImported11.py +0 -22
  561. arelle/examples/plugin/importTestParent.py +0 -48
  562. arelle/examples/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
  563. arelle/examples/plugin/packagedImportTest/__init__.py +0 -47
  564. arelle/examples/plugin/packagedImportTest/importTestChild1.py +0 -21
  565. arelle/examples/plugin/packagedImportTest/importTestChild2.py +0 -22
  566. arelle/examples/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
  567. arelle/examples/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
  568. arelle/examples/plugin/packagedImportTest/importTestImported1.py +0 -24
  569. arelle/examples/plugin/packagedImportTest/importTestImported11.py +0 -21
  570. arelle/examples/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
  571. arelle/examples/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
  572. arelle/examples/plugin/sakaCalendar.py +0 -215
  573. arelle/examples/plugin/saveInstanceInfoset.py +0 -121
  574. arelle/examples/plugin/streamingExtensions.py +0 -335
  575. arelle/examples/plugin/testcaseCalc11ValidateSetup.py +0 -32
  576. arelle/examples/plugin/testcaseIxExpectedHtmlFixup.py +0 -45
  577. arelle/examples/plugin/updateTableLB.py +0 -242
  578. arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
  579. arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
  580. arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
  581. arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
  582. arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
  583. arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -109
  584. arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -58
  585. arelle/examples/plugin/validateSchemaLxml.py +0 -156
  586. arelle/examples/plugin/validateTableInfoset.py +0 -52
  587. arelle/examples/us-gaap-dei-docType-extraction-frm.xml +0 -90
  588. arelle/examples/us-gaap-dei-ratio-cash-frm.xml +0 -150
  589. arelle/plugin/functionsXmlCreation.py +0 -106
  590. arelle/plugin/instanceInfo.py +0 -306
  591. arelle/plugin/loadFromOIM-2018.py +0 -1282
  592. arelle/plugin/objectmaker.py +0 -285
  593. arelle/plugin/sphinx/FormulaGenerator.py +0 -823
  594. arelle/plugin/sphinx/SphinxContext.py +0 -404
  595. arelle/plugin/sphinx/SphinxEvaluator.py +0 -783
  596. arelle/plugin/sphinx/SphinxMethods.py +0 -1287
  597. arelle/plugin/sphinx/SphinxParser.py +0 -1093
  598. arelle/plugin/sphinx/SphinxValidator.py +0 -163
  599. arelle/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
  600. arelle/plugin/sphinx/__init__.py +0 -285
  601. arelle/plugin/transforms/SEC/__init__.py +0 -308
  602. arelle/plugin/transforms/SEC/conf/README.md +0 -39
  603. arelle/plugin/transforms/SEC/conf/extractTestcase.sh +0 -2
  604. arelle/plugin/transforms/SEC/conf/extractTestcase.xsl +0 -109
  605. arelle/plugin/transforms/SEC/conf/runIxtSecTests.sh +0 -16
  606. arelle/plugin/transforms/SEC/conf/saxon9.jar +0 -0
  607. arelle/plugin/transforms/SEC/conf/testcase.xml +0 -7117
  608. arelle/plugin/transforms/SEC/conf/tests.xml +0 -848
  609. arelle/plugin/transforms/SEC/text2num.py +0 -110
  610. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-boolballotbox.xml +0 -66
  611. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-countrynameen.xml +0 -65
  612. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-datequarterend.xml +0 -66
  613. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durday.xml +0 -61
  614. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durhour.xml +0 -69
  615. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durmonth.xml +0 -71
  616. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durweek.xml +0 -70
  617. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durwordsen.xml +0 -56
  618. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-duryear.xml +0 -64
  619. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-edgarprovcountryen.xml +0 -65
  620. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-entityfilercategoryen.xml +0 -63
  621. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-exchnameen.xml +0 -86
  622. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-numwordsen.xml +0 -55
  623. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-stateprovnameen.xml +0 -64
  624. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-yesnoballotbox.xml +0 -66
  625. arelle/plugin/transforms/SEC/transformationRegistry/registry/transform-registry.xml +0 -314
  626. arelle/plugin/transforms/SEC/transformationRegistry/schema/inlinexbrl-sec-transformation.xsd +0 -418
  627. arelle/plugin/validate/EFM/Consts.py +0 -362
  628. arelle/plugin/validate/EFM/DTS.py +0 -569
  629. arelle/plugin/validate/EFM/Dimensions.py +0 -264
  630. arelle/plugin/validate/EFM/Document.py +0 -206
  631. arelle/plugin/validate/EFM/Filing.py +0 -4383
  632. arelle/plugin/validate/EFM/IsolateSeparateIXDSes.py +0 -19
  633. arelle/plugin/validate/EFM/MessageNumericId.py +0 -142
  634. arelle/plugin/validate/EFM/PreCalAlignment.py +0 -324
  635. arelle/plugin/validate/EFM/Util.py +0 -688
  636. arelle/plugin/validate/EFM/__init__.py +0 -843
  637. arelle/plugin/validate/EFM/config.xml +0 -333
  638. arelle/plugin/validate/EFM/resources/README.md +0 -57
  639. arelle/plugin/validate/EFM/resources/axiswarnings.json +0 -27
  640. arelle/plugin/validate/EFM/resources/cef-deprecated-concepts.json +0 -8
  641. arelle/plugin/validate/EFM/resources/country-deprecated-concepts.json +0 -19
  642. arelle/plugin/validate/EFM/resources/currency-deprecated-concepts.json +0 -7
  643. arelle/plugin/validate/EFM/resources/dei-deprecated-concepts.json +0 -8
  644. arelle/plugin/validate/EFM/resources/dei-validations.json +0 -2884
  645. arelle/plugin/validate/EFM/resources/dqc-us-rules.json +0 -1389
  646. arelle/plugin/validate/EFM/resources/ecd-deprecated-concepts.json +0 -1
  647. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-16-4.xml +0 -115
  648. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-0-4.xml +0 -300
  649. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-1.xml +0 -304
  650. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-2.xml +0 -290
  651. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-3-1.xml +0 -294
  652. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.1.xml +0 -549
  653. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.2.xml +0 -506
  654. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.3.xml +0 -496
  655. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-1.xml +0 -662
  656. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-2.xml +0 -3761
  657. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-3.xml +0 -3577
  658. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-1.xml +0 -4020
  659. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-2.xml +0 -3320
  660. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-3.xml +0 -2998
  661. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2012.xml +0 -957
  662. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2013.xml +0 -982
  663. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2014.xml +0 -1001
  664. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2015.xml +0 -1076
  665. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2016.xml +0 -120
  666. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-1.xml +0 -3329
  667. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-2.xml +0 -1230
  668. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-3.xml +0 -1113
  669. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-4.xml +0 -1321
  670. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1-preview.xml +0 -1721
  671. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1.xml +0 -1841
  672. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2-2.xml +0 -1450
  673. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2.xml +0 -1429
  674. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-4.xml +0 -1527
  675. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1-1.xml +0 -2049
  676. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1.xml +0 -2065
  677. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-2.xml +0 -1674
  678. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-3.xml +0 -1715
  679. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-all-years.xml +0 -10671
  680. arelle/plugin/validate/EFM/resources/edgartaxonomies/erxl.xsd +0 -69
  681. arelle/plugin/validate/EFM/resources/edgartaxonomies/extendedtaxonomies-all-years.xml +0 -18
  682. arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrs-taxonomies.xml +0 -3126
  683. arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrstaxonomies-all-years.xml +0 -22
  684. arelle/plugin/validate/EFM/resources/ex26-validations.json +0 -255
  685. arelle/plugin/validate/EFM/resources/exch-deprecated-concepts.json +0 -163
  686. arelle/plugin/validate/EFM/resources/ifrs-full-deprecated-concepts.json +0 -204
  687. arelle/plugin/validate/EFM/resources/invest-deprecated-concepts.json +0 -99
  688. arelle/plugin/validate/EFM/resources/ixbrl-transform-registries.json +0 -16
  689. arelle/plugin/validate/EFM/resources/naics-deprecated-concepts.json +0 -295
  690. arelle/plugin/validate/EFM/resources/oef-deprecated-concepts.json +0 -59
  691. arelle/plugin/validate/EFM/resources/other-standard-taxonomies.json +0 -12
  692. arelle/plugin/validate/EFM/resources/rr-deprecated-concepts.json +0 -14
  693. arelle/plugin/validate/EFM/resources/rxp-deprecated-concepts.json +0 -1
  694. arelle/plugin/validate/EFM/resources/shr-deprecated-concepts.json +0 -1
  695. arelle/plugin/validate/EFM/resources/sic-deprecated-concepts.json +0 -1
  696. arelle/plugin/validate/EFM/resources/signwarnings.json +0 -112
  697. arelle/plugin/validate/EFM/resources/srt-deprecated-concepts.json +0 -1
  698. arelle/plugin/validate/EFM/resources/stpr-deprecated-concepts.json +0 -1
  699. arelle/plugin/validate/EFM/resources/taxonomy-compatibility.json +0 -79
  700. arelle/plugin/validate/EFM/resources/us-gaap-deprecated-concepts.json +0 -2886
  701. arelle/plugin/validate/EFM/resources/us-gaap-rels-2020.json +0 -29068
  702. arelle/plugin/validate/EFM/resources/us-gaap-rels-2021.json +0 -29598
  703. arelle/plugin/validate/EFM/resources/us-gaap-rels-2022.json +0 -29141
  704. arelle/plugin/validate/EFM/resources/us-gaap-rels-2023.json +0 -29400
  705. arelle/plugin/validate/EFM/resources/vip-deprecated-concepts.json +0 -1
  706. arelle/plugin/validate/EFM/tools/CheckTxmyRefs.py +0 -180
  707. arelle/plugin/validate/EFM-htm/Const.py +0 -205
  708. arelle/plugin/validate/EFM-htm/__init__.py +0 -217
  709. arelle/plugin/validate/EFM-htm/config.xml +0 -17
  710. arelle/plugin/validate/EFM-htm/resources/efm-htm.dtd +0 -664
  711. arelle/plugin/validate/ESEF/ESEF_Current/Image.py +0 -199
  712. arelle/plugin/validate/ESEF_2022/__init__.py +0 -47
  713. arelle/plugin/validate/GFM/__init__.py +0 -59
  714. arelle/plugin/validate/GFM/config.xml +0 -82
  715. arelle/plugin/validate/SBRnl/CustomLoader.py +0 -19
  716. arelle/plugin/validate/SBRnl/DTS.py +0 -305
  717. arelle/plugin/validate/SBRnl/Dimensions.py +0 -357
  718. arelle/plugin/validate/SBRnl/Document.py +0 -799
  719. arelle/plugin/validate/SBRnl/Filing.py +0 -467
  720. arelle/plugin/validate/SBRnl/__init__.py +0 -75
  721. arelle/plugin/validate/SBRnl/config.xml +0 -26
  722. arelle/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
  723. arelle/plugin/validate/USBestPractices.py +0 -570
  724. arelle/plugin/validate/USCorpAction.py +0 -557
  725. arelle/plugin/validate/USSecTagging.py +0 -337
  726. arelle/plugin/validate/XDC/__init__.py +0 -77
  727. arelle/plugin/validate/XDC/config.xml +0 -20
  728. arelle/plugin/validate/XFsyntax/__init__.py +0 -64
  729. arelle/plugin/validate/XFsyntax/xf.py +0 -2227
  730. arelle/plugin/validate/__init__.py +0 -20
  731. arelle/plugin/validate/calc2.py +0 -536
  732. arelle/plugin/validateSBRnl.py +0 -530
  733. arelle/scripts-macOS/startWebServer.command +0 -3
  734. arelle/scripts-unix/startWebServer.sh +0 -1
  735. arelle/scripts-windows/startWebServer.bat +0 -5
  736. arelle_release-2.17.1.dist-info/RECORD +0 -676
  737. tests/__init__.py +0 -0
  738. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj +0 -30
  739. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Tests.cs +0 -381
  740. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Usings.cs +0 -1
  741. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest.sln +0 -31
  742. tests/integration_tests/ui_tests/resources/workiva.zip +0 -0
  743. tests/integration_tests/validation/README.md +0 -50
  744. tests/integration_tests/validation/conformance_suite_config.py +0 -59
  745. tests/integration_tests/validation/conformance_suite_configs.py +0 -63
  746. tests/integration_tests/validation/conformance_suite_configurations/efm_current.py +0 -261
  747. tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2021.py +0 -85
  748. tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2022.py +0 -90
  749. tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2021.py +0 -15
  750. tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2022.py +0 -15
  751. tests/integration_tests/validation/conformance_suite_configurations/nl_nt16.py +0 -13
  752. tests/integration_tests/validation/conformance_suite_configurations/nl_nt17.py +0 -13
  753. tests/integration_tests/validation/conformance_suite_configurations/nl_nt18.py +0 -13
  754. tests/integration_tests/validation/conformance_suite_configurations/xbrl_2_1.py +0 -34
  755. tests/integration_tests/validation/conformance_suite_configurations/xbrl_calculations_1_1.py +0 -40
  756. tests/integration_tests/validation/conformance_suite_configurations/xbrl_dimensions_1_0.py +0 -28
  757. tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_1_0.py +0 -10
  758. tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_2_0.py +0 -10
  759. tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0.py +0 -9
  760. tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_assertion_severity_2_0.py +0 -9
  761. tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_function_registry.py +0 -14
  762. tests/integration_tests/validation/conformance_suite_configurations/xbrl_ixbrl_1_1.py +0 -22
  763. tests/integration_tests/validation/conformance_suite_configurations/xbrl_link_role_registry_1_0.py +0 -11
  764. tests/integration_tests/validation/conformance_suite_configurations/xbrl_oim_1_0.py +0 -19
  765. tests/integration_tests/validation/conformance_suite_configurations/xbrl_table_linkbase_1_0.py +0 -296
  766. tests/integration_tests/validation/conformance_suite_configurations/xbrl_taxonomy_packages_1_0.py +0 -13
  767. tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_3.py +0 -13
  768. tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_4.py +0 -13
  769. tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_5.py +0 -13
  770. tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_malformed_1_0.py +0 -31
  771. tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_registry_1_0.py +0 -22
  772. tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_structure_1_0.py +0 -18
  773. tests/integration_tests/validation/conftest.py +0 -24
  774. tests/integration_tests/validation/discover_tests.py +0 -22
  775. tests/integration_tests/validation/download_conformance_suites.py +0 -47
  776. tests/integration_tests/validation/run_conformance_suites.py +0 -175
  777. tests/integration_tests/validation/test_conformance_suites.py +0 -14
  778. tests/integration_tests/validation/validation_util.py +0 -271
  779. tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-invalid-period.xbrl +0 -63
  780. tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-testcase.xml +0 -22
  781. tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-missing.xbrl +0 -53
  782. tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-multiple.xbrl +0 -60
  783. tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-testcase.xml +0 -33
  784. tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-invalid.xbrl +0 -57
  785. tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-testcase.xml +0 -22
  786. tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-invalid.xbrl +0 -58
  787. tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-testcase.xml +0 -22
  788. tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-invalid.xbrl +0 -63
  789. tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-testcase.xml +0 -22
  790. tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-missing.xbrl +0 -61
  791. tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-testcase.xml +0 -22
  792. tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-invalid-date.xbrl +0 -89
  793. tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-testcase.xml +0 -22
  794. tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-invalid-file-extension.xml +0 -56
  795. tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-testcase.xml +0 -22
  796. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-invalid-lang.xbrl +0 -56
  797. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-missing-lang.xbrl +0 -55
  798. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-testcase.xml +0 -33
  799. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-entrypoint.xsd +0 -6
  800. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
  801. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-testcase.xml +0 -22
  802. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
  803. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-testcase.xml +0 -22
  804. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
  805. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-testcase.xml +0 -22
  806. tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-file.xbrl +0 -2
  807. tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-zip.zip +0 -0
  808. tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-testcase.xml +0 -33
  809. tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-invalid-doctype.xbrl +0 -4
  810. tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-testcase.xml +0 -22
  811. tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-invalid-encoding.xbrl +0 -0
  812. tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-testcase.xml +0 -22
  813. tests/resources/conformance_suites/nl_nt16/fr_nl/1-06-testcase.xml +0 -22
  814. tests/resources/conformance_suites/nl_nt16/fr_nl/1-06.invalid.xbrl +0 -2
  815. tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-file.xbrl +0 -8
  816. tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-zip.zip +0 -0
  817. tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-testcase.xml +0 -33
  818. tests/resources/conformance_suites/nl_nt16/index.xml +0 -20
  819. tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-invalid-period.xbrl +0 -63
  820. tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-testcase.xml +0 -22
  821. tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-missing.xbrl +0 -53
  822. tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-multiple.xbrl +0 -60
  823. tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-testcase.xml +0 -33
  824. tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-invalid.xbrl +0 -57
  825. tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-testcase.xml +0 -22
  826. tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-invalid.xbrl +0 -58
  827. tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-testcase.xml +0 -22
  828. tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-invalid.xbrl +0 -63
  829. tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-testcase.xml +0 -22
  830. tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-missing.xbrl +0 -61
  831. tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-testcase.xml +0 -22
  832. tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-invalid-date.xbrl +0 -89
  833. tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-testcase.xml +0 -22
  834. tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-invalid-file-extension.xml +0 -56
  835. tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-testcase.xml +0 -22
  836. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-invalid-lang.xbrl +0 -56
  837. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-missing-lang.xbrl +0 -55
  838. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-testcase.xml +0 -33
  839. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-entrypoint.xsd +0 -6
  840. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
  841. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-testcase.xml +0 -22
  842. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
  843. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-testcase.xml +0 -22
  844. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
  845. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-testcase.xml +0 -22
  846. tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-file.xbrl +0 -2
  847. tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-zip.zip +0 -0
  848. tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-testcase.xml +0 -33
  849. tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-invalid-doctype.xbrl +0 -4
  850. tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-testcase.xml +0 -22
  851. tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-invalid-encoding.xbrl +0 -0
  852. tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-testcases.xml +0 -22
  853. tests/resources/conformance_suites/nl_nt17/fr_nl/1-06-testcase.xml +0 -22
  854. tests/resources/conformance_suites/nl_nt17/fr_nl/1-06.invalid.xbrl +0 -2
  855. tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-file.xbrl +0 -8
  856. tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-zip.zip +0 -0
  857. tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-testcase.xml +0 -33
  858. tests/resources/conformance_suites/nl_nt17/index.xml +0 -20
  859. tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-invalid-doctype.xbrl +0 -4
  860. tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-testcase.xml +0 -22
  861. tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-invalid-encoding.xbrl +0 -0
  862. tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-testcases.xml +0 -22
  863. tests/resources/conformance_suites/nl_nt18/fr_nl/1-06-testcase.xml +0 -22
  864. tests/resources/conformance_suites/nl_nt18/fr_nl/1-06.invalid.xbrl +0 -2
  865. tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-file.xbrl +0 -2
  866. tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-zip.zip +0 -0
  867. tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-testcase.xml +0 -33
  868. tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-file.xbrl +0 -8
  869. tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-zip.zip +0 -0
  870. tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-testcase.xml +0 -33
  871. tests/resources/conformance_suites/nl_nt18/index.xml +0 -8
  872. tests/unit_tests/arelle/conftest.py +0 -16
  873. tests/unit_tests/arelle/formula/test_fact_aspects_cache.py +0 -170
  874. tests/unit_tests/arelle/plugin/test_loadfromoim.py +0 -40
  875. tests/unit_tests/arelle/plugin/test_plugin_imports.py +0 -27
  876. tests/unit_tests/arelle/test_betafeatures.py +0 -81
  877. tests/unit_tests/arelle/test_cntlr.py +0 -28
  878. tests/unit_tests/arelle/test_import.py +0 -40
  879. tests/unit_tests/arelle/test_locale.py +0 -73
  880. tests/unit_tests/arelle/test_modelmanager.py +0 -15
  881. tests/unit_tests/arelle/test_packagemanager.py +0 -65
  882. tests/unit_tests/arelle/test_pluginmanager.py +0 -176
  883. tests/unit_tests/arelle/test_qname.py +0 -140
  884. tests/unit_tests/arelle/test_runtimeoptions.py +0 -56
  885. tests/unit_tests/arelle/test_system_info.py +0 -26
  886. tests/unit_tests/arelle/test_updater.py +0 -507
  887. tests/unit_tests/arelle/test_urlutil.py +0 -49
  888. tests/unit_tests/arelle/test_version.py +0 -46
  889. tests/unit_tests/arelle/utils/validate/test_decorator.py +0 -59
  890. /arelle/{examples/plugin/validate/XYZ → plugin/validate/EDINET}/rules/__init__.py +0 -0
  891. /arelle/plugin/validate/{HMRC → UK}/consistencyChecksByName.json +0 -0
  892. /arelle/plugin/validate/{HMRC → UK}/hmrc-taxonomies.xml +0 -0
  893. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/entry_points.txt +0 -0
arelle/Validate.py CHANGED
@@ -1,21 +1,32 @@
1
1
  '''
2
2
  See COPYRIGHT.md for copyright information.
3
3
  '''
4
+ import bisect
5
+ import fnmatch
4
6
  import os, sys, traceback, logging
7
+ import time
8
+ from urllib.parse import unquote
9
+ import zipfile
10
+
5
11
  import regex as re
6
12
  from collections import defaultdict, OrderedDict
7
13
  from arelle import (FileSource, ModelXbrl, ModelDocument, ModelVersReport, XbrlConst,
8
14
  ValidateXbrl, ValidateVersReport,
9
- ValidateInfoset, RenderingEvaluator, ViewFileRenderedGrid, UrlUtil)
15
+ ValidateInfoset, ViewFileRenderedLayout, UrlUtil)
16
+ from arelle.PythonUtil import isLegacyAbs
17
+ from arelle.ValidateFileSource import ValidateFileSource
10
18
  from arelle.formula import ValidateFormula
11
19
  from arelle.ModelDocument import Type, ModelDocumentReference, load as modelDocumentLoad
12
20
  from arelle.ModelDtsObject import ModelResource
13
21
  from arelle.ModelInstanceObject import ModelFact
14
22
  from arelle.ModelObject import ModelObject
15
23
  from arelle.ModelRelationshipSet import ModelRelationshipSet
16
- from arelle.ModelTestcaseObject import testcaseVariationsByTarget
24
+ from arelle.ModelTestcaseObject import testcaseVariationsByTarget, ModelTestcaseVariation
17
25
  from arelle.ModelValue import (qname, QName)
18
26
  from arelle.PluginManager import pluginClassMethods
27
+ from arelle.packages.report.DetectReportPackage import isReportPackageExtension
28
+ from arelle.rendering import RenderingEvaluator
29
+ from arelle.utils.EntryPointDetection import filesourceEntrypointFiles
19
30
  from arelle.XmlUtil import collapseWhitespace, xmlstring
20
31
 
21
32
  def validate(modelXbrl):
@@ -52,6 +63,16 @@ class Validate:
52
63
  else:
53
64
  self.useFileSource = None
54
65
 
66
+ def filterTestcaseVariation(self, modelTestcaseVariation: ModelTestcaseVariation):
67
+ patterns = self.modelXbrl.modelManager.formulaOptions.testcaseFilters
68
+ if not patterns:
69
+ return True
70
+ variationIdPath = f'{unquote(modelTestcaseVariation.base)}:{modelTestcaseVariation.id}'
71
+ for pattern in patterns:
72
+ if fnmatch.fnmatch(variationIdPath, pattern):
73
+ return True
74
+ return False
75
+
55
76
  def close(self):
56
77
  self.instValidator.close(reusable=False)
57
78
  self.formulaValidator.close(reusable=False)
@@ -112,7 +133,8 @@ class Validate:
112
133
  self.modelXbrl.error("exception:" + type(err).__name__,
113
134
  _("Instance validation exception: %(error)s, instance: %(instance)s"),
114
135
  modelXbrl=self.modelXbrl,
115
- instance=self.modelXbrl.modelDocument.basename, error=err,
136
+ instance=self.modelXbrl.modelDocument.basename if hasattr(self.modelXbrl, "modelDocument") and hasattr(self.modelXbrl.modelDocument, "basename") else "(closed)",
137
+ error=err,
116
138
  # traceback=traceback.format_tb(sys.exc_info()[2]),
117
139
  exc_info=(type(err) is not AssertionError))
118
140
  self.close()
@@ -121,6 +143,10 @@ class Validate:
121
143
  self.modelXbrl.info("info", "RSS Feed", modelDocument=self.modelXbrl)
122
144
  from arelle.FileSource import openFileSource
123
145
  reloadCache = getattr(self.modelXbrl, "reloadCache", False)
146
+ if self.modelXbrl.modelManager.formulaOptions.testcaseResultsCaptureWarnings:
147
+ errorCaptureLevel = logging._checkLevel("WARNING")
148
+ else:
149
+ errorCaptureLevel = logging._checkLevel("INCONSISTENCY")# default is INCONSISTENCY
124
150
  for rssItem in self.modelXbrl.modelDocument.rssItems:
125
151
  if getattr(rssItem, "skipRssItem", False):
126
152
  self.modelXbrl.info("info", _("skipping RSS Item %(accessionNumber)s %(formType)s %(companyName)s %(period)s"),
@@ -130,9 +156,27 @@ class Validate:
130
156
  modelObject=rssItem, accessionNumber=rssItem.accessionNumber, formType=rssItem.formType, companyName=rssItem.companyName, period=rssItem.period)
131
157
  modelXbrl = None
132
158
  try:
133
- modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
134
- openFileSource(rssItem.zippedUrl, self.modelXbrl.modelManager.cntlr, reloadCache=reloadCache),
135
- _("validating"), rssItem=rssItem)
159
+ rssItemUrl = rssItem.zippedUrl
160
+ if self.useFileSource.isArchive and (isLegacyAbs(rssItemUrl) or not rssItemUrl.endswith(".zip")):
161
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
162
+ openFileSource(rssItemUrl, self.modelXbrl.modelManager.cntlr, reloadCache=reloadCache),
163
+ _("validating"), rssItem=rssItem)
164
+ else: # need own file source, may need instance discovery
165
+ filesource = FileSource.openFileSource(rssItemUrl, self.modelXbrl.modelManager.cntlr)
166
+ if filesource and not filesource.selection and filesource.isArchive:
167
+ try:
168
+ entrypoints = filesourceEntrypointFiles(filesource)
169
+ if entrypoints:
170
+ # resolve an IXDS in entrypoints
171
+ for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
172
+ pluginXbrlMethod(self, filesource,entrypoints)
173
+ filesource.select(entrypoints[0].get("file", None) )
174
+ except Exception as err:
175
+ self.modelXbrl.error("exception:" + type(err).__name__,
176
+ _("RSS item validation exception: %(error)s, entry URL: %(instance)s"),
177
+ modelXbrl=self.modelXbrl, instance=rssItemUrl, error=err)
178
+ continue # don't try to load this entry URL
179
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager, filesource, _("validating"), rssItem=rssItem, errorCaptureLevel=errorCaptureLevel)
136
180
  for pluginXbrlMethod in pluginClassMethods("RssItem.Xbrl.Loaded"):
137
181
  pluginXbrlMethod(modelXbrl, {}, rssItem)
138
182
  if getattr(rssItem, "doNotProcessRSSitem", False) or modelXbrl.modelDocument is None:
@@ -166,377 +210,17 @@ class Validate:
166
210
  for doc in sorted(testcase.referencesDocument.keys(), key=lambda doc: doc.uri):
167
211
  self.validateTestcase(doc) # testcases doc's are sorted by their uri (file names), e.g., for formula
168
212
  elif hasattr(testcase, "testcaseVariations"):
169
- for modelTestcaseVariation in testcaseVariationsByTarget(testcase.testcaseVariations):
170
- # update ui thread via modelManager (running in background here)
171
- self.modelXbrl.modelManager.viewModelObject(self.modelXbrl, modelTestcaseVariation.objectId())
172
- # is this a versioning report?
173
- resultIsVersioningReport = modelTestcaseVariation.resultIsVersioningReport
174
- resultIsXbrlInstance = modelTestcaseVariation.resultIsXbrlInstance
175
- resultIsTaxonomyPackage = modelTestcaseVariation.resultIsTaxonomyPackage
176
- formulaOutputInstance = None
177
- inputDTSes = defaultdict(list)
178
- baseForElement = testcase.baseForElement(modelTestcaseVariation)
179
- # try to load instance document
180
- self.modelXbrl.info("info", _("Variation %(id)s%(name)s%(target)s: %(expected)s - %(description)s"),
181
- modelObject=modelTestcaseVariation,
182
- id=modelTestcaseVariation.id,
183
- name=(" {}".format(modelTestcaseVariation.name) if modelTestcaseVariation.name else ""),
184
- target=(" target {}".format(modelTestcaseVariation.ixdsTarget) if modelTestcaseVariation.ixdsTarget else ""),
185
- expected=modelTestcaseVariation.expected,
186
- description=modelTestcaseVariation.description)
187
- if self.modelXbrl.modelManager.formulaOptions.testcaseResultsCaptureWarnings:
188
- errorCaptureLevel = logging._checkLevel("WARNING")
213
+ testcaseVariations = []
214
+ for testcaseVariation in testcaseVariationsByTarget(testcase.testcaseVariations):
215
+ if self.filterTestcaseVariation(testcaseVariation):
216
+ testcaseVariations.append(testcaseVariation)
189
217
  else:
190
- errorCaptureLevel = modelTestcaseVariation.severityLevel # default is INCONSISTENCY
191
- parameters = modelTestcaseVariation.parameters.copy()
192
- for i, readMeFirstUri in enumerate(modelTestcaseVariation.readMeFirstUris):
193
- readMeFirstElements = modelTestcaseVariation.readMeFirstElements
194
- expectTaxonomyPackage = (i < len(readMeFirstElements) and
195
- readMeFirstElements[i] is not None and
196
- readMeFirstElements[i].qname.localName == "taxonomyPackage")
197
- if isinstance(readMeFirstUri,tuple):
198
- # dtsName is for formula instances, but is from/to dts if versioning
199
- dtsName, readMeFirstUri = readMeFirstUri
200
- elif resultIsVersioningReport:
201
- if inputDTSes: dtsName = "to"
202
- else: dtsName = "from"
203
- else:
204
- dtsName = None
205
- if resultIsVersioningReport and dtsName: # build multi-schemaRef containing document
206
- if dtsName in inputDTSes:
207
- dtsName = inputDTSes[dtsName]
208
- else:
209
- modelXbrl = ModelXbrl.create(self.modelXbrl.modelManager,
210
- Type.DTSENTRIES,
211
- self.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(readMeFirstUri[:-4] + ".dts", baseForElement),
212
- isEntry=True,
213
- errorCaptureLevel=errorCaptureLevel)
214
- DTSdoc = modelXbrl.modelDocument
215
- DTSdoc.inDTS = True
216
- doc = modelDocumentLoad(modelXbrl, readMeFirstUri, base=baseForElement)
217
- if doc is not None:
218
- DTSdoc.referencesDocument[doc] = ModelDocumentReference("import", DTSdoc.xmlRootElement) #fake import
219
- doc.inDTS = True
220
- elif resultIsTaxonomyPackage:
221
- from arelle import PackageManager, PrototypeInstanceObject
222
- dtsName = readMeFirstUri
223
- modelXbrl = PrototypeInstanceObject.XbrlPrototype(self.modelXbrl.modelManager, readMeFirstUri)
224
- PackageManager.packageInfo(self.modelXbrl.modelManager.cntlr, readMeFirstUri, reload=True, errors=modelXbrl.errors)
225
- else: # not a multi-schemaRef versioning report
226
- if self.useFileSource.isArchive and (os.path.isabs(readMeFirstUri) or not readMeFirstUri.endswith(".zip")):
227
- modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
228
- readMeFirstUri,
229
- _("validating"),
230
- base=baseForElement,
231
- useFileSource=self.useFileSource,
232
- errorCaptureLevel=errorCaptureLevel,
233
- ixdsTarget=modelTestcaseVariation.ixdsTarget)
234
- else: # need own file source, may need instance discovery
235
- sourceFileSource = None
236
- newSourceFileSource = False
237
- if (
238
- self.useFileSource
239
- and not os.path.isabs(readMeFirstUri)
240
- and readMeFirstUri.endswith('.zip')
241
- ):
242
- if self.useFileSource.isArchive:
243
- sourceFileSource = self.useFileSource
244
- elif expectTaxonomyPackage:
245
- archiveFilenameParts = FileSource.archiveFilenameParts(baseForElement)
246
- if archiveFilenameParts is not None:
247
- sourceFileSource = FileSource.openFileSource(archiveFilenameParts[0], self.modelXbrl.modelManager.cntlr)
248
- newSourceFileSource = True
249
-
250
- filesource = FileSource.openFileSource(readMeFirstUri, self.modelXbrl.modelManager.cntlr, base=baseForElement,
251
- sourceFileSource=sourceFileSource)
252
- if newSourceFileSource:
253
- sourceFileSource.close()
254
- _errors = [] # accumulate pre-loading errors, such as during taxonomy package loading
255
- if filesource and not filesource.selection and filesource.isArchive:
256
- try:
257
- if filesource.isTaxonomyPackage or expectTaxonomyPackage:
258
- _rptPkgIxdsOptions = {}
259
- for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ReportPackageIxdsOptions"):
260
- pluginXbrlMethod(self, _rptPkgIxdsOptions)
261
- filesource.loadTaxonomyPackageMappings(errors=_errors, expectTaxonomyPackage=expectTaxonomyPackage)
262
- filesource.select(None) # must select loadable reports (not the taxonomy package itself)
263
- for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ReportPackageIxds"):
264
- filesource.select(pluginXbrlMethod(filesource, **_rptPkgIxdsOptions))
265
- else:
266
- from arelle.CntlrCmdLine import filesourceEntrypointFiles
267
- entrypoints = filesourceEntrypointFiles(filesource)
268
- if entrypoints:
269
- # resolve an IXDS in entrypoints
270
- for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
271
- pluginXbrlMethod(self, filesource,entrypoints)
272
- filesource.select(entrypoints[0].get("file", None) )
273
- except Exception as err:
274
- self.modelXbrl.error("exception:" + type(err).__name__,
275
- _("Testcase variation validation exception: %(error)s, entry URL: %(instance)s"),
276
- modelXbrl=self.modelXbrl, instance=readMeFirstUri, error=err)
277
- continue # don't try to load this entry URL
278
- modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
279
- filesource,
280
- _("validating"),
281
- base=baseForElement,
282
- errorCaptureLevel=errorCaptureLevel,
283
- ixdsTarget=modelTestcaseVariation.ixdsTarget,
284
- isLoadable=modelTestcaseVariation.variationDiscoversDTS or filesource.url,
285
- errors=_errors)
286
- modelXbrl.isTestcaseVariation = True
287
- if not modelTestcaseVariation.variationDiscoversDTS and modelXbrl.modelDocument is None: # e.g., taxonomyPackage test
288
- self.determineTestStatus(modelTestcaseVariation, modelXbrl.errors)
289
- modelXbrl.close()
290
- elif modelXbrl.modelDocument is None:
291
- modelXbrl.info("arelle:notLoaded",
292
- _("Variation %(id)s %(name)s readMeFirst document not loaded: %(file)s"),
293
- modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name, file=os.path.basename(readMeFirstUri))
294
- self.determineNotLoadedTestStatus(modelTestcaseVariation, modelXbrl.errors)
295
- modelXbrl.close()
296
- elif resultIsVersioningReport or resultIsTaxonomyPackage:
297
- inputDTSes[dtsName] = modelXbrl
298
- elif modelXbrl.modelDocument.type == Type.VERSIONINGREPORT:
299
- ValidateVersReport.ValidateVersReport(self.modelXbrl).validate(modelXbrl)
300
- self.determineTestStatus(modelTestcaseVariation, modelXbrl.errors)
301
- modelXbrl.close()
302
- elif testcase.type == Type.REGISTRYTESTCASE:
303
- self.instValidator.validate(modelXbrl) # required to set up dimensions, etc
304
- self.instValidator.executeCallTest(modelXbrl, modelTestcaseVariation.id,
305
- modelTestcaseVariation.cfcnCall, modelTestcaseVariation.cfcnTest)
306
- self.determineTestStatus(modelTestcaseVariation, modelXbrl.errors)
307
- self.instValidator.close()
308
- modelXbrl.close()
309
- else:
310
- inputDTSes[dtsName].append(modelXbrl)
311
- # validate except for formulas
312
- _hasFormulae = modelXbrl.hasFormulae
313
- modelXbrl.hasFormulae = False
314
- try:
315
- for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Xbrl.Loaded"):
316
- pluginXbrlMethod(self.modelXbrl, modelXbrl, modelTestcaseVariation)
317
- self.instValidator.validate(modelXbrl, parameters)
318
- for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Xbrl.Validated"):
319
- pluginXbrlMethod(self.modelXbrl, modelXbrl)
320
- except Exception as err:
321
- modelXbrl.error("exception:" + type(err).__name__,
322
- _("Testcase variation validation exception: %(error)s, instance: %(instance)s"),
323
- modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=(type(err) is not AssertionError))
324
- modelXbrl.hasFormulae = _hasFormulae
325
- if resultIsVersioningReport and modelXbrl.modelDocument:
326
- versReportFile = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(
327
- modelTestcaseVariation.versioningReportUri, baseForElement)
328
- if os.path.exists(versReportFile): #validate existing
329
- modelVersReport = ModelXbrl.load(self.modelXbrl.modelManager, versReportFile, _("validating existing version report"))
330
- if modelVersReport and modelVersReport.modelDocument and modelVersReport.modelDocument.type == Type.VERSIONINGREPORT:
331
- ValidateVersReport.ValidateVersReport(self.modelXbrl).validate(modelVersReport)
332
- self.determineTestStatus(modelTestcaseVariation, modelVersReport.errors)
333
- modelVersReport.close()
334
- elif len(inputDTSes) == 2:
335
- ModelVersReport.ModelVersReport(self.modelXbrl).diffDTSes(
336
- versReportFile, inputDTSes["from"], inputDTSes["to"])
337
- modelTestcaseVariation.status = "generated"
338
- else:
339
- modelXbrl.error("arelle:notLoaded",
340
- _("Variation %(id)s %(name)s input DTSes not loaded, unable to generate versioning report: %(file)s"),
341
- modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name, file=os.path.basename(readMeFirstUri))
342
- modelTestcaseVariation.status = "failed"
343
- for inputDTS in inputDTSes.values():
344
- inputDTS.close()
345
- del inputDTSes # dereference
346
- elif resultIsTaxonomyPackage:
347
- self.determineTestStatus(modelTestcaseVariation, modelXbrl.errors)
348
- modelXbrl.close()
349
- elif inputDTSes:
350
- # validate schema, linkbase, or instance
351
- modelXbrl = inputDTSes[None][0]
352
- expectedDataFiles = set(modelXbrl.modelManager.cntlr.webCache.normalizeUrl(uri, baseForElement)
353
- for d in modelTestcaseVariation.dataUris.values() for uri in d
354
- if not UrlUtil.isAbsolute(uri))
355
- foundDataFiles = set()
356
- variationBase = os.path.dirname(baseForElement)
357
- for dtsName, inputDTS in inputDTSes.items(): # input instances are also parameters
358
- if dtsName: # named instance
359
- parameters[dtsName] = (None, inputDTS) #inputDTS is a list of modelXbrl's (instance DTSes)
360
- elif len(inputDTS) > 1: # standard-input-instance with multiple instance documents
361
- parameters[XbrlConst.qnStandardInputInstance] = (None, inputDTS) # allow error detection in validateFormula
362
- for _inputDTS in inputDTS:
363
- for docUrl, doc in _inputDTS.urlDocs.items():
364
- if docUrl.startswith(variationBase) and not doc.type == Type.INLINEXBRLDOCUMENTSET:
365
- if getattr(doc,"loadedFromXbrlFormula", False): # may have been sourced from xf file
366
- if docUrl.replace("-formula.xml", ".xf") in expectedDataFiles:
367
- docUrl = docUrl.replace("-formula.xml", ".xf")
368
- foundDataFiles.add(docUrl)
369
- if expectedDataFiles - foundDataFiles:
370
- modelXbrl.info("arelle:testcaseDataNotUsed",
371
- _("Variation %(id)s %(name)s data files not used: %(missingDataFiles)s"),
372
- modelObject=modelTestcaseVariation, name=modelTestcaseVariation.name, id=modelTestcaseVariation.id,
373
- missingDataFiles=", ".join(sorted(os.path.basename(f) for f in expectedDataFiles - foundDataFiles)))
374
- if foundDataFiles - expectedDataFiles:
375
- modelXbrl.info("arelle:testcaseDataUnexpected",
376
- _("Variation %(id)s %(name)s files not in variation data: %(unexpectedDataFiles)s"),
377
- modelObject=modelTestcaseVariation, name=modelTestcaseVariation.name, id=modelTestcaseVariation.id,
378
- unexpectedDataFiles=", ".join(sorted(os.path.basename(f) for f in foundDataFiles - expectedDataFiles)))
379
- if modelXbrl.hasTableRendering or modelTestcaseVariation.resultIsTable:
380
- try:
381
- RenderingEvaluator.init(modelXbrl)
382
- except Exception as err:
383
- modelXbrl.error("exception:" + type(err).__name__,
384
- _("Testcase RenderingEvaluator.init exception: %(error)s, instance: %(instance)s"),
385
- modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=True)
386
- modelXbrlHasFormulae = modelXbrl.hasFormulae
387
- if modelXbrlHasFormulae and self.modelXbrl.modelManager.formulaOptions.formulaAction != "none":
388
- try:
389
- # validate only formulae
390
- self.instValidator.parameters = parameters
391
- ValidateFormula.validate(self.instValidator)
392
- except Exception as err:
393
- modelXbrl.error("exception:" + type(err).__name__,
394
- _("Testcase formula variation validation exception: %(error)s, instance: %(instance)s"),
395
- modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=(type(err) is not AssertionError))
396
- if modelTestcaseVariation.resultIsInfoset and self.modelXbrl.modelManager.validateInfoset:
397
- for pluginXbrlMethod in pluginClassMethods("Validate.Infoset"):
398
- pluginXbrlMethod(modelXbrl, modelTestcaseVariation.resultInfosetUri)
399
- infoset = ModelXbrl.load(self.modelXbrl.modelManager,
400
- modelTestcaseVariation.resultInfosetUri,
401
- _("loading result infoset"),
402
- base=baseForElement,
403
- useFileSource=self.useFileSource,
404
- errorCaptureLevel=errorCaptureLevel)
405
- if infoset.modelDocument is None:
406
- modelXbrl.error("arelle:notLoaded",
407
- _("Variation %(id)s %(name)s result infoset not loaded: %(file)s"),
408
- modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name,
409
- file=os.path.basename(modelTestcaseVariation.resultXbrlInstance))
410
- modelTestcaseVariation.status = "result infoset not loadable"
411
- else: # check infoset
412
- ValidateInfoset.validate(self.instValidator, modelXbrl, infoset)
413
- infoset.close()
414
- if modelXbrl.hasTableRendering or modelTestcaseVariation.resultIsTable: # and self.modelXbrl.modelManager.validateInfoset:
415
- # diff (or generate) table infoset
416
- resultTableUri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(modelTestcaseVariation.resultTableUri, baseForElement)
417
- if not any(alternativeValidation(modelXbrl, resultTableUri)
418
- for alternativeValidation in pluginClassMethods("Validate.TableInfoset")):
419
- try:
420
- ViewFileRenderedGrid.viewRenderedGrid(modelXbrl, resultTableUri, diffToFile=True) # false to save infoset files
421
- except Exception as err:
422
- modelXbrl.error("exception:" + type(err).__name__,
423
- _("Testcase table linkbase validation exception: %(error)s, instance: %(instance)s"),
424
- modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=True)
425
- self.instValidator.close()
426
- extraErrors = []
427
- for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Validated"):
428
- pluginXbrlMethod(self.modelXbrl, modelXbrl, extraErrors, inputDTSes)
429
- self.determineTestStatus(modelTestcaseVariation, [e for inputDTSlist in inputDTSes.values() for inputDTS in inputDTSlist for e in inputDTS.errors] + extraErrors) # include infoset errors in status
430
- if modelXbrl.formulaOutputInstance and self.noErrorCodes(modelTestcaseVariation.actual):
431
- # if an output instance is created, and no string error codes, ignoring dict of assertion results, validate it
432
- modelXbrl.formulaOutputInstance.hasFormulae = False # block formulae on output instance (so assertion of input is not lost)
433
- self.instValidator.validate(modelXbrl.formulaOutputInstance, modelTestcaseVariation.parameters)
434
- self.determineTestStatus(modelTestcaseVariation, modelXbrl.formulaOutputInstance.errors)
435
- if self.noErrorCodes(modelTestcaseVariation.actual): # if still 'clean' pass it forward for comparison to expected result instance
436
- formulaOutputInstance = modelXbrl.formulaOutputInstance
437
- modelXbrl.formulaOutputInstance = None # prevent it from being closed now
438
- self.instValidator.close()
439
- compareIxResultInstance = (modelXbrl.modelDocument.type in (Type.INLINEXBRL, Type.INLINEXBRLDOCUMENTSET) and
440
- modelTestcaseVariation.resultXbrlInstanceUri is not None)
441
- if compareIxResultInstance:
442
- formulaOutputInstance = modelXbrl # compare modelXbrl to generated output instance
443
- errMsgPrefix = "ix"
444
- else: # delete input instances before formula output comparision
445
- for inputDTSlist in inputDTSes.values():
446
- for inputDTS in inputDTSlist:
447
- inputDTS.close()
448
- del inputDTSes # dereference
449
- errMsgPrefix = "formula"
450
- if resultIsXbrlInstance and formulaOutputInstance and formulaOutputInstance.modelDocument:
451
- _matchExpectedResultIDs = not modelXbrlHasFormulae # formula restuls have inconsistent IDs
452
- expectedInstance = ModelXbrl.load(self.modelXbrl.modelManager,
453
- modelTestcaseVariation.resultXbrlInstanceUri,
454
- _("loading expected result XBRL instance"),
455
- base=baseForElement,
456
- useFileSource=self.useFileSource,
457
- errorCaptureLevel=errorCaptureLevel)
458
- if expectedInstance.modelDocument is None:
459
- self.modelXbrl.error("{}:expectedResultNotLoaded".format(errMsgPrefix),
460
- _("Testcase \"%(name)s\" %(id)s expected result instance not loaded: %(file)s"),
461
- modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name,
462
- file=os.path.basename(modelTestcaseVariation.resultXbrlInstanceUri),
463
- messageCodes=("formula:expectedResultNotLoaded","ix:expectedResultNotLoaded"))
464
- modelTestcaseVariation.status = "result not loadable"
465
- else: # compare facts
466
- for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.ExpectedInstance.Loaded"):
467
- pluginXbrlMethod(expectedInstance, formulaOutputInstance)
468
- if len(expectedInstance.facts) != len(formulaOutputInstance.facts):
469
- formulaOutputInstance.error("{}:resultFactCounts".format(errMsgPrefix),
470
- _("Formula output %(countFacts)s facts, expected %(expectedFacts)s facts"),
471
- modelXbrl=modelXbrl, countFacts=len(formulaOutputInstance.facts),
472
- expectedFacts=len(expectedInstance.facts),
473
- messageCodes=("formula:resultFactCounts","ix:resultFactCounts"))
474
- else:
475
- formulaOutputFootnotesRelSet = ModelRelationshipSet(formulaOutputInstance, "XBRL-footnotes")
476
- expectedFootnotesRelSet = ModelRelationshipSet(expectedInstance, "XBRL-footnotes")
477
- def factFootnotes(fact, footnotesRelSet):
478
- footnotes = {}
479
- footnoteRels = footnotesRelSet.fromModelObject(fact)
480
- if footnoteRels:
481
- # most process rels in same order between two instances, use labels to sort
482
- for i, footnoteRel in enumerate(sorted(footnoteRels,
483
- key=lambda r: (r.fromLabel,r.toLabel))):
484
- modelObject = footnoteRel.toModelObject
485
- if isinstance(modelObject, ModelResource):
486
- xml = collapseWhitespace(modelObject.viewText().strip())
487
- footnotes["Footnote {}".format(i+1)] = xml #re.sub(r'\s+', ' ', collapseWhitespace(modelObject.stringValue))
488
- elif isinstance(modelObject, ModelFact):
489
- footnotes["Footnoted fact {}".format(i+1)] = \
490
- "{} context: {} value: {}".format(
491
- modelObject.qname,
492
- modelObject.contextID,
493
- collapseWhitespace(modelObject.value))
494
- return footnotes
495
- for expectedInstanceFact in expectedInstance.facts:
496
- unmatchedFactsStack = []
497
- formulaOutputFact = formulaOutputInstance.matchFact(expectedInstanceFact, unmatchedFactsStack, deemP0inf=True, matchId=_matchExpectedResultIDs, matchLang=False)
498
- #formulaOutputFact = formulaOutputInstance.matchFact(expectedInstanceFact, unmatchedFactsStack, deemP0inf=True, matchId=True, matchLang=True)
499
- if formulaOutputFact is None:
500
- if unmatchedFactsStack: # get missing nested tuple fact, if possible
501
- missingFact = unmatchedFactsStack[-1]
502
- else:
503
- missingFact = expectedInstanceFact
504
- # is it possible to show value mismatches?
505
- expectedFacts = formulaOutputInstance.factsByQname.get(missingFact.qname)
506
- if expectedFacts and len(expectedFacts) == 1:
507
- formulaOutputInstance.error("{}:expectedFactMissing".format(errMsgPrefix),
508
- _("Output missing expected fact %(fact)s, extracted value \"%(value1)s\", expected value \"%(value2)s\""),
509
- modelXbrl=missingFact, fact=missingFact.qname, value1=missingFact.xValue, value2=next(iter(expectedFacts)).xValue,
510
- messageCodes=("formula:expectedFactMissing","ix:expectedFactMissing"))
511
- else:
512
- formulaOutputInstance.error("{}:expectedFactMissing".format(errMsgPrefix),
513
- _("Output missing expected fact %(fact)s"),
514
- modelXbrl=missingFact, fact=missingFact.qname,
515
- messageCodes=("formula:expectedFactMissing","ix:expectedFactMissing"))
516
- else: # compare footnotes
517
- expectedInstanceFactFootnotes = factFootnotes(expectedInstanceFact, expectedFootnotesRelSet)
518
- formulaOutputFactFootnotes = factFootnotes(formulaOutputFact, formulaOutputFootnotesRelSet)
519
- if (len(expectedInstanceFactFootnotes) != len(formulaOutputFactFootnotes) or
520
- set(expectedInstanceFactFootnotes.values()) != set(formulaOutputFactFootnotes.values())):
521
- formulaOutputInstance.error("{}:expectedFactFootnoteDifference".format(errMsgPrefix),
522
- _("Output expected fact %(fact)s expected footnotes %(footnotes1)s produced footnotes %(footnotes2)s"),
523
- modelXbrl=(formulaOutputFact,expectedInstanceFact), fact=expectedInstanceFact.qname, footnotes1=sorted(expectedInstanceFactFootnotes.items()), footnotes2=sorted(formulaOutputFactFootnotes.items()),
524
- messageCodes=("formula:expectedFactFootnoteDifference","ix:expectedFactFootnoteDifference"))
525
-
526
- # for debugging uncomment next line to save generated instance document
527
- # formulaOutputInstance.saveInstance(r"c:\temp\test-out-inst.xml")
528
- expectedInstance.close()
529
- del expectedInstance # dereference
530
- self.determineTestStatus(modelTestcaseVariation, formulaOutputInstance.errors)
531
- formulaOutputInstance.close()
532
- del formulaOutputInstance
533
- if compareIxResultInstance:
534
- for inputDTSlist in inputDTSes.values():
535
- for inputDTS in inputDTSlist:
536
- inputDTS.close()
537
- del inputDTSes # dereference
538
- # update ui thread via modelManager (running in background here)
539
- self.modelXbrl.modelManager.viewModelObject(self.modelXbrl, modelTestcaseVariation.objectId())
218
+ testcaseVariation.status = 'skip'
219
+ self.modelXbrl.info("info", "Skipped testcase variation %(variationId)s.",
220
+ modelObject=testcaseVariation,
221
+ variationId=testcaseVariation.id)
222
+ for modelTestcaseVariation in testcaseVariations:
223
+ self._validateTestcaseVariation(testcase, modelTestcaseVariation)
540
224
 
541
225
  _statusCounts = OrderedDict((("pass",0),("fail",0)))
542
226
  for tv in getattr(testcase, "testcaseVariations", ()):
@@ -545,22 +229,538 @@ class Validate:
545
229
 
546
230
  self.modelXbrl.modelManager.showStatus(_("ready"), 2000)
547
231
 
232
+ def _validateTestcaseVariation(self, testcase, modelTestcaseVariation):
233
+ # update ui thread via modelManager (running in background here)
234
+ startTime = time.perf_counter()
235
+ self.modelXbrl.modelManager.viewModelObject(self.modelXbrl, modelTestcaseVariation.objectId())
236
+ # is this a versioning report?
237
+ resultIsVersioningReport = modelTestcaseVariation.resultIsVersioningReport
238
+ resultIsXbrlInstance = modelTestcaseVariation.resultIsXbrlInstance
239
+ resultIsTaxonomyPackage = modelTestcaseVariation.resultIsTaxonomyPackage
240
+ inputDTSes = defaultdict(list)
241
+ baseForElement = testcase.baseForElement(modelTestcaseVariation)
242
+ # try to load instance document
243
+ self.modelXbrl.info("info", _("Variation %(id)s%(name)s%(target)s: %(expected)s - %(description)s"),
244
+ modelObject=modelTestcaseVariation,
245
+ id=modelTestcaseVariation.id,
246
+ name=(" {}".format(modelTestcaseVariation.name) if modelTestcaseVariation.name else ""),
247
+ target=(" target {}".format(modelTestcaseVariation.ixdsTarget) if modelTestcaseVariation.ixdsTarget else ""),
248
+ expected=modelTestcaseVariation.expected,
249
+ description=modelTestcaseVariation.description)
250
+ if self.modelXbrl.modelManager.formulaOptions.testcaseResultsCaptureWarnings:
251
+ errorCaptureLevel = logging._checkLevel("WARNING")
252
+ else:
253
+ errorCaptureLevel = modelTestcaseVariation.severityLevel # default is INCONSISTENCY
254
+ parameters = modelTestcaseVariation.parameters.copy()
255
+ loadedModels = []
256
+ for i, readMeFirstUri in enumerate(modelTestcaseVariation.readMeFirstUris):
257
+ loadedModels.extend(self._testcaseLoadReadMeFirstUri(
258
+ testcase=testcase,
259
+ modelTestcaseVariation=modelTestcaseVariation,
260
+ index=i,
261
+ readMeFirstUri=readMeFirstUri,
262
+ resultIsVersioningReport=resultIsVersioningReport,
263
+ resultIsTaxonomyPackage=resultIsTaxonomyPackage,
264
+ inputDTSes=inputDTSes,
265
+ errorCaptureLevel=errorCaptureLevel,
266
+ baseForElement=baseForElement,
267
+ parameters=parameters,
268
+ ))
269
+ validateInputDTS = False
270
+ for modelXbrl in loadedModels:
271
+ if resultIsVersioningReport and modelXbrl.modelDocument:
272
+ versReportFile = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(
273
+ modelTestcaseVariation.versioningReportUri, baseForElement)
274
+ if os.path.exists(versReportFile): #validate existing
275
+ modelVersReport = ModelXbrl.load(self.modelXbrl.modelManager, versReportFile, _("validating existing version report"))
276
+ if modelVersReport and modelVersReport.modelDocument and modelVersReport.modelDocument.type == Type.VERSIONINGREPORT:
277
+ ValidateVersReport.ValidateVersReport(self.modelXbrl).validate(modelVersReport)
278
+ self.determineTestStatus(modelTestcaseVariation, modelVersReport.errors)
279
+ modelVersReport.close()
280
+ elif len(inputDTSes) == 2:
281
+ ModelVersReport.ModelVersReport(self.modelXbrl).diffDTSes(
282
+ versReportFile, inputDTSes["from"], inputDTSes["to"])
283
+ modelTestcaseVariation.status = "generated"
284
+ else:
285
+ modelXbrl.error("arelle:notLoaded",
286
+ _("Variation %(id)s %(name)s input DTSes not loaded, unable to generate versioning report: %(file)s"),
287
+ modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name, file=os.path.basename(readMeFirstUri))
288
+ modelTestcaseVariation.status = "failed"
289
+ elif resultIsTaxonomyPackage:
290
+ self.determineTestStatus(modelTestcaseVariation, modelXbrl.errors)
291
+ modelXbrl.close()
292
+ elif inputDTSes:
293
+ validateInputDTS = True
294
+ if validateInputDTS:
295
+ self._testcaseValidateInputDTS(testcase, modelTestcaseVariation, errorCaptureLevel, parameters, inputDTSes, baseForElement, resultIsXbrlInstance)
296
+ # update ui thread via modelManager (running in background here)
297
+ self.modelXbrl.modelManager.viewModelObject(self.modelXbrl, modelTestcaseVariation.objectId())
298
+ self.modelXbrl.modelManager.cntlr.testcaseVariationReset()
299
+ modelTestcaseVariation.duration = time.perf_counter() - startTime
300
+
301
+ def _testcaseLoadReadMeFirstUri(self, testcase, modelTestcaseVariation, index, readMeFirstUri, resultIsVersioningReport, resultIsTaxonomyPackage, inputDTSes, errorCaptureLevel, baseForElement, parameters):
302
+ preLoadingErrors = [] # accumulate pre-loading errors, such as during taxonomy package loading
303
+ loadedModels = []
304
+ filesource = None
305
+ readMeFirstElements = modelTestcaseVariation.readMeFirstElements
306
+ expectTaxonomyPackage = (index < len(readMeFirstElements) and
307
+ readMeFirstElements[index] is not None and
308
+ readMeFirstElements[index].qname.localName == "taxonomyPackage")
309
+ if isinstance(readMeFirstUri,tuple):
310
+ # dtsName is for formula instances, but is from/to dts if versioning
311
+ dtsName, readMeFirstUri = readMeFirstUri
312
+ elif resultIsVersioningReport:
313
+ if inputDTSes: dtsName = "to"
314
+ else: dtsName = "from"
315
+ else:
316
+ dtsName = None
317
+ if resultIsVersioningReport and dtsName: # build multi-schemaRef containing document
318
+ if dtsName in inputDTSes:
319
+ dtsName = inputDTSes[dtsName]
320
+ else:
321
+ modelXbrl = ModelXbrl.create(self.modelXbrl.modelManager,
322
+ Type.DTSENTRIES,
323
+ self.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(readMeFirstUri[:-4] + ".dts", baseForElement),
324
+ isEntry=True,
325
+ errorCaptureLevel=errorCaptureLevel)
326
+ loadedModels.append(modelXbrl)
327
+ DTSdoc = modelXbrl.modelDocument
328
+ DTSdoc.inDTS = True
329
+ doc = modelDocumentLoad(modelXbrl, readMeFirstUri, base=baseForElement)
330
+ if doc is not None:
331
+ DTSdoc.referencesDocument[doc] = ModelDocumentReference("import", DTSdoc.xmlRootElement) #fake import
332
+ doc.inDTS = True
333
+ elif resultIsTaxonomyPackage:
334
+ from arelle import PackageManager, PrototypeInstanceObject
335
+ dtsName = readMeFirstUri
336
+ modelXbrl = PrototypeInstanceObject.XbrlPrototype(self.modelXbrl.modelManager, readMeFirstUri)
337
+ loadedModels.append(modelXbrl)
338
+ PackageManager.packageInfo(self.modelXbrl.modelManager.cntlr, readMeFirstUri, reload=True, errors=modelXbrl.errors)
339
+ else: # not a multi-schemaRef versioning report
340
+ readMeFirstUriIsArchive = isReportPackageExtension(readMeFirstUri)
341
+ readMeFirstUriIsEmbeddedZipFile = False
342
+ if self.useFileSource.isArchive and not isLegacyAbs(readMeFirstUri):
343
+ if readMeFirstUriIsArchive:
344
+ readMeFirstUriIsEmbeddedZipFile = True
345
+ else:
346
+ normalizedReadMeFirstUri = self.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(readMeFirstUri, baseForElement)
347
+ archivePath = FileSource.archiveFilenameParts(normalizedReadMeFirstUri)
348
+ if archivePath:
349
+ with self.useFileSource.fs.open(archivePath[1]) as embeddedFile:
350
+ readMeFirstUriIsArchive = readMeFirstUriIsEmbeddedZipFile = zipfile.is_zipfile(embeddedFile)
351
+ if not readMeFirstUriIsArchive:
352
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
353
+ readMeFirstUri,
354
+ _("validating"),
355
+ base=baseForElement,
356
+ useFileSource=self.useFileSource,
357
+ errorCaptureLevel=errorCaptureLevel,
358
+ ixdsTarget=modelTestcaseVariation.ixdsTarget)
359
+ loadedModels.append(modelXbrl)
360
+ else: # need own file source, may need instance discovery
361
+ sourceFileSource = None
362
+ newSourceFileSource = False
363
+ if (
364
+ self.useFileSource
365
+ and not isLegacyAbs(readMeFirstUri)
366
+ and (readMeFirstUriIsEmbeddedZipFile or isReportPackageExtension(readMeFirstUri))
367
+ ):
368
+ if self.useFileSource.isArchive:
369
+ sourceFileSource = self.useFileSource
370
+ elif expectTaxonomyPackage:
371
+ archiveFilenameParts = FileSource.archiveFilenameParts(baseForElement)
372
+ if archiveFilenameParts is not None:
373
+ sourceFileSource = FileSource.openFileSource(archiveFilenameParts[0], self.modelXbrl.modelManager.cntlr)
374
+ newSourceFileSource = True
375
+
376
+ filesource = FileSource.openFileSource(readMeFirstUri, self.modelXbrl.modelManager.cntlr, base=baseForElement,
377
+ sourceFileSource=sourceFileSource)
378
+ if filesource.isReportPackage:
379
+ expectTaxonomyPackage = filesource.isTaxonomyPackage
380
+
381
+ if newSourceFileSource:
382
+ sourceFileSource.close()
383
+ _rptPkgIxdsOptions = {}
384
+ for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ReportPackageIxdsOptions"):
385
+ pluginXbrlMethod(self, _rptPkgIxdsOptions)
386
+ reportPackageErrors = False
387
+ if (filesource.isReportPackage or self.modelXbrl.modelManager.validateAllFilesAsReportPackages) and not _rptPkgIxdsOptions:
388
+ preLoadingErrorsCount = len(preLoadingErrors)
389
+ fileSourceValidator = ValidateFileSource(self.modelXbrl.modelManager.cntlr, filesource)
390
+ fileSourceValidator.validate(self.modelXbrl.modelManager.validateAllFilesAsReportPackages, preLoadingErrors)
391
+ if len(preLoadingErrors) > preLoadingErrorsCount:
392
+ reportPackageErrors = True
393
+ if filesource and not filesource.selection and filesource.isArchive:
394
+ try:
395
+ if filesource.isTaxonomyPackage or expectTaxonomyPackage:
396
+ filesource.loadTaxonomyPackageMappings(errors=preLoadingErrors, expectTaxonomyPackage=expectTaxonomyPackage)
397
+ filesource.select(None) # must select loadable reports (not the taxonomy package itself)
398
+ elif not filesource.isReportPackage:
399
+ entrypoints = filesourceEntrypointFiles(filesource)
400
+ fileSourceValidator = ValidateFileSource(self.modelXbrl.modelManager.cntlr, filesource)
401
+ fileSourceValidator.validate(self.modelXbrl.modelManager.validateAllFilesAsReportPackages, preLoadingErrors)
402
+ if entrypoints:
403
+ # resolve an IXDS in entrypoints
404
+ for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
405
+ pluginXbrlMethod(self, filesource,entrypoints)
406
+ for entrypoint in entrypoints:
407
+ filesource.select(entrypoint.get("file", None))
408
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
409
+ filesource,
410
+ _("validating"),
411
+ base=filesource.basefile + "/",
412
+ errorCaptureLevel=errorCaptureLevel,
413
+ ixdsTarget=modelTestcaseVariation.ixdsTarget,
414
+ errors=preLoadingErrors)
415
+ loadedModels.append(modelXbrl)
416
+ except Exception as err:
417
+ self.modelXbrl.error("exception:" + type(err).__name__,
418
+ _("Testcase variation validation exception: %(error)s, entry URL: %(instance)s"),
419
+ modelXbrl=self.modelXbrl, instance=readMeFirstUri, error=err)
420
+ return [] # don't try to load this entry URL
421
+ if filesource and filesource.isReportPackage and not _rptPkgIxdsOptions:
422
+ if not reportPackageErrors:
423
+ assert isinstance(filesource.basefile, str)
424
+ if entrypoints := filesourceEntrypointFiles(filesource):
425
+ fileSourceValidator = ValidateFileSource(self.modelXbrl.modelManager.cntlr, filesource)
426
+ fileSourceValidator.validate(self.modelXbrl.modelManager.validateAllFilesAsReportPackages, preLoadingErrors)
427
+ for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
428
+ pluginXbrlMethod(self, filesource, entrypoints)
429
+ for entrypoint in entrypoints:
430
+ filesource.select(entrypoint.get("file", None))
431
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
432
+ filesource,
433
+ _("validating"),
434
+ base=filesource.basefile + "/",
435
+ errorCaptureLevel=errorCaptureLevel,
436
+ ixdsTarget=modelTestcaseVariation.ixdsTarget,
437
+ errors=preLoadingErrors)
438
+ loadedModels.append(modelXbrl)
439
+ else:
440
+ if _rptPkgIxdsOptions and filesource.isTaxonomyPackage:
441
+ # Legacy ESEF conformance suite logic.
442
+ for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ReportPackageIxds"):
443
+ filesource.select(pluginXbrlMethod(filesource, **_rptPkgIxdsOptions))
444
+ if len(loadedModels) == 0:
445
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
446
+ filesource,
447
+ _("validating"),
448
+ base=baseForElement,
449
+ errorCaptureLevel=errorCaptureLevel,
450
+ ixdsTarget=modelTestcaseVariation.ixdsTarget,
451
+ isLoadable=modelTestcaseVariation.variationDiscoversDTS or filesource.url,
452
+ errors=preLoadingErrors)
453
+ loadedModels.append(modelXbrl)
454
+
455
+ for model in loadedModels:
456
+ modelXbrl.isTestcaseVariation = True
457
+ if model.modelDocument is None:
458
+ if modelTestcaseVariation.expected not in ("EFM.6.03.04", "EFM.6.03.05"):
459
+ level = "ERROR" if modelTestcaseVariation.variationDiscoversDTS else "INFO"
460
+ model.log(
461
+ level,
462
+ "arelle:notLoaded",
463
+ _("Variation %(id)s %(name)s readMeFirst document not loaded: %(file)s"),
464
+ modelXbrl=testcase,
465
+ id=modelTestcaseVariation.id,
466
+ name=modelTestcaseVariation.name,
467
+ file=os.path.basename(readMeFirstUri),
468
+ )
469
+ elif resultIsVersioningReport or resultIsTaxonomyPackage:
470
+ inputDTSes['dtsName'].append(model)
471
+ elif model.modelDocument.type == Type.VERSIONINGREPORT:
472
+ ValidateVersReport.ValidateVersReport(self.modelXbrl).validate(model)
473
+ elif testcase.type == Type.REGISTRYTESTCASE:
474
+ self.instValidator.validate(model) # required to set up dimensions, etc
475
+ self.instValidator.executeCallTest(model, modelTestcaseVariation.id,
476
+ modelTestcaseVariation.cfcnCall, modelTestcaseVariation.cfcnTest)
477
+ self.instValidator.close()
478
+ else:
479
+ inputDTSes[dtsName].append(model)
480
+ # validate except for formulas
481
+ _hasFormulae = model.hasFormulae
482
+ model.hasFormulae = False
483
+ try:
484
+ for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Xbrl.Loaded"):
485
+ pluginXbrlMethod(self.modelXbrl, model, modelTestcaseVariation)
486
+ self.instValidator.validate(model, parameters)
487
+ for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Xbrl.Validated"):
488
+ pluginXbrlMethod(self.modelXbrl, model)
489
+ except Exception as err:
490
+ model.error("exception:" + type(err).__name__,
491
+ _("Testcase variation validation exception: %(error)s, instance: %(instance)s"),
492
+ modelXbrl=model, instance=model.modelDocument.basename, error=err, exc_info=(type(err) is not AssertionError))
493
+ model.hasFormulae = _hasFormulae
494
+ for pluginXbrlMethod in pluginClassMethods("Validate.Complete"):
495
+ pluginXbrlMethod(self.modelXbrl.modelManager.cntlr, filesource)
496
+ errors = [error for model in loadedModels for error in model.errors]
497
+ for err in preLoadingErrors:
498
+ if err not in errors:
499
+ # include errors from models which failed to load.
500
+ errors.append(err)
501
+ reportModelCount = len([
502
+ model for model in loadedModels
503
+ if model.modelDocument is not None and (model.fileSource.isReportPackage or not model.fileSource.isTaxonomyPackage)
504
+ ])
505
+ self.determineTestStatus(modelTestcaseVariation, errors, validateModelCount=reportModelCount)
506
+ if not inputDTSes:
507
+ for model in loadedModels:
508
+ model.close()
509
+ return loadedModels
510
+
511
+ def _testcaseValidateInputDTS(self, testcase, modelTestcaseVariation, errorCaptureLevel, parameters, inputDTSes, baseForElement, resultIsXbrlInstance):
512
+ # validate schema, linkbase, or instance
513
+ formulaOutputInstance = None
514
+ modelXbrl = inputDTSes[None][0]
515
+ expectedDataFiles = set()
516
+ expectedTaxonomyPackages = []
517
+ for localName, d in modelTestcaseVariation.dataUris.items():
518
+ for uri in d:
519
+ if not UrlUtil.isAbsolute(uri):
520
+ normalizedUri = self.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(uri, baseForElement)
521
+ if localName == "taxonomyPackage":
522
+ expectedTaxonomyPackages.append(normalizedUri)
523
+ else:
524
+ expectedDataFiles.add(normalizedUri)
525
+ expectedTaxonomyPackages.sort()
526
+ foundDataFiles = set()
527
+ variationBase = os.path.dirname(baseForElement)
528
+ for dtsName, inputDTS in inputDTSes.items(): # input instances are also parameters
529
+ if dtsName: # named instance
530
+ parameters[dtsName] = (None, inputDTS) #inputDTS is a list of modelXbrl's (instance DTSes)
531
+ elif len(inputDTS) > 1: # standard-input-instance with multiple instance documents
532
+ parameters[XbrlConst.qnStandardInputInstance] = (None, inputDTS) # allow error detection in validateFormula
533
+ for _inputDTS in inputDTS:
534
+ for docUrl, doc in _inputDTS.urlDocs.items():
535
+ if docUrl.startswith(variationBase) and not doc.type == Type.INLINEXBRLDOCUMENTSET:
536
+ if getattr(doc,"loadedFromXbrlFormula", False): # may have been sourced from xf file
537
+ if docUrl.replace("-formula.xml", ".xf") in expectedDataFiles:
538
+ docUrl = docUrl.replace("-formula.xml", ".xf")
539
+ foundDataFiles.add(docUrl)
540
+
541
+ foundDataFilesInTaxonomyPackages = set()
542
+ foundTaxonomyPackages = set()
543
+ for f in foundDataFiles:
544
+ if i := bisect.bisect(expectedTaxonomyPackages, f):
545
+ package = expectedTaxonomyPackages[i-1]
546
+ if f.startswith(package + "/"):
547
+ foundDataFilesInTaxonomyPackages.add(f)
548
+ foundTaxonomyPackages.add(package)
549
+
550
+ expectedNotFound = expectedDataFiles.union(expectedTaxonomyPackages) - foundDataFiles - foundTaxonomyPackages
551
+ if expectedNotFound:
552
+ modelXbrl.info("arelle:testcaseDataNotUsed",
553
+ _("Variation %(id)s %(name)s data files not used: %(missingDataFiles)s"),
554
+ modelObject=modelTestcaseVariation, name=modelTestcaseVariation.name, id=modelTestcaseVariation.id,
555
+ missingDataFiles=", ".join(sorted(os.path.basename(f) for f in expectedNotFound)))
556
+ foundNotExpected = foundDataFiles - expectedDataFiles - foundDataFilesInTaxonomyPackages
557
+ if foundNotExpected:
558
+ modelXbrl.info("arelle:testcaseDataUnexpected",
559
+ _("Variation %(id)s %(name)s files not in variation data: %(unexpectedDataFiles)s"),
560
+ modelObject=modelTestcaseVariation, name=modelTestcaseVariation.name, id=modelTestcaseVariation.id,
561
+ unexpectedDataFiles=", ".join(sorted(os.path.basename(f) for f in foundNotExpected)))
562
+ if modelXbrl.hasTableRendering or modelTestcaseVariation.resultIsTable:
563
+ try:
564
+ RenderingEvaluator.init(modelXbrl)
565
+ except Exception as err:
566
+ modelXbrl.error("exception:" + type(err).__name__,
567
+ _("Testcase RenderingEvaluator.init exception: %(error)s, instance: %(instance)s"),
568
+ modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=True)
569
+ modelXbrlHasFormulae = modelXbrl.hasFormulae
570
+ if modelXbrlHasFormulae and self.modelXbrl.modelManager.formulaOptions.formulaAction != "none":
571
+ try:
572
+ # validate only formulae
573
+ self.instValidator.parameters = parameters
574
+ ValidateFormula.validate(self.instValidator)
575
+ except Exception as err:
576
+ modelXbrl.error("exception:" + type(err).__name__,
577
+ _("Testcase formula variation validation exception: %(error)s, instance: %(instance)s"),
578
+ modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=(type(err) is not AssertionError))
579
+ if modelTestcaseVariation.resultIsInfoset and self.modelXbrl.modelManager.validateInfoset:
580
+ for pluginXbrlMethod in pluginClassMethods("Validate.Infoset"):
581
+ pluginXbrlMethod(modelXbrl, modelTestcaseVariation.resultInfosetUri)
582
+ infoset = ModelXbrl.load(self.modelXbrl.modelManager,
583
+ modelTestcaseVariation.resultInfosetUri,
584
+ _("loading result infoset"),
585
+ base=baseForElement,
586
+ useFileSource=self.useFileSource,
587
+ errorCaptureLevel=errorCaptureLevel)
588
+ if infoset.modelDocument is None:
589
+ modelXbrl.error("arelle:notLoaded",
590
+ _("Variation %(id)s %(name)s result infoset not loaded: %(file)s"),
591
+ modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name,
592
+ file=os.path.basename(modelTestcaseVariation.resultXbrlInstance))
593
+ modelTestcaseVariation.status = "result infoset not loadable"
594
+ else: # check infoset
595
+ ValidateInfoset.validate(self.instValidator, modelXbrl, infoset)
596
+ infoset.close()
597
+ if modelXbrl.hasTableRendering or modelTestcaseVariation.resultIsTable: # and self.modelXbrl.modelManager.validateInfoset:
598
+ # diff (or generate) table infoset
599
+ resultTableUri = modelXbrl.modelManager.cntlr.webCache.normalizeUrl(modelTestcaseVariation.resultTableUri, baseForElement)
600
+ if not any(alternativeValidation(modelXbrl, resultTableUri)
601
+ for alternativeValidation in pluginClassMethods("Validate.TableInfoset")):
602
+ try:
603
+ ViewFileRenderedLayout.viewRenderedLayout(modelXbrl, resultTableUri, diffToFile=True) # false to save infoset files
604
+ except Exception as err:
605
+ modelXbrl.error("exception:" + type(err).__name__,
606
+ _("Testcase table linkbase validation exception: %(error)s, instance: %(instance)s"),
607
+ modelXbrl=modelXbrl, instance=modelXbrl.modelDocument.basename, error=err, exc_info=True)
608
+ self.instValidator.close()
609
+ extraErrors = []
610
+ for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Validated"):
611
+ pluginXbrlMethod(self.modelXbrl, modelXbrl, extraErrors, inputDTSes)
612
+ self.determineTestStatus(modelTestcaseVariation, [e for inputDTSlist in inputDTSes.values() for inputDTS in inputDTSlist for e in inputDTS.errors] + extraErrors) # include infoset errors in status
613
+ if modelXbrl.formulaOutputInstance and self.noErrorCodes(modelTestcaseVariation.actual):
614
+ # if an output instance is created, and no string error codes, ignoring dict of assertion results, validate it
615
+ modelXbrl.formulaOutputInstance.hasFormulae = False # block formulae on output instance (so assertion of input is not lost)
616
+ self.instValidator.validate(modelXbrl.formulaOutputInstance, modelTestcaseVariation.parameters)
617
+ self.determineTestStatus(modelTestcaseVariation, modelXbrl.formulaOutputInstance.errors)
618
+ if self.noErrorCodes(modelTestcaseVariation.actual): # if still 'clean' pass it forward for comparison to expected result instance
619
+ formulaOutputInstance = modelXbrl.formulaOutputInstance
620
+ modelXbrl.formulaOutputInstance = None # prevent it from being closed now
621
+ self.instValidator.close()
622
+ compareIxResultInstance = (modelXbrl.modelDocument.type in (Type.INLINEXBRL, Type.INLINEXBRLDOCUMENTSET) and
623
+ modelTestcaseVariation.resultXbrlInstanceUri is not None)
624
+ if compareIxResultInstance:
625
+ formulaOutputInstance = modelXbrl # compare modelXbrl to generated output instance
626
+ errMsgPrefix = "ix"
627
+ else: # delete input instances before formula output comparision
628
+ for inputDTSlist in inputDTSes.values():
629
+ for inputDTS in inputDTSlist:
630
+ inputDTS.close()
631
+ del inputDTSes # dereference
632
+ errMsgPrefix = "formula"
633
+ if resultIsXbrlInstance and formulaOutputInstance and formulaOutputInstance.modelDocument:
634
+ _matchExpectedResultIDs = not modelXbrlHasFormulae # formula restuls have inconsistent IDs
635
+ expectedInstance = ModelXbrl.load(self.modelXbrl.modelManager,
636
+ modelTestcaseVariation.resultXbrlInstanceUri,
637
+ _("loading expected result XBRL instance"),
638
+ base=baseForElement,
639
+ useFileSource=self.useFileSource,
640
+ errorCaptureLevel=errorCaptureLevel)
641
+ if expectedInstance.modelDocument is None:
642
+ self.modelXbrl.error("{}:expectedResultNotLoaded".format(errMsgPrefix),
643
+ _("Testcase \"%(name)s\" %(id)s expected result instance not loaded: %(file)s"),
644
+ modelXbrl=testcase, id=modelTestcaseVariation.id, name=modelTestcaseVariation.name,
645
+ file=os.path.basename(modelTestcaseVariation.resultXbrlInstanceUri),
646
+ messageCodes=("formula:expectedResultNotLoaded","ix:expectedResultNotLoaded"))
647
+ modelTestcaseVariation.status = "result not loadable"
648
+ else: # compare facts
649
+ for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.ExpectedInstance.Loaded"):
650
+ pluginXbrlMethod(expectedInstance, formulaOutputInstance)
651
+ if len(expectedInstance.facts) != len(formulaOutputInstance.facts):
652
+ formulaOutputInstance.error("{}:resultFactCounts".format(errMsgPrefix),
653
+ _("Formula output %(countFacts)s facts, expected %(expectedFacts)s facts"),
654
+ modelXbrl=modelXbrl, countFacts=len(formulaOutputInstance.facts),
655
+ expectedFacts=len(expectedInstance.facts),
656
+ messageCodes=("formula:resultFactCounts","ix:resultFactCounts"))
657
+ else:
658
+ formulaOutputFootnotesRelSet = ModelRelationshipSet(formulaOutputInstance, "XBRL-footnotes")
659
+ expectedFootnotesRelSet = ModelRelationshipSet(expectedInstance, "XBRL-footnotes")
660
+ def factFootnotes(fact, footnotesRelSet):
661
+ footnotes = {}
662
+ footnoteRels = footnotesRelSet.fromModelObject(fact)
663
+ if footnoteRels:
664
+ # most process rels in same order between two instances, use labels to sort
665
+ for i, footnoteRel in enumerate(sorted(footnoteRels,
666
+ key=lambda r: (r.fromLabel,r.toLabel))):
667
+ modelObject = footnoteRel.toModelObject
668
+ if isinstance(modelObject, ModelResource):
669
+ xml = collapseWhitespace(modelObject.viewText().strip())
670
+ footnotes["Footnote {}".format(i+1)] = xml #re.sub(r'\s+', ' ', collapseWhitespace(modelObject.stringValue))
671
+ elif isinstance(modelObject, ModelFact):
672
+ footnotes["Footnoted fact {}".format(i+1)] = \
673
+ "{} context: {} value: {}".format(
674
+ modelObject.qname,
675
+ modelObject.contextID,
676
+ collapseWhitespace(modelObject.value))
677
+ return footnotes
678
+ for expectedInstanceFact in expectedInstance.facts:
679
+ unmatchedFactsStack = []
680
+ formulaOutputFact = formulaOutputInstance.matchFact(expectedInstanceFact, unmatchedFactsStack, deemP0inf=True, matchId=_matchExpectedResultIDs, matchLang=False)
681
+ #formulaOutputFact = formulaOutputInstance.matchFact(expectedInstanceFact, unmatchedFactsStack, deemP0inf=True, matchId=True, matchLang=True)
682
+ if formulaOutputFact is None:
683
+ if unmatchedFactsStack: # get missing nested tuple fact, if possible
684
+ missingFact = unmatchedFactsStack[-1]
685
+ else:
686
+ missingFact = expectedInstanceFact
687
+ # is it possible to show value mismatches?
688
+ expectedFacts = formulaOutputInstance.factsByQname.get(missingFact.qname)
689
+ if expectedFacts and len(expectedFacts) == 1:
690
+ formulaOutputInstance.error("{}:expectedFactMissing".format(errMsgPrefix),
691
+ _("Output missing expected fact %(fact)s, extracted value \"%(value1)s\", expected value \"%(value2)s\""),
692
+ modelXbrl=missingFact, fact=missingFact.qname, value1=missingFact.xValue, value2=next(iter(expectedFacts)).xValue,
693
+ messageCodes=("formula:expectedFactMissing","ix:expectedFactMissing"))
694
+ else:
695
+ formulaOutputInstance.error("{}:expectedFactMissing".format(errMsgPrefix),
696
+ _("Output missing expected fact %(fact)s"),
697
+ modelXbrl=missingFact, fact=missingFact.qname,
698
+ messageCodes=("formula:expectedFactMissing","ix:expectedFactMissing"))
699
+ else: # compare footnotes
700
+ expectedInstanceFactFootnotes = factFootnotes(expectedInstanceFact, expectedFootnotesRelSet)
701
+ formulaOutputFactFootnotes = factFootnotes(formulaOutputFact, formulaOutputFootnotesRelSet)
702
+ if (len(expectedInstanceFactFootnotes) != len(formulaOutputFactFootnotes) or
703
+ set(expectedInstanceFactFootnotes.values()) != set(formulaOutputFactFootnotes.values())):
704
+ formulaOutputInstance.error("{}:expectedFactFootnoteDifference".format(errMsgPrefix),
705
+ _("Output expected fact %(fact)s expected footnotes %(footnotes1)s produced footnotes %(footnotes2)s"),
706
+ modelXbrl=(formulaOutputFact,expectedInstanceFact), fact=expectedInstanceFact.qname, footnotes1=sorted(expectedInstanceFactFootnotes.items()), footnotes2=sorted(formulaOutputFactFootnotes.items()),
707
+ messageCodes=("formula:expectedFactFootnoteDifference","ix:expectedFactFootnoteDifference"))
708
+
709
+ # for debugging uncomment next line to save generated instance document
710
+ # formulaOutputInstance.saveInstance(r"c:\temp\test-out-inst.xml")
711
+ expectedInstance.close()
712
+ del expectedInstance # dereference
713
+ self.determineTestStatus(modelTestcaseVariation, formulaOutputInstance.errors)
714
+ formulaOutputInstance.close()
715
+ del formulaOutputInstance
716
+ if compareIxResultInstance:
717
+ for inputDTSlist in inputDTSes.values():
718
+ for inputDTS in inputDTSlist:
719
+ inputDTS.close()
720
+ del inputDTSes # dereference
721
+
548
722
  def noErrorCodes(self, modelTestcaseVariationActual):
549
723
  return not any(not isinstance(actual,dict) for actual in modelTestcaseVariationActual)
550
724
 
551
- def determineTestStatus(self, modelTestcaseVariation, errors):
725
+ def determineTestStatus(self, modelTestcaseVariation, errors, validateModelCount=None):
552
726
  testcaseResultOptions = self.modelXbrl.modelManager.formulaOptions.testcaseResultOptions
553
- matchAllExpected = testcaseResultOptions == "match-all"
727
+ testcaseExpectedErrors = self.modelXbrl.modelManager.formulaOptions.testcaseExpectedErrors or {}
728
+ matchAllExpected = testcaseResultOptions == "match-all" or modelTestcaseVariation.match == 'all'
729
+ expectedReportCount = modelTestcaseVariation.expectedReportCount
730
+ expectedWarnings = modelTestcaseVariation.expectedWarnings if self.modelXbrl.modelManager.formulaOptions.testcaseResultsCaptureWarnings else []
731
+ if expectedReportCount is not None and validateModelCount is not None and expectedReportCount != validateModelCount:
732
+ errors.append("conf:testcaseExpectedReportCountError")
554
733
  _blockedMessageCodes = modelTestcaseVariation.blockedMessageCodes # restricts codes examined when provided
555
734
  if _blockedMessageCodes:
556
735
  _blockPattern = re.compile(_blockedMessageCodes)
557
736
  _errors = [e for e in errors if isinstance(e,str) and not _blockPattern.match(e)]
558
737
  else:
559
738
  _errors = errors
739
+ _errors.extend(self.modelXbrl.modelManager.cntlr.errors)
560
740
  numErrors = sum(isinstance(e,(QName,str)) for e in _errors) # does not include asserton dict results
561
741
  hasAssertionResult = any(isinstance(e,dict) for e in _errors)
562
742
  expected = modelTestcaseVariation.expected
563
743
  expectedCount = modelTestcaseVariation.expectedCount
744
+ indexPath = modelTestcaseVariation.document.filepath
745
+ if self.useFileSource is not None and self.useFileSource.isZip:
746
+ baseZipFile = self.useFileSource.basefile
747
+ if indexPath.startswith(baseZipFile):
748
+ indexPath = indexPath[len(baseZipFile) + 1:]
749
+ indexPath = indexPath.replace("\\", "/")
750
+ variationIdPath = f'{indexPath}:{modelTestcaseVariation.id}'
751
+ userExpectedErrors = []
752
+ for userPattern, userErrors in testcaseExpectedErrors.items():
753
+ if fnmatch.fnmatch(variationIdPath, userPattern):
754
+ userExpectedErrors.extend(userErrors)
755
+ if userExpectedErrors:
756
+ if expected is None:
757
+ expected = []
758
+ if isinstance(expected, str):
759
+ assert expected in {"valid", "invalid"}, f"unhandled expected value string '{expected}'"
760
+ expected = []
761
+ expected.extend(userExpectedErrors)
762
+ if expectedCount is not None:
763
+ expectedCount += len(userExpectedErrors)
564
764
  if matchAllExpected:
565
765
  if isinstance(expected, list):
566
766
  if not expectedCount:
@@ -568,27 +768,30 @@ class Validate:
568
768
  elif expectedCount is None:
569
769
  expectedCount = 0
570
770
  if expected == "valid":
571
- if numErrors == 0:
572
- status = "pass"
573
- else:
574
- status = "fail"
771
+ status = "pass" if numErrors == 0 else "fail"
575
772
  elif expected == "invalid":
576
- if numErrors == 0:
577
- status = "fail"
578
- else:
579
- status = "pass"
580
- elif expected in (None, []) and numErrors == 0:
773
+ status = "fail" if numErrors == 0 else "pass"
774
+ elif expected in (None, []) and numErrors == 0 and not expectedWarnings:
581
775
  status = "pass"
582
- elif isinstance(expected,(QName,str,dict,list)): # string or assertion id counts dict
776
+ elif isinstance(expected, (QName, str, dict, list)) or expectedWarnings:
583
777
  status = "fail"
584
778
  _passCount = 0
585
779
  if isinstance(expected, list):
586
- _expectedList = expected.copy() # need shallow copy
780
+ _expectedList = expected.copy()
781
+ elif not expected:
782
+ _expectedList = []
587
783
  else:
588
784
  _expectedList = [expected]
589
- if not isinstance(expected, list): expected = [expected]
785
+ if expectedWarnings:
786
+ _expectedList.extend(expectedWarnings)
787
+ if expectedCount is not None:
788
+ expectedCount += len(expectedWarnings)
789
+ else:
790
+ expectedCount = len(expectedWarnings)
791
+ if not isinstance(expected, list):
792
+ expected = [expected]
590
793
  for testErr in _errors:
591
- if isinstance(testErr,str) and testErr.startswith("ESEF."): # compared as list of strings to QName localname
794
+ if isinstance(testErr, str) and testErr.startswith(("ESEF.", "NL.NL-KVK")): # compared as list of strings to QName localname
592
795
  testErr = testErr.rpartition(".")[2]
593
796
  for _exp in _expectedList:
594
797
  _expMatched = False
@@ -601,7 +804,7 @@ class Validate:
601
804
  # XDT xml schema tests expected results
602
805
  (_exp.namespaceURI == XbrlConst.xdtSchemaErrorNS and errPrefix == "xmlSchema")):
603
806
  _expMatched = True
604
- elif type(testErr) == type(_exp):
807
+ elif type(testErr) is type(_exp):
605
808
  if isinstance(testErr,dict):
606
809
  if len(testErr) == len(_exp) and all(
607
810
  k in testErr and counts == testErr[k][:len(counts)]
@@ -615,6 +818,7 @@ class Validate:
615
818
  (_exp == "EFM.6.04.03" and (testErr.startswith("xmlSchema:") or testErr.startswith("utr:") or testErr.startswith("xbrl.") or testErr.startswith("xlink:"))) or
616
819
  (_exp == "EFM.6.05.35" and testErr.startswith("utre:")) or
617
820
  (_exp.startswith("EFM.") and testErr.startswith(_exp)) or
821
+ (_exp.startswith("EXG.") and testErr.startswith(_exp)) or
618
822
  (_exp == "vere:invalidDTSIdentifier" and testErr.startswith("xbrl"))
619
823
  ))):
620
824
  _expMatched = True
@@ -665,16 +869,6 @@ class Validate:
665
869
  if isinstance(error,dict):
666
870
  modelTestcaseVariation.actual.append(error)
667
871
 
668
- def determineNotLoadedTestStatus(self, modelTestcaseVariation, errors):
669
- if errors:
670
- self.determineTestStatus(modelTestcaseVariation, errors)
671
- return
672
- expected = modelTestcaseVariation.expected
673
- status = "not loadable"
674
- if expected in ("EFM.6.03.04", "EFM.6.03.05"):
675
- status = "pass"
676
- modelTestcaseVariation.status = status
677
-
678
872
  import logging
679
873
  class ValidationLogListener(logging.Handler):
680
874
  def __init__(self, logView):