arelle-release 2.37.46__py3-none-any.whl → 2.38.0__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 (204) hide show
  1. arelle/BetaFeatures.py +0 -21
  2. arelle/Cntlr.py +15 -8
  3. arelle/CntlrCmdLine.py +121 -56
  4. arelle/CntlrWinMain.py +143 -70
  5. arelle/DialogFind.py +1 -1
  6. arelle/DialogPluginManager.py +6 -4
  7. arelle/DisclosureSystem.py +7 -0
  8. arelle/ErrorManager.py +21 -6
  9. arelle/FileSource.py +11 -4
  10. arelle/FunctionIxt.py +16 -11
  11. arelle/HtmlUtil.py +5 -4
  12. arelle/LeiUtil.py +63 -43
  13. arelle/ModelDocument.py +20 -15
  14. arelle/ModelDtsObject.py +8 -0
  15. arelle/ModelInstanceObject.py +1 -1
  16. arelle/ModelObject.py +16 -18
  17. arelle/ModelObjectFactory.py +35 -17
  18. arelle/ModelXbrl.py +28 -11
  19. arelle/PluginManager.py +130 -105
  20. arelle/RuntimeOptions.py +1 -0
  21. arelle/UrlUtil.py +14 -0
  22. arelle/Validate.py +17 -12
  23. arelle/ValidateDuplicateFacts.py +3 -1
  24. arelle/ValidateFileSource.py +38 -0
  25. arelle/ValidateFilingText.py +3 -3
  26. arelle/ValidateXbrl.py +5 -2
  27. arelle/ValidateXbrlCalcs.py +210 -186
  28. arelle/ValidateXbrlDTS.py +1 -1
  29. arelle/ViewFile.py +1 -0
  30. arelle/ViewFileFactTable.py +2 -2
  31. arelle/ViewWinDTS.py +4 -1
  32. arelle/WebCache.py +28 -24
  33. arelle/XbrlConst.py +22 -0
  34. arelle/XmlUtil.py +16 -21
  35. arelle/XmlValidate.py +6 -9
  36. arelle/_version.py +16 -3
  37. arelle/api/Session.py +11 -2
  38. arelle/config/disclosuresystems.xsd +2 -0
  39. arelle/config/rosettaEntitlements.plist +8 -0
  40. arelle/conformance/CSVTestcaseLoader.py +1 -1
  41. arelle/formula/XPathContext.py +3 -3
  42. arelle/logging/formatters/LogFormatter.py +3 -1
  43. arelle/packages/report/ReportPackage.py +26 -13
  44. arelle/packages/report/ReportPackageConst.py +0 -1
  45. arelle/plugin/inlineXbrlDocumentSet.py +19 -5
  46. arelle/plugin/validate/DBA/DisclosureSystems.py +19 -1
  47. arelle/plugin/validate/DBA/PluginValidationDataExtension.py +2 -4
  48. arelle/plugin/validate/DBA/ValidationPluginExtension.py +2 -1
  49. arelle/plugin/validate/DBA/resources/config.xml +5 -0
  50. arelle/plugin/validate/DBA/rules/__init__.py +2 -2
  51. arelle/plugin/validate/DBA/rules/fr.py +19 -2
  52. arelle/plugin/validate/DBA/rules/tc.py +2 -0
  53. arelle/plugin/validate/DBA/rules/th.py +6 -0
  54. arelle/plugin/validate/DBA/rules/tm.py +18 -5
  55. arelle/plugin/validate/DBA/rules/tr.py +11 -5
  56. arelle/plugin/validate/EDINET/Constants.py +193 -9
  57. arelle/plugin/validate/EDINET/ContextRequirement.py +58 -0
  58. arelle/plugin/validate/EDINET/ControllerPluginData.py +220 -1
  59. arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
  60. arelle/plugin/validate/EDINET/DeiRequirements.py +118 -0
  61. arelle/plugin/validate/EDINET/FilingFormat.py +275 -0
  62. arelle/plugin/validate/EDINET/FormType.py +134 -0
  63. arelle/plugin/validate/EDINET/ManifestInstance.py +72 -5
  64. arelle/plugin/validate/EDINET/NamespaceConfig.py +50 -0
  65. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +493 -132
  66. arelle/plugin/validate/EDINET/{InstanceType.py → ReportFolderType.py} +72 -15
  67. arelle/plugin/validate/EDINET/Statement.py +139 -0
  68. arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +595 -0
  69. arelle/plugin/validate/EDINET/UploadContents.py +48 -0
  70. arelle/plugin/validate/EDINET/ValidationPluginExtension.py +20 -2
  71. arelle/plugin/validate/EDINET/__init__.py +31 -6
  72. arelle/plugin/validate/EDINET/resources/config.xml +8 -1
  73. arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
  74. arelle/plugin/validate/EDINET/resources/dei-requirements.csv +27 -0
  75. arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +2 -0
  76. arelle/plugin/validate/EDINET/rules/contexts.py +375 -14
  77. arelle/plugin/validate/EDINET/rules/edinet.py +1934 -45
  78. arelle/plugin/validate/EDINET/rules/frta.py +122 -3
  79. arelle/plugin/validate/EDINET/rules/gfm.py +1907 -11
  80. arelle/plugin/validate/EDINET/rules/upload.py +989 -141
  81. arelle/plugin/validate/ESEF/Const.py +3 -1
  82. arelle/plugin/validate/ESEF/ESEF_2021/DTS.py +5 -0
  83. arelle/plugin/validate/ESEF/ESEF_2021/Image.py +2 -2
  84. arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +23 -20
  85. arelle/plugin/validate/ESEF/ESEF_Current/DTS.py +47 -14
  86. arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +100 -25
  87. arelle/plugin/validate/ESEF/__init__.py +20 -6
  88. arelle/plugin/validate/ESEF/resources/authority-validations.json +76 -9
  89. arelle/plugin/validate/ESEF/resources/config.xml +20 -0
  90. arelle/plugin/validate/NL/DisclosureSystems.py +22 -0
  91. arelle/plugin/validate/NL/PluginValidationDataExtension.py +27 -9
  92. arelle/plugin/validate/NL/ValidationPluginExtension.py +51 -7
  93. arelle/plugin/validate/NL/resources/config.xml +18 -0
  94. arelle/plugin/validate/NL/rules/br_kvk.py +17 -61
  95. arelle/plugin/validate/NL/rules/fg_nl.py +7 -38
  96. arelle/plugin/validate/NL/rules/fr_kvk.py +7 -42
  97. arelle/plugin/validate/NL/rules/fr_nl.py +31 -147
  98. arelle/plugin/validate/NL/rules/nl_kvk.py +142 -28
  99. arelle/plugin/validate/ROS/PluginValidationDataExtension.py +2 -0
  100. arelle/plugin/validate/ROS/ValidationPluginExtension.py +4 -1
  101. arelle/plugin/validate/ROS/rules/ros.py +41 -9
  102. arelle/plugin/validate/UK/ValidateUK.py +130 -66
  103. arelle/plugin/validate/UK/__init__.py +89 -103
  104. arelle/utils/EntryPointDetection.py +79 -13
  105. arelle/utils/PluginHooks.py +125 -0
  106. arelle/utils/validate/ESEFImage.py +6 -6
  107. arelle/utils/validate/Validation.py +18 -0
  108. arelle/utils/validate/ValidationPlugin.py +76 -11
  109. arelle/utils/validate/ValidationUtil.py +35 -3
  110. {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/METADATA +30 -20
  111. {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/RECORD +115 -191
  112. {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/licenses/LICENSE.md +0 -3
  113. arelle/archive/CustomLogger.py +0 -43
  114. arelle/archive/LoadEFMvalidate.py +0 -32
  115. arelle/archive/LoadSavePreLbCsv.py +0 -26
  116. arelle/archive/LoadValidate.cs +0 -31
  117. arelle/archive/LoadValidate.py +0 -36
  118. arelle/archive/LoadValidateCmdLine.java +0 -69
  119. arelle/archive/LoadValidatePostedZip.java +0 -57
  120. arelle/archive/LoadValidateWebService.java +0 -34
  121. arelle/archive/SaveTableToExelle.py +0 -140
  122. arelle/archive/TR3toTR4.py +0 -88
  123. arelle/archive/plugin/ESEF_2022/__init__.py +0 -47
  124. arelle/archive/plugin/bigInstance.py +0 -394
  125. arelle/archive/plugin/cmdWebServerExtension.py +0 -43
  126. arelle/archive/plugin/crashTest.py +0 -38
  127. arelle/archive/plugin/functionsXmlCreation.py +0 -106
  128. arelle/archive/plugin/hello_i18n.pot +0 -26
  129. arelle/archive/plugin/hello_i18n.py +0 -32
  130. arelle/archive/plugin/importTestChild1.py +0 -21
  131. arelle/archive/plugin/importTestChild2.py +0 -22
  132. arelle/archive/plugin/importTestGrandchild1.py +0 -21
  133. arelle/archive/plugin/importTestGrandchild2.py +0 -21
  134. arelle/archive/plugin/importTestImported1.py +0 -23
  135. arelle/archive/plugin/importTestImported11.py +0 -22
  136. arelle/archive/plugin/importTestParent.py +0 -48
  137. arelle/archive/plugin/instanceInfo.py +0 -306
  138. arelle/archive/plugin/loadFromOIM-2018.py +0 -1282
  139. arelle/archive/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
  140. arelle/archive/plugin/objectmaker.py +0 -285
  141. arelle/archive/plugin/packagedImportTest/__init__.py +0 -47
  142. arelle/archive/plugin/packagedImportTest/importTestChild1.py +0 -21
  143. arelle/archive/plugin/packagedImportTest/importTestChild2.py +0 -22
  144. arelle/archive/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
  145. arelle/archive/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
  146. arelle/archive/plugin/packagedImportTest/importTestImported1.py +0 -24
  147. arelle/archive/plugin/packagedImportTest/importTestImported11.py +0 -21
  148. arelle/archive/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
  149. arelle/archive/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
  150. arelle/archive/plugin/sakaCalendar.py +0 -215
  151. arelle/archive/plugin/saveInstanceInfoset.py +0 -121
  152. arelle/archive/plugin/sphinx/FormulaGenerator.py +0 -823
  153. arelle/archive/plugin/sphinx/SphinxContext.py +0 -404
  154. arelle/archive/plugin/sphinx/SphinxEvaluator.py +0 -783
  155. arelle/archive/plugin/sphinx/SphinxMethods.py +0 -1287
  156. arelle/archive/plugin/sphinx/SphinxParser.py +0 -1093
  157. arelle/archive/plugin/sphinx/SphinxValidator.py +0 -163
  158. arelle/archive/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
  159. arelle/archive/plugin/sphinx/__init__.py +0 -285
  160. arelle/archive/plugin/streamingExtensions.py +0 -335
  161. arelle/archive/plugin/updateTableLB.py +0 -242
  162. arelle/archive/plugin/validate/SBRnl/CustomLoader.py +0 -19
  163. arelle/archive/plugin/validate/SBRnl/DTS.py +0 -305
  164. arelle/archive/plugin/validate/SBRnl/Dimensions.py +0 -357
  165. arelle/archive/plugin/validate/SBRnl/Document.py +0 -799
  166. arelle/archive/plugin/validate/SBRnl/Filing.py +0 -467
  167. arelle/archive/plugin/validate/SBRnl/__init__.py +0 -75
  168. arelle/archive/plugin/validate/SBRnl/config.xml +0 -26
  169. arelle/archive/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
  170. arelle/archive/plugin/validate/USBestPractices.py +0 -570
  171. arelle/archive/plugin/validate/USCorpAction.py +0 -557
  172. arelle/archive/plugin/validate/USSecTagging.py +0 -337
  173. arelle/archive/plugin/validate/XDC/__init__.py +0 -77
  174. arelle/archive/plugin/validate/XDC/config.xml +0 -20
  175. arelle/archive/plugin/validate/XFsyntax/__init__.py +0 -64
  176. arelle/archive/plugin/validate/XFsyntax/xf.py +0 -2227
  177. arelle/archive/plugin/validate/calc2.py +0 -536
  178. arelle/archive/plugin/validateSchemaLxml.py +0 -156
  179. arelle/archive/plugin/validateTableInfoset.py +0 -52
  180. arelle/archive/us-gaap-dei-docType-extraction-frm.xml +0 -90
  181. arelle/archive/us-gaap-dei-ratio-cash-frm.xml +0 -150
  182. arelle/examples/plugin/formulaSuiteConverter.py +0 -212
  183. arelle/examples/plugin/functionsCustom.py +0 -59
  184. arelle/examples/plugin/hello_dolly.py +0 -64
  185. arelle/examples/plugin/multi.py +0 -58
  186. arelle/examples/plugin/rssSaveOim.py +0 -96
  187. arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
  188. arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
  189. arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
  190. arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
  191. arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
  192. arelle/examples/plugin/validate/XYZ/rules/__init__.py +0 -0
  193. arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -110
  194. arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -59
  195. arelle/model/CommentBase.py +0 -9
  196. arelle/model/ElementBase.py +0 -11
  197. arelle/model/PIBase.py +0 -10
  198. arelle/model/__init__.py +0 -15
  199. arelle/scripts-macOS/startWebServer.command +0 -3
  200. arelle/scripts-unix/startWebServer.sh +0 -1
  201. arelle/scripts-windows/startWebServer.bat +0 -5
  202. {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/WHEEL +0 -0
  203. {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/entry_points.txt +0 -0
  204. {arelle_release-2.37.46.dist-info → arelle_release-2.38.0.dist-info}/top_level.txt +0 -0
@@ -1,212 +0,0 @@
1
- '''
2
- XBRL formula conf suite converter
3
- from Formula 1.0 to XF
4
-
5
- arelleCmdline
6
- --plugin formulaSuiteConverter
7
- --source-test-suite-dir {directory containing index.xml file for suite)
8
- --converted-test-suite-dir {directory receiving converted suite)
9
-
10
-
11
- See COPYRIGHT.md for copyright information.
12
- '''
13
- from arelle import ModelXbrl, XmlUtil
14
- from arelle.ModelDocument import Type
15
- from arelle.ModelValue import qname
16
- from arelle.ViewUtilFormulae import rootFormulaObjects, formulaObjSortKey
17
- from arelle.PluginManager import pluginClassMethods
18
- from arelle.PrototypeDtsObject import PrototypeObject
19
- from arelle.PythonUtil import attrdict
20
- from arelle.Version import authorLabel, copyrightLabel
21
- import os, shutil
22
- from lxml import etree
23
- import regex as re
24
-
25
- oimErrPattern = re.compile("(oime|xbrlxe):")
26
- QN_SCHEMA_REF = qname("{http://www.xbrl.org/2003/linkbase}schemaRef")
27
-
28
- def convertVariation(cntlr, variationFile, variationElt, inPath, outPath, entryPoint, resultInstFile):
29
- entryFile = os.path.join(inPath, entryPoint)
30
- modelXbrl = ModelXbrl.load(cntlr.modelManager, entryFile)
31
- doc = modelXbrl.modelDocument
32
- formulaRootObjects = rootFormulaObjects(modelXbrl) # sets var sets up
33
- formulaFile = None
34
- for formulaRootObject in sorted(formulaRootObjects, key=formulaObjSortKey):
35
- formulaFile = formulaRootObject.modelDocument.basename # first formula file
36
- break
37
- # convert formula linkbaseRefs into shim schema refs
38
- if doc.type in (Type.INSTANCE, Type.INLINEXBRL, Type.INLINEXBRLDOCUMENTSET):
39
- for lbDoc, ref in doc.referencesDocument.items():
40
- if lbDoc.type == Type.LINKBASE:
41
- lbRef = lbDoc.basename
42
- if lbRef == formulaFile:
43
- lbRef = os.path.splitext(lbRef)[0] + ".xf"
44
- lbDoc.uri = os.path.splitext(lbDoc.uri)[0] + ".xsd"
45
- lbXsdFile = os.path.splitext(lbRef)[0] + ".xsd"
46
- with open(os.path.join(outPath, lbXsdFile), "w", encoding="utf-8") as fh:
47
- fh.write("""
48
- <?xml version="1.0" encoding="utf-8"?>
49
- <schema
50
- xmlns="http://www.w3.org/2001/XMLSchema"
51
- xmlns:link="http://www.xbrl.org/2003/linkbase"
52
- xmlns:xlink="http://www.w3.org/1999/xlink"
53
- elementFormDefault="qualified">
54
- <annotation>
55
- <appinfo>
56
- <link:linkbaseRef
57
- xlink:href="{}"
58
- xlink:type="simple"
59
- xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase"/>
60
- </appinfo>
61
- </annotation>
62
- </schema>
63
- """.format(lbRef))
64
- lbDoc.type = Type.SCHEMA
65
- ref.referringModelObject = PrototypeObject(ref.referringModelObject.modelDocument, ref.referringModelObject)
66
- ref.referringModelObject.qname = QN_SCHEMA_REF
67
-
68
- # perform OIM validation on xBRL-XML source instance
69
- for pluginXbrlMethod in pluginClassMethods("Validate.XBRL.Finally"):
70
- pluginXbrlMethod(doc)
71
- if any(oimErrPattern.match(err) for err in modelXbrl.errors):
72
- modelXbrl.error("testSuiteConverter:unconvertableTestcase",
73
- f"Variation {variationFile} {variationElt.get('id')} has OIM errors",
74
- modelObject=modelXbrl)
75
- variationElt.getparent().remove(variationElt)
76
- return {}
77
- transformedFiles = {}
78
- convertedFiles = {}
79
- if formulaFile:
80
- formulaOutFile = os.path.splitext(formulaFile)[0] + ".xf"
81
- transformedFiles["xbrlFormulaFile"] = os.path.join(outPath, formulaOutFile)
82
- convertedFiles[formulaFile] = formulaOutFile
83
- if doc.type in (Type.INSTANCE, Type.INLINEXBRL, Type.INLINEXBRLDOCUMENTSET):
84
- instOutFile = os.path.splitext(doc.basename)[0] + ".json"
85
- transformedFiles["saveLoadableOIM"] = os.path.join(outPath, instOutFile)
86
- convertedFiles[doc.basename] = instOutFile
87
- # CntlrCmdLine.Xbrl.Run invokes both saveLoadableOIM for instance and formulaSaver for xf
88
- options = attrdict(**transformedFiles)
89
- try:
90
- for pluginXbrlMethod in pluginClassMethods("CntlrCmdLine.Xbrl.Run"):
91
- pluginXbrlMethod(cntlr, options, modelXbrl)
92
- except Exception as ex:
93
- modelXbrl.error("testSuiteConverter:unconvertableTestcase",
94
- f"Variation {variationFile} {variationElt.get('id')} is not transformable to XF or OIM: {ex}",
95
- modelObject=modelXbrl)
96
- variationElt.getparent().remove(variationElt)
97
- return {}
98
- if resultInstFile:
99
- resultOutFile = os.path.splitext(resultInstFile)[0] + ".json"
100
- options = attrdict(saveLoadableOIM=os.path.join(outPath, resultOutFile))
101
- convertedFiles[resultInstFile] = resultOutFile
102
- try:
103
- for pluginXbrlMethod in pluginClassMethods("CntlrCmdLine.Xbrl.Run"):
104
- pluginXbrlMethod(cntlr, options, modelXbrl)
105
- except Exception as ex:
106
- modelXbrl.error("testSuiteConverter:unconvertableTestcase",
107
- f"Variation {variationFile} {variationElt.get('id')} is not transformable to XF or OIM: {ex}",
108
- modelObject=modelXbrl)
109
- variationElt.getparent().remove(variationElt)
110
- return {}
111
- return convertedFiles
112
-
113
- def convertTestcase(cntlr, inPath, outPath, testcaseFile):
114
- testcaseDir = os.path.dirname(testcaseFile)
115
- indexTree = etree.parse(os.path.join(inPath, testcaseFile))
116
- # check if an index to testcases
117
- if indexTree.find("testcases") is not None:
118
- for testcasesElt in indexTree.iter("testcases"):
119
- # index to testcases
120
- testcaseRoot = testcasesElt.get("root")
121
- if testcaseRoot:
122
- tcInPath = os.path.join(inPath, testcaseRoot)
123
- tcOutPath = os.path.join(outPath, testcaseRoot)
124
- else:
125
- tcInPath = inPath
126
- tcOutPath = outPath
127
- if not os.path.exists(tcOutPath):
128
- os.mkdir(tcOutPath)
129
- for testcaseElt in testcasesElt.iter("testcase"):
130
- convertTestcase(cntlr, tcInPath, tcOutPath, testcaseElt.get("uri"))
131
- else:
132
- # testcase file
133
- convertedFiles = {}
134
- for variationElt in indexTree.iter("{*}variation"):
135
- readMeFirstElt = variationElt.find("*/*[@readMeFirst='true']")
136
- readMeFirstFile = readMeFirstElt.text
137
- resultInstElt = variationElt.find("{*}result/{*}instance")
138
- if resultInstElt is not None:
139
- resultInstFile = resultInstElt.text
140
- else:
141
- resultInstFile = None
142
- if testcaseDir:
143
- tcInPath = os.path.join(inPath, testcaseDir)
144
- tcOutPath = os.path.join(outPath, testcaseDir)
145
- else:
146
- tcInPath = inPath
147
- tcOutPath = outPath
148
- if not os.path.exists(tcOutPath):
149
- os.mkdir(tcOutPath)
150
- if os.path.exists(os.path.join(tcInPath, readMeFirstFile)):
151
- convertedFiles |= convertVariation(cntlr, os.path.basename(testcaseFile), variationElt, tcInPath, tcOutPath, readMeFirstFile, resultInstFile)
152
- if convertedFiles:
153
- # update testcase and copy over un-converted files
154
- if testcaseDir:
155
- tcInPath = os.path.join(inPath, testcaseDir)
156
- tcOutPath = os.path.join(outPath, testcaseDir)
157
- else:
158
- tcInPath = inPath
159
- tcOutPath = outPath
160
- if not os.path.exists(tcOutPath):
161
- os.mkdir(tcOutPath)
162
- for elt in indexTree.iter():
163
- if isinstance(elt.tag, str) and (elt.tag.endswith("schema") or elt.tag.endswith("linkbase") or elt.tag.endswith("instance")):
164
- if elt.text in convertedFiles:
165
- elt.text = convertedFiles[elt.text]
166
- else:
167
- srcFile = os.path.join(tcInPath, elt.text)
168
- if os.path.exists(srcFile):
169
- dstFile = os.path.join(tcOutPath, elt.text)
170
- dstdir = os.path.dirname(dstFile)
171
- if not os.path.exists(dstdir):
172
- os.mkdir(dstdir)
173
- shutil.copyfile(srcFile, dstFile)
174
- tcOutFile = os.path.join(outPath, testcaseFile)
175
- tcOutDir = os.path.dirname(tcOutFile)
176
- if not os.path.exists(tcOutDir):
177
- os.mkdir(tcOutDir)
178
- with open(tcOutFile, "w", encoding="utf-8") as fh:
179
- XmlUtil.writexml(fh, indexTree, indent=" ", encoding="utf-8")
180
-
181
- def convertSuite(cntlr, options, *args, **kwargs):
182
- sourceSuiteDir = getattr(options, "sourceTestSuiteDir", None)
183
- convertedSuiteDir = getattr(options, "convertedTestSuiteDir", None)
184
- if not os.path.exists(sourceSuiteDir):
185
- os.mkdir(sourceSuiteDir)
186
- for testcaseFile in ("index.xml",):
187
- convertTestcase(cntlr, sourceSuiteDir, convertedSuiteDir, testcaseFile)
188
- shutil.copyfile(os.path.join(sourceSuiteDir, testcaseFile), os.path.join(convertedSuiteDir, testcaseFile))
189
-
190
- def commandLineOptionExtender(parser, *args, **kwargs):
191
- parser.add_option("--source-test-suite-dir",
192
- action="store",
193
- dest="sourceTestSuiteDir",
194
- help=_("The source directory containing formula linkbase files to convert to XF."))
195
- parser.add_option("--converted-test-suite-dir",
196
- action="store",
197
- dest="convertedTestSuiteDir",
198
- help=_("The destination directory to save the converted XF files."))
199
-
200
- __pluginInfo__ = {
201
- 'name': 'Formula Suite Converter',
202
- 'version': '0.9',
203
- 'description': "Convert XBRL Formula conformance suite to XF.",
204
- 'license': 'Apache-2',
205
- 'author': authorLabel,
206
- 'copyright': copyrightLabel,
207
- # use formulaSaver tt output XF and saveLoadableOIM to output json instance
208
- 'import': ('formulaSaver', 'saveLoadableOIM'),
209
- # classes of mount points (required)
210
- 'CntlrCmdLine.Options': commandLineOptionExtender,
211
- 'CntlrCmdLine.Utility.Run': convertSuite
212
- }
@@ -1,59 +0,0 @@
1
- '''
2
- Sample custom functions plugin for formula custom functions
3
-
4
- See COPYRIGHT.md for copyright information.
5
- '''
6
- from arelle import XbrlUtil
7
- from arelle.formula import XPathContext
8
- from arelle.ModelValue import qname
9
- from arelle.ModelInstanceObject import ModelDimensionValue
10
- from arelle.Version import authorLabel, copyrightLabel
11
- from decimal import Decimal
12
-
13
- # custom function for test case 22015 v01, same as in FunctionCustom.py
14
- def test_22015v01_my_fn_PDxEV(xc, p, contextItem, args):
15
- if len(args) != 2: raise XPathContext.FunctionNumArgs()
16
- PDseq = args[0] if isinstance(args[0],(list,tuple)) else (args[0],)
17
- EVseq = args[1] if isinstance(args[1],(list,tuple)) else (args[1],)
18
- dimQname = qname("{http://www.example.com/wgt-avg}ExposuresDimension")
19
- PDxEV = []
20
- for pd in PDseq:
21
- if pd.context is not None:
22
- pdDim = pd.context.dimValue(dimQname)
23
- for ev in EVseq:
24
- if ev.context is not None:
25
- evDim = ev.context.dimValue(dimQname)
26
- if pdDim is not None and isinstance(pdDim,ModelDimensionValue):
27
- dimEqual = pdDim.isEqualTo(evDim, equalMode=XbrlUtil.S_EQUAL2)
28
- elif evDim is not None and isinstance(evDim,ModelDimensionValue):
29
- dimEqual = evDim.isEqualTo(pdDim, equalMode=XbrlUtil.S_EQUAL2)
30
- else:
31
- dimEqual = (pdDim == evDim)
32
- if dimEqual:
33
- PDxEV.append(pd.xValue * ev.xValue)
34
- # type promotion required
35
- if isinstance(pdX,Decimal) and isinstance(evX,float):
36
- pdX = float(pdX)
37
- elif isinstance(evX,Decimal) and isinstance(pdX,float):
38
- pdX = float(evX)
39
- PDxEV.append(pdX * evX)
40
- break
41
- return PDxEV
42
-
43
- # returns dict of function QName and method executing the function
44
- def customFunctions():
45
- return {
46
- # sample function included for formula tests
47
- qname("{http://www.example.com/wgt-avg/function}my-fn:PDxEV"): test_22015v01_my_fn_PDxEV
48
- }
49
-
50
- __pluginInfo__ = {
51
- 'name': 'Custom Formula Functions (example)',
52
- 'version': '1.0',
53
- 'description': "This plug-in adds a custom function implemented by a plug-in. ",
54
- 'license': 'Apache-2',
55
- 'author': authorLabel,
56
- 'copyright': copyrightLabel,
57
- # classes of mount points (required)
58
- 'Formula.CustomFunctions': customFunctions,
59
- }
@@ -1,64 +0,0 @@
1
- '''
2
- Hello dolly is a simple "Hello world" to demonstrate how plug-ins
3
- are written for Arelle
4
-
5
- See COPYRIGHT.md for copyright information.
6
- '''
7
- from __future__ import print_function
8
- from arelle.Version import copyrightLabel
9
- from random import randint
10
-
11
-
12
- LYRICS = ["I said hello, dolly,......well, hello, dolly", \
13
- "It's so nice to have you back where you belong ", \
14
- "You're lookin' swell, dolly.......i can tell, dolly ", \
15
- "You're still glowin'...you're still crowin'...you're still goin' strong ", \
16
- "I feel that room swayin'......while the band's playin' ", \
17
- "One of your old favourite songs from way back when ", \
18
- "So..... take her wrap, fellas.......find her an empty lap, fellas ", \
19
- "Dolly'll never go away again"
20
- ]
21
-
22
- def randomLyric():
23
- ''' A random lyrics.'''
24
- return LYRICS[randint(0, len(LYRICS) - 1)]
25
-
26
- def helloMenuEntender(cntlr, menu):
27
- menu.add_command(label="Hello Dolly", underline=0, command=lambda: helloMenuCommand(cntlr, "Hello Dolly") )
28
-
29
- def helloMenuCommand(cntlr, label):
30
- hello_dolly = randomLyric();
31
- cntlr.addToLog(hello_dolly)
32
- import tkinter
33
- tkinter.messagebox.showinfo(label, hello_dolly, parent=cntlr.parent)
34
-
35
- def helloCommandLineOptionExtender(parser):
36
- parser.add_option("--hello_dolly",
37
- action="store_true",
38
- dest="hello_dolly",
39
- help=_('Print a random lyric from "Hello, Dolly"'))
40
-
41
- def helloCommandLineUtilityRun(cntlr, options, **kwargs):
42
- if getattr(options, "hello_dolly", False):
43
- hello_dolly = randomLyric();
44
- try:
45
- cntlr.addToLog("[info] " + hello_dolly)
46
- except:
47
- print(hello_dolly)
48
-
49
-
50
- __pluginInfo__ = {
51
- 'name': 'Hello Dolly',
52
- 'version': '0.9',
53
- 'description': "This is not just a plug-in, it symbolizes the hope and enthusiasm "
54
- "of an entire generation summed up in two words sung most famously "
55
- "by Louis Armstrong: Hello, Dolly. When activated you will randomly "
56
- "see a lyric from Hello, Dolly.",
57
- 'license': 'Apache-2',
58
- 'author': 'R\xe9gis D\xce9camps',
59
- 'copyright': copyrightLabel,
60
- # classes of mount points (required)
61
- 'CntlrWinMain.Menu.Tools': helloMenuEntender,
62
- 'CntlrCmdLine.Options': helloCommandLineOptionExtender,
63
- 'CntlrCmdLine.Utility.Run': helloCommandLineUtilityRun,
64
- }
@@ -1,58 +0,0 @@
1
- """
2
- See COPYRIGHT.md for copyright information.
3
- """
4
- from __future__ import annotations
5
-
6
- import logging
7
- import sys
8
- from typing import Any
9
-
10
- from arelle.Cntlr import Cntlr
11
- from arelle.PluginUtils import PluginProcessPoolExecutor
12
- from arelle.RuntimeOptions import RuntimeOptions
13
- from arelle.Version import authorLabel, copyrightLabel
14
- from arelle.utils.PluginHooks import PluginHooks
15
-
16
-
17
- def sumPositiveNumbers(vals: tuple[int, ...]) -> int:
18
- if any(val < 1 for val in vals):
19
- raise ValueError("Verify exceptions are logged.")
20
- return sum(vals)
21
-
22
-
23
- class MultiPlugin(PluginHooks):
24
- @staticmethod
25
- def cntlrInit(
26
- cntlr: Cntlr,
27
- *args: Any,
28
- **kwargs: Any,
29
- ) -> None:
30
- jobs = (
31
- (0, 1),
32
- (2, 3, 4),
33
- (5, 6),
34
- (7, 8, 9),
35
- )
36
- with PluginProcessPoolExecutor(sys.modules[__name__]) as pool:
37
- jobFutures = [
38
- pool.submit(sumPositiveNumbers, job)
39
- for job in jobs
40
- ]
41
- val = 0
42
- for future in jobFutures:
43
- try:
44
- val += future.result(1)
45
- except ValueError as e:
46
- cntlr.addToLog(messageCode="multi:error", message=str(e), level=logging.ERROR)
47
- cntlr.addToLog(messageCode="multi:done", message=f"Computed val={val}")
48
-
49
-
50
- __pluginInfo__ = {
51
- "name": "multi",
52
- "version": "0.0.1",
53
- "description": "multiprocessing example",
54
- "license": "Apache-2",
55
- "author": authorLabel,
56
- "copyright": copyrightLabel,
57
- "Cntlr.Init": MultiPlugin.cntlrInit,
58
- }
@@ -1,96 +0,0 @@
1
- '''
2
- Rss Save OIM is a plug-in to the RSS GUI menu that will load an RSS filing's
3
- instances and save them as OIM files.
4
-
5
- See COPYRIGHT.md for copyright information.
6
-
7
- ViewWinRssFeed allows the GUI user to right-click on a filing. This plugin
8
- adds a menu item to save the filing as OIM Json files.
9
-
10
- The identified filing is loaded in a separate thread (so the GUI is not blocked)
11
- and each (of possibly multiple) instances are saved to OIM JSON files.
12
-
13
- If there is only one instance it saves to the file name provided by the Save Dialog.
14
- If there are multiple instances (such as a multi-IXDS inline filing), the additional
15
- instances are saved under their base file name with replaced suffix json, in the
16
- directory chosen by the Save Dialog.
17
-
18
- This plug-in imports the following plug-ins:
19
- saveLoadableOIM to save the xBRL-JSON instances
20
- inlineXbrlDocumentSet for multi-doc or multi-IXDS filings
21
- EDGAR/validate for isolation of multi-IXDS filings into primary and supplemental modelXbrl objects
22
- '''
23
-
24
- import os
25
- from arelle import ModelXbrl
26
- from arelle.FileSource import openFileSource
27
- from arelle.PluginManager import pluginClassMethods
28
- from arelle.Version import authorLabel, copyrightLabel
29
-
30
- def saveFilingOim(cntlr, zippedUrl, oimFile):
31
- # load filing
32
- modelXbrl = ModelXbrl.load(cntlr.modelManager,
33
- openFileSource(zippedUrl, cntlr))
34
- if modelXbrl is not None:
35
- for saveLoadableOIM in pluginClassMethods("SaveLoadableOim.Save"):
36
- saveLoadableOIM(modelXbrl, oimFile)
37
- modelXbrl.info("arelle:savedOIM", _("Saved OIM File {}").format(oimFile))
38
- # check for supplemental instances
39
- if hasattr(modelXbrl, "supplementalModelXbrls"):
40
- oimFileDir = os.path.dirname(oimFile)
41
- for supplementalModelXbrl in modelXbrl.supplementalModelXbrls:
42
- # use basename for the json file
43
- supplementalOimFile = os.path.join(oimFileDir, os.path.splitext(supplementalModelXbrl.basename)[0] + ".json")
44
- for saveLoadableOIM in pluginClassMethods("SaveLoadableOim.Save"):
45
- saveLoadableOIM(supplementalModelXbrl, supplementalOimFile)
46
- modelXbrl.info("arelle:savedOIM",_("Saved OIM File {}").format(supplementalOimFile))
47
- supplementalModelXbrl.close()
48
- modelXbrl.close()
49
-
50
-
51
- def rssFeedFilingMenuExtender(viewRssFeed, menu, *args, **kwargs):
52
- # Extend menu with an item for the savedts plugin
53
- menu.add_command(label="Save Filing OIM",
54
- underline=0,
55
- command=lambda: saveFilingOimMenuCommand(viewRssFeed) )
56
-
57
- def saveFilingOimMenuCommand(viewRssFeed):
58
- # save DTS menu item has been invoked
59
- cntlr = viewRssFeed.modelXbrl.modelManager.cntlr
60
- # get rssItemObj for the currently active row (if any)
61
- rssItemObj = viewRssFeed.modelXbrl.modelObject(viewRssFeed.menuRow)
62
- if rssItemObj is None:
63
- return
64
- # get file name into which to save log file while in foreground thread
65
- oimFile = cntlr.uiFileDialog("save",
66
- title=_("arelle - Save Filing OIM JSON file"),
67
- initialdir=cntlr.config.setdefault("loadableExcelFileDir","."),
68
- filetypes=[(_("JSON file .json"), "*.json")],
69
- defaultextension=".json")
70
- if not oimFile:
71
- return False
72
- import os
73
- cntlr.config["loadableOIMFileDir"] = os.path.dirname(oimFile)
74
- cntlr.saveConfig()
75
-
76
- import threading
77
- thread = threading.Thread(target=lambda
78
- _cntlr=cntlr,
79
- _zippedUrl=rssItemObj.zippedUrl,
80
- _oimFile=oimFile:
81
- saveFilingOim(_cntlr, _zippedUrl, _oimFile))
82
- thread.daemon = True
83
- thread.start()
84
-
85
-
86
- __pluginInfo__ = {
87
- 'name': 'Load RSS item and save OIM file',
88
- 'version': '1.0',
89
- 'description': "This plug-in saves an RSS-identified XBRL filing in OIM JSON files, for each instance of the filing.",
90
- 'license': 'Apache-2',
91
- 'author': authorLabel,
92
- 'copyright': copyrightLabel,
93
- 'import': ('saveLoadableOIM', 'inlineXbrlDocumentSet', 'EDGAR/validate'), # import dependent modules
94
- # classes of mount points (required)
95
- 'RssFeed.Menu.Filing': rssFeedFilingMenuExtender
96
- }
@@ -1,2 +0,0 @@
1
- DISCLOSURE_SYSTEM_2022 = "XYZ 2022"
2
- DISCLOSURE_SYSTEM_2023 = "XYZ 2023"
@@ -1,10 +0,0 @@
1
- """
2
- See COPYRIGHT.md for copyright information.
3
- """
4
- from __future__ import annotations
5
-
6
- from arelle.utils.PluginData import PluginData
7
-
8
-
9
- class PluginValidationDataExtension(PluginData):
10
- positiveFactConcepts: set[str] | None = None
@@ -1,49 +0,0 @@
1
- """
2
- See COPYRIGHT.md for copyright information.
3
- """
4
- from __future__ import annotations
5
-
6
- from typing import Any
7
-
8
- from arelle.ModelDocument import LoadingException, ModelDocument
9
- from arelle.ModelXbrl import ModelXbrl
10
- from arelle.ValidateXbrl import ValidateXbrl
11
- from arelle.typing import TypeGetText
12
- from arelle.utils.validate.ValidationPlugin import ValidationPlugin
13
- from .PluginValidationDataExtension import PluginValidationDataExtension
14
-
15
- _: TypeGetText
16
-
17
-
18
- class ValidationPluginExtension(ValidationPlugin):
19
- def newPluginData(self, validateXbrl: ValidateXbrl) -> PluginValidationDataExtension:
20
- return PluginValidationDataExtension(self.name)
21
-
22
- def modelDocumentPullLoader(
23
- self,
24
- modelXbrl: ModelXbrl,
25
- normalizedUri: str,
26
- filepath: str,
27
- isEntry: bool,
28
- namespace: str | None,
29
- *args: Any,
30
- **kwargs: Any,
31
- ) -> ModelDocument | LoadingException | None:
32
- if self.disclosureSystemFromPluginSelected(modelXbrl):
33
- return LoadingException(_("XYZ validation plugin is a template for new validation plugins and shouldn't be used directly."))
34
- return None
35
-
36
- def modelXbrlLoadComplete(
37
- self,
38
- modelXbrl: ModelXbrl,
39
- *args: Any,
40
- **kwargs: Any,
41
- ) -> None:
42
- if self.disclosureSystemFromPluginSelected(modelXbrl):
43
- if modelXbrl.modelDocument is None:
44
- modelXbrl.error(
45
- codes="XYZ.01.01",
46
- msg=_("An XBRL Report Package is required but could not be loaded"),
47
- modelObject=modelXbrl,
48
- )
49
- return None
@@ -1,75 +0,0 @@
1
- """
2
- See COPYRIGHT.md for copyright information.
3
-
4
- Filer Manual Guidelines: https://www.example.com/fake-xyz-filer-manual-v0.0.1.pdf
5
- """
6
- from __future__ import annotations
7
-
8
- from pathlib import Path
9
- from typing import Any
10
-
11
- from arelle.ModelDocument import LoadingException, ModelDocument
12
- from arelle.Version import authorLabel, copyrightLabel
13
- from .ValidationPluginExtension import ValidationPluginExtension
14
- from .rules import rules01, rules02
15
-
16
- PLUGIN_NAME = "Validate XYZ"
17
- DISCLOSURE_SYSTEM_VALIDATION_TYPE = "XYZ"
18
-
19
-
20
- validationPlugin = ValidationPluginExtension(
21
- name=PLUGIN_NAME,
22
- disclosureSystemConfigUrl=Path(__file__).parent / "resources" / "config.xml",
23
- validationTypes=[DISCLOSURE_SYSTEM_VALIDATION_TYPE],
24
- validationRuleModules=[rules01, rules02],
25
- )
26
-
27
-
28
- def disclosureSystemTypes(*args: Any, **kwargs: Any) -> tuple[tuple[str, str], ...]:
29
- return validationPlugin.disclosureSystemTypes
30
-
31
-
32
- def disclosureSystemConfigURL(*args: Any, **kwargs: Any) -> str:
33
- return validationPlugin.disclosureSystemConfigURL
34
-
35
-
36
- def modelDocumentPullLoader(*args: Any, **kwargs: Any) -> ModelDocument | LoadingException | None:
37
- return validationPlugin.modelDocumentPullLoader(*args, **kwargs)
38
-
39
-
40
- def modelXbrlLoadComplete(*args: Any, **kwargs: Any) -> None:
41
- return validationPlugin.modelXbrlLoadComplete(*args, **kwargs)
42
-
43
-
44
- def validateXbrlStart(*args: Any, **kwargs: Any) -> None:
45
- return validationPlugin.validateXbrlStart(*args, **kwargs)
46
-
47
-
48
- def validateXbrlFinally(*args: Any, **kwargs: Any) -> None:
49
- return validationPlugin.validateXbrlFinally(*args, **kwargs)
50
-
51
-
52
- def validateXbrlDtsDocument(*args: Any, **kwargs: Any) -> None:
53
- return validationPlugin.validateXbrlDtsDocument(*args, **kwargs)
54
-
55
-
56
- def validateFinally(*args: Any, **kwargs: Any) -> None:
57
- return validationPlugin.validateFinally(*args, **kwargs)
58
-
59
-
60
- __pluginInfo__ = {
61
- "name": PLUGIN_NAME,
62
- "version": "0.0.1",
63
- "description": "Example validation plugin for the fictitious XYZ taxonomy.",
64
- "license": "Apache-2",
65
- "author": authorLabel,
66
- "copyright": copyrightLabel,
67
- "DisclosureSystem.Types": disclosureSystemTypes,
68
- "DisclosureSystem.ConfigURL": disclosureSystemConfigURL,
69
- "ModelDocument.PullLoader": modelDocumentPullLoader,
70
- "ModelXbrl.LoadComplete": modelXbrlLoadComplete,
71
- "Validate.XBRL.Start": validateXbrlStart,
72
- "Validate.XBRL.Finally": validateXbrlFinally,
73
- "Validate.XBRL.DTS.document": validateXbrlDtsDocument,
74
- "Validate.Finally": validateFinally,
75
- }
@@ -1,16 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <DisclosureSystems
3
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
- xsi:noNamespaceSchemaLocation="../../../../config/disclosuresystems.xsd">
5
- <!-- see arelle/config/disclosuresystems.xml for full comments -->
6
- <DisclosureSystem
7
- names="XYZ 2023|XYZ-2023|xyz-2023|XYZ|xyz"
8
- description="Checks for example XYZ validation plugin for year 2023"
9
- validationType="XYZ"
10
- />
11
- <DisclosureSystem
12
- names="XYZ 2022|XYZ-2022|xyz-2022"
13
- description="Checks for example XYZ validation plugin for year 2022"
14
- validationType="XYZ"
15
- />
16
- </DisclosureSystems>
File without changes