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,335 +0,0 @@
1
- '''
2
- StreamingExtensions is a plug-in to both GUI menu and command line/web service
3
- that provides an alternative approach to big instance documents without building a DOM, to save
4
- memory footprint. lxml iterparse is used to parse the big instance. ModelObjects are specialized by features
5
- for efficiency and to avoid dependency on an underlying DOM.
6
-
7
- (Note that this module is based on iterparse, the module under the installation/plugs is much faster.)
8
-
9
- See COPYRIGHT.md for copyright information.
10
- '''
11
-
12
- import io, sys, os, time
13
- from decimal import Decimal, InvalidOperation
14
- from lxml import etree
15
- from collections import defaultdict
16
- from arelle import XbrlConst, XmlUtil, XmlValidate, ValidateXbrlDimensions
17
- from arelle.ModelDocument import ModelDocument, Type
18
- from arelle.ModelObject import ModelObject
19
- from arelle.ModelObjectFactory import parser
20
- from arelle.ModelValue import QName
21
- from arelle.ModelInstanceObject import ModelContext, ModelFact, ModelUnit
22
- from arelle.Validate import Validate
23
- from arelle.Version import authorLabel, copyrightLabel
24
-
25
- _streamingExtensionsValidate = False
26
- _streamingExtensionsCheck = False
27
-
28
- def precedingProcessingInstruction(elt, target):
29
- pi = elt.getprevious()
30
- while pi is not None:
31
- if isinstance(pi, etree._ProcessingInstruction) and pi.target == target:
32
- return pi
33
- pi = pi.getprevious()
34
- return None
35
-
36
- def streamingExtensionsLoader(modelXbrl, mappedUri, filepath):
37
- # check if big instance and has header with an initial incomplete tree walk (just 2 elements
38
- def logSyntaxErrors(parsercontext):
39
- for error in parsercontext.error_log:
40
- modelXbrl.error("xmlSchema:syntax",
41
- _("%(error)s, %(fileName)s, line %(line)s, column %(column)s, %(sourceAction)s source element"),
42
- modelObject=modelDocument, fileName=os.path.basename(filepath),
43
- error=error.message, line=error.line, column=error.column, sourceAction="streaming")
44
- #### note: written for iterparse of lxml prior to version 3.3, otherwise rewrite to use XmlPullParser ###
45
- #### note: iterparse wants a binary file, but file is text mode
46
- _file, = modelXbrl.fileSource.file(filepath, binary=True)
47
- startedAt = time.time()
48
- modelXbrl.profileActivity()
49
- parsercontext = etree.iterparse(_file, events=("start","end"), huge_tree=True)
50
- foundInstance = False
51
- foundErrors = False
52
- streamingAspects = None
53
- numRootFacts1 = 0
54
- numElts = 0
55
- elt = None
56
- for event, elt in parsercontext:
57
- if event == "start":
58
- if elt.getparent() is not None:
59
- if elt.getparent().tag == "{http://www.xbrl.org/2003/instance}xbrl":
60
- if not foundInstance:
61
- foundInstance = True
62
- pi = precedingProcessingInstruction(elt, "xbrl-streamable-instance")
63
- if pi is None:
64
- break
65
- else:
66
- streamingAspects = dict(pi.attrib.copy())
67
- if not elt.tag.startswith("{http://www.xbrl.org/"):
68
- numRootFacts1 += 1
69
- if numRootFacts1 % 1000 == 0:
70
- modelXbrl.profileActivity("... streaming tree check", minTimeToShow=20.0)
71
- elif not foundInstance:
72
- break
73
- elif elt.tag == "{http://www.xbrl.org/2003/instance}xbrl" and precedingProcessingInstruction(elt, "xbrl-streamable-instance") is not None:
74
- modelXbrl.error("streamingExtensions:headerMisplaced",
75
- _("Header is misplaced: %(error)s, must follow xbrli:xbrl element"),
76
- modelObject=elt)
77
- elif event == "end":
78
- elt.clear()
79
- numElts += 1
80
- if numElts % 1000 == 0 and elt.getparent() is not None:
81
- while elt.getprevious() is not None and elt.getparent() is not None:
82
- del elt.getparent()[0]
83
- if elt is not None:
84
- elt.clear()
85
- _file.seek(0,io.SEEK_SET) # allow reparsing
86
- if not foundInstance or streamingAspects is None:
87
- del elt, parsercontext
88
- _file.close()
89
- return None
90
- modelXbrl.profileStat(_("streaming tree check"), time.time() - startedAt)
91
- startedAt = time.time()
92
- try:
93
- version = Decimal(streamingAspects.get("version"))
94
- if int(version) != 1:
95
- modelXbrl.error("streamingExtensions:unsupportedVersion",
96
- _("Streaming version %(version)s, major version number must be 1"),
97
- modelObject=elt, version=version)
98
- foundErrors = True
99
- except (InvalidOperation, OverflowError):
100
- modelXbrl.error("streamingExtensions:versionError",
101
- _("Version %(version)s, number must be 1.n"),
102
- modelObject=elt, version=streamingAspects.get("version", "(none)"))
103
- foundErrors = True
104
- for bufAspect in ("contextBuffer", "unitBuffer", "footnoteBuffer"):
105
- try:
106
- bufLimit = Decimal(streamingAspects.get(bufAspect, "INF"))
107
- if bufLimit < 1 or (bufLimit.is_finite() and bufLimit % 1 != 0):
108
- raise InvalidOperation
109
- elif bufAspect == "contextBuffer":
110
- contextBufferLimit = bufLimit
111
- elif bufAspect == "unitBuffer":
112
- unitBufferLimit = bufLimit
113
- elif bufAspect == "footnoteBuffer":
114
- footnoteBufferLimit = bufLimit
115
- except InvalidOperation:
116
- modelXbrl.error("streamingExtensions:valueError",
117
- _("Streaming %(attrib)s %(value)s, number must be a positive integer or INF"),
118
- modelObject=elt, attrib=bufAspect, value=streamingAspects.get(bufAspect))
119
- foundErrors = True
120
- if parsercontext.error_log:
121
- foundErrors = True
122
- logSyntaxErrors(parsercontext)
123
-
124
- if foundErrors:
125
- _file.close()
126
- return None
127
- parsercontext = etree.iterparse(_file, events=("start","end"), huge_tree=True)
128
- _parser, _parserLookupName, _parserLookupClass = parser(modelXbrl,filepath)
129
- eltMdlObjs = {}
130
- beforeInstanceStream = True
131
- validator = None
132
- contextBuffer = []
133
- unitBuffer = []
134
- footnoteBuffer = []
135
- factBuffer = []
136
- numFacts = numRootFacts2 = 1
137
- for event, elt in parsercontext:
138
- if event == "start":
139
- mdlObj = _parser.makeelement(elt.tag, attrib=elt.attrib, nsmap=elt.nsmap)
140
- mdlObj.sourceline = elt.sourceline
141
- eltMdlObjs[elt] = mdlObj
142
- if elt.getparent() is None:
143
- modelDocument = ModelDocument(modelXbrl, Type.INSTANCE, mappedUri, filepath, etree.ElementTree(mdlObj))
144
- modelDocument.xmlRootElement = mdlObj
145
- modelXbrl.modelDocument = modelDocument # needed for incremental validation
146
- mdlObj.init(modelDocument)
147
- modelXbrl.info("streamingExtensions:streaming",
148
- _("Stream processing this instance."),
149
- modelObject = modelDocument)
150
- else:
151
- eltMdlObjs[elt.getparent()].append(mdlObj)
152
- mdlObj._init()
153
- ns = mdlObj.namespaceURI
154
- ln = mdlObj.localName
155
- if (beforeInstanceStream and (
156
- (ns == XbrlConst.link and ln not in ("schemaRef", "linkbaseRef")) or
157
- (ns == XbrlConst.xbrli and ln in ("context", "unit")) or
158
- (ns not in (XbrlConst.link, XbrlConst.xbrli)))):
159
- beforeInstanceStream = False
160
- if _streamingExtensionsValidate:
161
- validator = Validate(modelXbrl)
162
- validator.instValidator.validate(modelXbrl, modelXbrl.modelManager.formulaOptions.typedParameters(modelXbrl.prefixedNamespaces))
163
- else: # need default dimensions
164
- ValidateXbrlDimensions.loadDimensionDefaults(modelXbrl)
165
- mdlObj = None # deref
166
-
167
- elif event == "end":
168
- mdlObj = eltMdlObjs.pop(elt)
169
- if elt.text: # text available after child nodes processed
170
- mdlObj.text = elt.text
171
- ns = mdlObj.namespaceURI
172
- ln = mdlObj.localName
173
- parentMdlObj = mdlObj.getparent()
174
- if ns == XbrlConst.xbrli:
175
- if ln == "context":
176
- if mdlObj.get("sticky"):
177
- del mdlObj.attrib["sticky"]
178
- modelDocument.contextDiscover(mdlObj)
179
- else:
180
- if _streamingExtensionsValidate and len(contextBuffer) >= contextBufferLimit:
181
- # drop before adding as dropped may have same id as added
182
- cntx = contextBuffer.pop(0)
183
- dropContext(modelXbrl, cntx)
184
- del parentMdlObj[parentMdlObj.index(cntx)]
185
- cntx = None
186
- modelDocument.contextDiscover(mdlObj)
187
- if contextBufferLimit.is_finite():
188
- contextBuffer.append(mdlObj)
189
- if _streamingExtensionsValidate:
190
- contextsToCheck = (mdlObj,)
191
- validator.instValidator.checkContexts(contextsToCheck)
192
- if modelXbrl.hasXDT:
193
- validator.instValidator.checkContextsDimensions(contextsToCheck)
194
- del contextsToCheck # dereference
195
- elif ln == "unit":
196
- if _streamingExtensionsValidate and len(unitBuffer) >= unitBufferLimit:
197
- # drop before additing as dropped may have same id as added
198
- unit = unitBuffer.pop(0)
199
- dropUnit(modelXbrl, unit)
200
- del parentMdlObj[parentMdlObj.index(unit)]
201
- unit = None
202
- modelDocument.unitDiscover(mdlObj)
203
- if unitBufferLimit.is_finite():
204
- unitBuffer.append(mdlObj)
205
- if _streamingExtensionsValidate:
206
- validator.instValidator.checkUnits( (mdlObj,) )
207
- elif ln == "xbrl": # end of document
208
- # check remaining footnote refs
209
- for footnoteLink in footnoteBuffer:
210
- checkFootnoteHrefs(modelXbrl, footnoteLink)
211
- elt.clear()
212
- elif ns == XbrlConst.link:
213
- if ln in ("schemaRef", "linkbaseRef"):
214
- modelDocument.discoverHref(mdlObj)
215
- elif ln in ("roleRef", "arcroleRef"):
216
- modelDocument.linkbaseDiscover((mdlObj,), inInstance=True)
217
- elif ln == "footnoteLink":
218
- footnoteLinks = (mdlObj,)
219
- modelDocument.linkbaseDiscover(footnoteLinks, inInstance=True)
220
- if footnoteBufferLimit.is_finite():
221
- footnoteBuffer.append(mdlObj)
222
- if _streamingExtensionsValidate:
223
- validator.instValidator.checkLinks(footnoteLinks)
224
- if len(footnoteBuffer) > footnoteBufferLimit:
225
- # check that hrefObjects for locators were all satisfied
226
- # drop before addition as dropped may have same id as added
227
- footnoteLink = footnoteBuffer.pop(0)
228
- checkFootnoteHrefs(modelXbrl, footnoteLink)
229
- dropFootnoteLink(modelXbrl, footnoteLink)
230
- del parentMdlObj[parentMdlObj.index(footnoteLink)]
231
- footnoteLink = None
232
- footnoteLinks = None
233
- elt.clear()
234
- elif parentMdlObj.qname == XbrlConst.qnXbrliXbrl:
235
- numRootFacts2 += 1
236
- modelDocument.factDiscover(mdlObj, modelXbrl.facts)
237
- XmlValidate.validate(modelXbrl, mdlObj)
238
- if _streamingExtensionsValidate:
239
- factsToCheck = (mdlObj,)
240
- validator.instValidator.checkFacts(factsToCheck)
241
- if modelXbrl.hasXDT:
242
- validator.instValidator.checkFactsDimensions(factsToCheck)
243
- del factsToCheck
244
- dropFact(modelXbrl, mdlObj, modelXbrl.facts)
245
- del parentMdlObj[parentMdlObj.index(mdlObj)]
246
- if numRootFacts2 % 1000 == 0:
247
- modelXbrl.profileActivity("... streaming fact {0} of {1} {2:.2f}%".format(numRootFacts2, numRootFacts1, 100.0 * numRootFacts2 / numRootFacts1),
248
- minTimeToShow=20.0)
249
- # get rid of root element from iterparse's tree
250
- elt.clear()
251
- while elt.getprevious() is not None: # cleans up any prior siblings
252
- del elt.getparent()[0]
253
- mdlObj = None # deref
254
- logSyntaxErrors(parsercontext)
255
- del parsercontext
256
- if validator is not None:
257
- validator.close()
258
- _file.close()
259
- modelXbrl.profileStat(_("streaming complete"), time.time() - startedAt)
260
- return modelDocument
261
-
262
- def checkFootnoteHrefs(modelXbrl, footnoteLink):
263
- for locElt in footnoteLink.iterchildren(tag="{http://www.xbrl.org/2003/linkbase}loc"):
264
- for hrefElt, doc, id in footnoteLink.modelDocument.hrefObjects:
265
- if locElt == hrefElt and id not in footnoteLink.modelDocument.idObjects:
266
- modelXbrl.error("streamingExtensions:footnoteId",
267
- _("Footnote id %(id)s not matched to fact in buffered region"),
268
- modelObject=footnoteLink, id=id)
269
-
270
- def dropContext(modelXbrl, cntx):
271
- del modelXbrl.contexts[cntx.id]
272
- dropObject(modelXbrl, cntx)
273
-
274
- def dropUnit(modelXbrl, unit):
275
- del modelXbrl.units[unit.id]
276
- dropObject(modelXbrl, unit)
277
-
278
- def dropFootnoteLink(modelXbrl, footnoteLink):
279
- for baseSet in modelXbrl.baseSets.values():
280
- if footnoteLink in baseSet:
281
- baseSet.remove(footnoteLink)
282
- dropObject(modelXbrl, footnoteLink)
283
-
284
- def dropFact(modelXbrl, fact, facts):
285
- while fact.modelTupleFacts:
286
- dropFact(modelXbrl, fact.modelTupleFacts[0], fact.modelTupleFacts)
287
- modelXbrl.factsInInstance.discard(fact)
288
- facts.remove(fact)
289
- modelXbrl.modelObjects[fact.objectIndex] = None # objects found by index, can't remove position from list
290
- fact.modelDocument.modelObjects.remove(fact)
291
- fact.clear()
292
-
293
- def dropObject(modelXbrl, mdlObj):
294
- for childObj in mdlObj.iterchildren():
295
- dropObject(modelXbrl, childObj)
296
- if mdlObj.qname == XbrlConst.qnLinkLoc:
297
- hrefs = mdlObj.modelDocument.hrefObjects
298
- removedHrefs = [i for i, hrefObj in enumerate(hrefs) if mdlObj == hrefObj[0]]
299
- for i in removedHrefs:
300
- del hrefs[i]
301
- modelXbrl.modelObjects[mdlObj.objectIndex] = None # objects found by index, can't remove position from list
302
- mdlObj.modelDocument.modelObjects.remove(mdlObj)
303
- mdlObj.modelDocument.idObjects.pop(mdlObj.id, None)
304
- mdlObj.clear()
305
-
306
- def streamingOptionsExtender(parser):
307
- parser.add_option("--check-streaming",
308
- action="store_true",
309
- dest="check_streaming",
310
- help=_('Check streamability of instance document."'))
311
-
312
- def streamingExtensionsSetup(self, options, **kwargs):
313
- global _streamingExtensionsCheck, _streamingExtensionsValidate
314
- _streamingExtensionsCheck = getattr(options, 'check_streaming', False)
315
- _streamingExtensionsValidate = options.validate
316
- if options.validate:
317
- options.validate = False # prevent cmdLine calling validation
318
-
319
- '''
320
- Do not use _( ) in pluginInfo itself (it is applied later, after loading
321
- '''
322
-
323
- __pluginInfo__ = {
324
- 'name': 'Streaming Extensions Loader',
325
- 'version': '0.9',
326
- 'description': "This plug-in loads big XBRL instances without building a DOM in memory. "
327
- "lxml iterparse parses XBRL directly into an object model without a DOM. ",
328
- 'license': 'Apache-2',
329
- 'author': authorLabel,
330
- 'copyright': copyrightLabel,
331
- # classes of mount points (required)
332
- 'CntlrCmdLine.Options': streamingOptionsExtender,
333
- 'CntlrCmdLine.Utility.Run': streamingExtensionsSetup,
334
- 'ModelDocument.PullLoader': streamingExtensionsLoader,
335
- }
@@ -1,242 +0,0 @@
1
- '''
2
- Update Table Linkbase is an example of a plug-in to both GUI menu and command line/web service
3
- that updates a table linkbase from Eurofiling 2010 syntax to XII 2011 PWD syntax and saves it.
4
-
5
- See COPYRIGHT.md for copyright information.
6
- '''
7
- from arelle.Version import authorLabel, copyrightLabel
8
-
9
- def generateUpdatedTableLB(dts, updatedTableLinkbaseFile):
10
- import os, io
11
- from arelle import XmlUtil, XbrlConst
12
- from arelle.ViewUtil import viewReferences, referenceURI
13
- from arelle.ModelRenderingObject import ModelEuAxisCoord
14
-
15
- if dts.fileSource.isArchive:
16
- dts.error("genTblLB:outFileIsArchive",
17
- _("Updated Table Linkbase file cannot be an archive: %(tableLBOutputFile)s."),
18
- modelObject=dts, tableLBOutputFile=updatedTableLinkbaseFile)
19
- return
20
- tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis)
21
- axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember)
22
- if len(tblAxisRelSet.modelRelationships) == 0:
23
- dts.error("genTblLB:noInputTables",
24
- _("DTS does not contain Eurofiling 2010 tables and axes: %(entryFile)s."),
25
- modelObject=dts, entryFile=dts.uri)
26
- return
27
-
28
- file = io.StringIO('''
29
- <nsmap>
30
- <link:linkbase
31
- xmlns:label="http://xbrl.org/2008/label"
32
- xmlns:gen="http://xbrl.org/2008/generic"
33
- xmlns:df="http://xbrl.org/2008/filter/dimension"
34
- xmlns:xlink="http://www.w3.org/1999/xlink"
35
- xmlns:reference="http://xbrl.org/2008/reference"
36
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
37
- xmlns:link="http://www.xbrl.org/2003/linkbase"
38
- xmlns:table="http://xbrl.org/2011/table"
39
- xmlns:formula="http://xbrl.org/2008/formula"
40
- xsi:schemaLocation="
41
- http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd
42
- http://xbrl.org/2008/generic http://www.xbrl.org/2008/generic-link.xsd
43
- http://xbrl.org/2008/reference http://www.xbrl.org/2008/generic-reference.xsd
44
- http://xbrl.org/2008/label http://www.xbrl.org/2008/generic-label.xsd
45
- http://xbrl.org/2011/table http://www.xbrl.org/2011/table.xsd
46
- http://xbrl.org/2008/filter/dimension http://www.xbrl.org/2008/dimension-filter.xsd">
47
- <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-filter" xlink:type="simple"
48
- xlink:href="http://www.xbrl.org/2011/table.xsd#table-filter"/>
49
- <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/table-axis" xlink:type="simple"
50
- xlink:href="http://www.xbrl.org/2011/table.xsd#table-axis"/>
51
- <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-subtree" xlink:type="simple"
52
- xlink:href="http://www.xbrl.org/2011/table.xsd#axis-subtree"/>
53
- <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2011/axis-filter" xlink:type="simple"
54
- xlink:href="http://www.xbrl.org/2011/filter-axis.xsd#axis-filter"/>
55
- </link:linkbase>
56
- </nsmap>
57
- <!-- Generated by Arelle(r) http://arelle.org -->
58
- '''
59
- )
60
- from arelle.ModelObjectFactory import parser
61
- parser, parserLookupName, parserLookupClass = parser(dts,None)
62
- from lxml import etree
63
- xmlDocument = etree.parse(file,parser=parser,base_url=updatedTableLinkbaseFile)
64
- file.close()
65
- nsmapElt = xmlDocument.getroot()
66
- #xmlDocument.getroot().init(self) ## is this needed ??
67
- for lbElement in xmlDocument.iter(tag="{http://www.xbrl.org/2003/linkbase}linkbase"):
68
- break
69
-
70
- class DocObj: # fake ModelDocument for namespaces
71
- def __init__(self):
72
- self.xmlRootElement = lbElement
73
- self.xmlDocument = xmlDocument
74
- docObj = DocObj()
75
-
76
- numELRs = 0
77
- numTables = 0
78
-
79
- def copyAttrs(fromElt, toElt, attrTags):
80
- for attr in attrTags:
81
- if fromElt.get(attr):
82
- toElt.set(attr, fromElt.get(attr))
83
-
84
- def generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, visited):
85
- if srcTblElt is not None:
86
- for rel in tblAxisRelSet.fromModelObject(srcTblElt):
87
- srcAxisElt = rel.toModelObject
88
- if isinstance(srcAxisElt, ModelEuAxisCoord):
89
- visited.add(srcAxisElt)
90
- newAxisElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}ruleAxis")
91
- copyAttrs(srcAxisElt, newAxisElt, ("id",
92
- "{http://www.w3.org/1999/xlink}type",
93
- "{http://www.w3.org/1999/xlink}label"))
94
- newAxisElt.set("abstract", "true") # always true on root element
95
- newArcElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}axisArc")
96
- copyAttrs(rel, newArcElt, ("id",
97
- "{http://www.w3.org/1999/xlink}type",
98
- "{http://www.w3.org/1999/xlink}from",
99
- "{http://www.w3.org/1999/xlink}to",
100
- "order"))
101
- newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableBreakdown)
102
- newArcElt.set("axisDisposition", rel.axisDisposition)
103
- generateAxis(newLinkElt, newAxisElt, srcAxisElt, axisMbrRelSet, visited)
104
- visited.discard(srcAxisElt)
105
-
106
- def generateAxis(newLinkElt, newAxisParentElt, srcAxisElt, axisMbrRelSet, visited):
107
- for rel in axisMbrRelSet.fromModelObject(srcAxisElt):
108
- tgtAxisElt = rel.toModelObject
109
- if isinstance(tgtAxisElt, ModelEuAxisCoord) and tgtAxisElt not in visited:
110
- visited.add(tgtAxisElt)
111
- newAxisElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}ruleAxis")
112
- copyAttrs(tgtAxisElt, newAxisElt, ("id",
113
- "abstract",
114
- "{http://www.w3.org/1999/xlink}type",
115
- "{http://www.w3.org/1999/xlink}label"))
116
- if tgtAxisElt.primaryItemQname:
117
- newRuleElt = etree.SubElement(newAxisElt, "{http://xbrl.org/2008/formula}concept")
118
- newQnameElt = etree.SubElement(newRuleElt, "{http://xbrl.org/2008/formula}qname")
119
- newQnameElt.text = XmlUtil.addQnameValue(docObj, tgtAxisElt.primaryItemQname)
120
- for dimQname, memQname in tgtAxisElt.explicitDims:
121
- newRuleElt = etree.SubElement(newAxisElt, "{http://xbrl.org/2008/formula}explicitDimension")
122
- newRuleElt.set("dimension", XmlUtil.addQnameValue(docObj, dimQname))
123
- newMbrElt = etree.SubElement(newRuleElt, "{http://xbrl.org/2008/formula}member")
124
- newQnameElt = etree.SubElement(newMbrElt, "{http://xbrl.org/2008/formula}qname")
125
- newQnameElt.text = XmlUtil.addQnameValue(docObj, memQname)
126
- newArcElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}axisArc")
127
- copyAttrs(rel, newArcElt, ("id",
128
- "{http://www.w3.org/1999/xlink}type",
129
- "{http://www.w3.org/1999/xlink}from",
130
- "{http://www.w3.org/1999/xlink}to",
131
- "order"))
132
- newArcElt.set("{http://www.w3.org/1999/xlink}arcrole", XbrlConst.tableAxisSubtree)
133
- generateAxis(newLinkElt, newAxisElt, tgtAxisElt, axisMbrRelSet, visited)
134
- visited.discard(tgtAxisElt)
135
-
136
- # sort URIs
137
- linkroleUris = sorted([linkroleUri
138
- for linkroleUri in tblAxisRelSet.linkRoleUris])
139
-
140
- firstNewLinkElt = None
141
- roleRefUris = set()
142
- for linkroleUri in linkroleUris:
143
- numELRs += 1
144
- newLinkElt = etree.SubElement(lbElement, "{http://xbrl.org/2008/generic}link")
145
- newLinkElt.set("{http://www.w3.org/1999/xlink}type", "extended")
146
- newLinkElt.set("{http://www.w3.org/1999/xlink}role", linkroleUri)
147
- if firstNewLinkElt is None: firstNewLinkElt = newLinkElt
148
- # To do: add roleRef if needed
149
- tblAxisRelSet = dts.relationshipSet(XbrlConst.euTableAxis, linkroleUri)
150
- axisMbrRelSet = dts.relationshipSet(XbrlConst.euAxisMember, linkroleUri)
151
- for srcTblElt in tblAxisRelSet.rootConcepts:
152
- if srcTblElt.tag == "{http://www.eurofiling.info/2010/rendering}table":
153
- numTables += 1
154
- newTblElt = etree.SubElement(newLinkElt, "{http://xbrl.org/2011/table}table")
155
- newTblElt.set("aspectModel", "dimensional")
156
- copyAttrs(srcTblElt, newTblElt, ("id",
157
- "{http://www.w3.org/1999/xlink}type",
158
- "{http://www.w3.org/1999/xlink}label"))
159
- generateTable(newLinkElt, newTblElt, srcTblElt, tblAxisRelSet, axisMbrRelSet, set())
160
-
161
- if linkroleUri not in roleRefUris:
162
- srcRoleRefElt = XmlUtil.descendant(srcTblElt.getroottree(), XbrlConst.link, "roleRef", "roleURI", linkroleUri)
163
- if srcRoleRefElt is not None:
164
- roleRefUris.add(linkroleUri)
165
- newRoleRefElt = etree.Element("{http://www.xbrl.org/2003/linkbase}roleRef")
166
- copyAttrs(srcRoleRefElt, newRoleRefElt, ("roleURI",
167
- "{http://www.w3.org/1999/xlink}type",
168
- "{http://www.w3.org/1999/xlink}href"))
169
- firstNewLinkElt.addprevious(newRoleRefElt)
170
-
171
- fh = open(updatedTableLinkbaseFile, "w", encoding="utf-8")
172
- XmlUtil.writexml(fh, xmlDocument, encoding="utf-8")
173
- fh.close()
174
-
175
- dts.info("info:updateTableLinkbase",
176
- _("Updated Table Linkbase of %(entryFile)s has %(numberOfLinkroles)s linkroles, %(numberOfTables)s tables in file %(tableLBOutputFile)s."),
177
- modelObject=dts,
178
- entryFile=dts.uri, numberOfLinkroles=numELRs, numberOfTables=numTables, tableLBOutputFile=updatedTableLinkbaseFile)
179
-
180
- def updateTableLBMenuEntender(cntlr, menu):
181
- # Extend menu with an item for the savedts plugin
182
- menu.add_command(label="Update table linkbase",
183
- underline=0,
184
- command=lambda: updateTableLBMenuCommand(cntlr) )
185
-
186
- def updateTableLBMenuCommand(cntlr):
187
- # save DTS menu item has been invoked
188
- if cntlr.modelManager is None or cntlr.modelManager.modelXbrl is None:
189
- cntlr.addToLog("No taxonomy loaded.")
190
- return
191
-
192
- # get file name into which to save log file while in foreground thread
193
- updatedTableLinkbaseFile = cntlr.uiFileDialog("save",
194
- title=_("arelle - Save Updated Table Linkbase file"),
195
- initialdir=cntlr.config.setdefault("tableLinkbaseFileDir","."),
196
- filetypes=[(_("Linkbase file .xml"), "*.xml")],
197
- defaultextension=".xml")
198
- if not updatedTableLinkbaseFile:
199
- return False
200
- import os
201
- cntlr.config["tableLinkbaseFileDir"] = os.path.dirname(updatedTableLinkbaseFile)
202
- cntlr.saveConfig()
203
-
204
- try:
205
- generateUpdatedTableLB(cntlr.modelManager.modelXbrl, updatedTableLinkbaseFile)
206
- except Exception as ex:
207
- dts = cntlr.modelManager.modelXbrl
208
- dts.error("exception",
209
- _("Updated table linkbase generation exception: %(error)s"), error=ex,
210
- modelXbrl=dts,
211
- exc_info=True)
212
-
213
- def updateTableLBCommandLineOptionExtender(parser):
214
- # extend command line options with a save DTS option
215
- parser.add_option("--save-updated-table-linkbase",
216
- action="store",
217
- dest="updatedTableLinkbaseFile",
218
- help=_("Update table linkbase file from Eurofiling 2010 to XII 2011 syntax."))
219
-
220
- def updateTableLBCommandLineXbrlRun(cntlr, options, modelXbrl, *args, **kwargs):
221
- # extend XBRL-loaded run processing for this option
222
- if getattr(options, "updatedTableLinkbaseFile", None):
223
- if cntlr.modelManager is None or cntlr.modelManager.modelXbrl is None:
224
- cntlr.addToLog("No taxonomy loaded.")
225
- return
226
- generateUpdatedTableLB(cntlr.modelManager.modelXbrl, options.updatedTableLinkbaseFile)
227
-
228
-
229
- __pluginInfo__ = {
230
- 'name': 'Update Table Linkbase',
231
- 'version': '0.9',
232
- 'description': "This plug-in updates a table linkbase from Eurofiling 2010 syntax to XII 2011 PWD syntax. "
233
- "The updated linkbase is saved to a local file. "
234
- "Hrefs in the new file are identical the prior hrefs (not offset considering save-to directory). ",
235
- 'license': 'Apache-2',
236
- 'author': authorLabel,
237
- 'copyright': copyrightLabel,
238
- # classes of mount points (required)
239
- 'CntlrWinMain.Menu.Tools': updateTableLBMenuEntender,
240
- 'CntlrCmdLine.Options': updateTableLBCommandLineOptionExtender,
241
- 'CntlrCmdLine.Xbrl.Run': updateTableLBCommandLineXbrlRun,
242
- }
@@ -1,19 +0,0 @@
1
- '''
2
- See COPYRIGHT.md for copyright information.
3
- '''
4
- import regex as re
5
-
6
- def checkForBOMs(modelXbrl, file, mappedUri, filepath, *args, **kwargs):
7
- # callback is for all opened docs, must only process when SBRNL validation active
8
- if (modelXbrl.modelManager.validateDisclosureSystem and
9
- # corrected merge of pre-plugin code per LOGIUS
10
- getattr(modelXbrl.modelManager.validateDisclosureSystem, "SBRNLplugin", False)):
11
- #must read file in binary and return nothing to not replace standard loading
12
- with open(filepath, 'rb') as fb:
13
- startingBytes = fb.read(8)
14
- if re.match(b"\\x00\\x00\\xFE\\xFF|\\xFF\\xFE\\x00\\x00|\\x2B\\x2F\\x76\\x38|\\x2B\\x2F\\x76\\x39|\\x2B\\x2F\\x76\\x2B|\\x2B\\x2F\\x76\\x2F|\\xDD\\x73\\x66\\x73|\\xEF\\xBB\\xBF|\\x0E\\xFE\\xFF|\\xFB\\xEE\\x28|\\xFE\\xFF|\\xFF\\xFE",
15
- startingBytes):
16
- modelXbrl.error("SBR.NL.2.1.0.09",
17
- _("File MUST not start with a Byte Order Mark (BOM): %(filename)s"),
18
- modelObject=modelXbrl, filename=mappedUri)
19
- return None # must return None for regular document loading to continue