arelle-release 2.37.46__py3-none-any.whl → 2.37.48__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.

Potentially problematic release.


This version of arelle-release might be problematic. Click here for more details.

Files changed (107) hide show
  1. arelle/CntlrCmdLine.py +10 -1
  2. arelle/ErrorManager.py +14 -5
  3. arelle/ModelObjectFactory.py +18 -2
  4. arelle/Validate.py +4 -0
  5. arelle/_version.py +2 -2
  6. arelle/plugin/validate/DBA/ValidationPluginExtension.py +2 -1
  7. arelle/plugin/validate/EDINET/ControllerPluginData.py +84 -0
  8. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +0 -114
  9. arelle/plugin/validate/EDINET/UploadContents.py +17 -0
  10. arelle/plugin/validate/EDINET/ValidationPluginExtension.py +8 -2
  11. arelle/plugin/validate/EDINET/__init__.py +5 -0
  12. arelle/plugin/validate/EDINET/rules/upload.py +66 -75
  13. arelle/plugin/validate/NL/ValidationPluginExtension.py +3 -1
  14. arelle/plugin/validate/ROS/ValidationPluginExtension.py +3 -1
  15. arelle/utils/PluginHooks.py +32 -0
  16. arelle/utils/validate/ValidationPlugin.py +54 -8
  17. {arelle_release-2.37.46.dist-info → arelle_release-2.37.48.dist-info}/METADATA +1 -1
  18. {arelle_release-2.37.46.dist-info → arelle_release-2.37.48.dist-info}/RECORD +22 -106
  19. arelle/archive/CustomLogger.py +0 -43
  20. arelle/archive/LoadEFMvalidate.py +0 -32
  21. arelle/archive/LoadSavePreLbCsv.py +0 -26
  22. arelle/archive/LoadValidate.cs +0 -31
  23. arelle/archive/LoadValidate.py +0 -36
  24. arelle/archive/LoadValidateCmdLine.java +0 -69
  25. arelle/archive/LoadValidatePostedZip.java +0 -57
  26. arelle/archive/LoadValidateWebService.java +0 -34
  27. arelle/archive/SaveTableToExelle.py +0 -140
  28. arelle/archive/TR3toTR4.py +0 -88
  29. arelle/archive/plugin/ESEF_2022/__init__.py +0 -47
  30. arelle/archive/plugin/bigInstance.py +0 -394
  31. arelle/archive/plugin/cmdWebServerExtension.py +0 -43
  32. arelle/archive/plugin/crashTest.py +0 -38
  33. arelle/archive/plugin/functionsXmlCreation.py +0 -106
  34. arelle/archive/plugin/hello_i18n.pot +0 -26
  35. arelle/archive/plugin/hello_i18n.py +0 -32
  36. arelle/archive/plugin/importTestChild1.py +0 -21
  37. arelle/archive/plugin/importTestChild2.py +0 -22
  38. arelle/archive/plugin/importTestGrandchild1.py +0 -21
  39. arelle/archive/plugin/importTestGrandchild2.py +0 -21
  40. arelle/archive/plugin/importTestImported1.py +0 -23
  41. arelle/archive/plugin/importTestImported11.py +0 -22
  42. arelle/archive/plugin/importTestParent.py +0 -48
  43. arelle/archive/plugin/instanceInfo.py +0 -306
  44. arelle/archive/plugin/loadFromOIM-2018.py +0 -1282
  45. arelle/archive/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
  46. arelle/archive/plugin/objectmaker.py +0 -285
  47. arelle/archive/plugin/packagedImportTest/__init__.py +0 -47
  48. arelle/archive/plugin/packagedImportTest/importTestChild1.py +0 -21
  49. arelle/archive/plugin/packagedImportTest/importTestChild2.py +0 -22
  50. arelle/archive/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
  51. arelle/archive/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
  52. arelle/archive/plugin/packagedImportTest/importTestImported1.py +0 -24
  53. arelle/archive/plugin/packagedImportTest/importTestImported11.py +0 -21
  54. arelle/archive/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
  55. arelle/archive/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
  56. arelle/archive/plugin/sakaCalendar.py +0 -215
  57. arelle/archive/plugin/saveInstanceInfoset.py +0 -121
  58. arelle/archive/plugin/sphinx/FormulaGenerator.py +0 -823
  59. arelle/archive/plugin/sphinx/SphinxContext.py +0 -404
  60. arelle/archive/plugin/sphinx/SphinxEvaluator.py +0 -783
  61. arelle/archive/plugin/sphinx/SphinxMethods.py +0 -1287
  62. arelle/archive/plugin/sphinx/SphinxParser.py +0 -1093
  63. arelle/archive/plugin/sphinx/SphinxValidator.py +0 -163
  64. arelle/archive/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
  65. arelle/archive/plugin/sphinx/__init__.py +0 -285
  66. arelle/archive/plugin/streamingExtensions.py +0 -335
  67. arelle/archive/plugin/updateTableLB.py +0 -242
  68. arelle/archive/plugin/validate/SBRnl/CustomLoader.py +0 -19
  69. arelle/archive/plugin/validate/SBRnl/DTS.py +0 -305
  70. arelle/archive/plugin/validate/SBRnl/Dimensions.py +0 -357
  71. arelle/archive/plugin/validate/SBRnl/Document.py +0 -799
  72. arelle/archive/plugin/validate/SBRnl/Filing.py +0 -467
  73. arelle/archive/plugin/validate/SBRnl/__init__.py +0 -75
  74. arelle/archive/plugin/validate/SBRnl/config.xml +0 -26
  75. arelle/archive/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
  76. arelle/archive/plugin/validate/USBestPractices.py +0 -570
  77. arelle/archive/plugin/validate/USCorpAction.py +0 -557
  78. arelle/archive/plugin/validate/USSecTagging.py +0 -337
  79. arelle/archive/plugin/validate/XDC/__init__.py +0 -77
  80. arelle/archive/plugin/validate/XDC/config.xml +0 -20
  81. arelle/archive/plugin/validate/XFsyntax/__init__.py +0 -64
  82. arelle/archive/plugin/validate/XFsyntax/xf.py +0 -2227
  83. arelle/archive/plugin/validate/calc2.py +0 -536
  84. arelle/archive/plugin/validateSchemaLxml.py +0 -156
  85. arelle/archive/plugin/validateTableInfoset.py +0 -52
  86. arelle/archive/us-gaap-dei-docType-extraction-frm.xml +0 -90
  87. arelle/archive/us-gaap-dei-ratio-cash-frm.xml +0 -150
  88. arelle/examples/plugin/formulaSuiteConverter.py +0 -212
  89. arelle/examples/plugin/functionsCustom.py +0 -59
  90. arelle/examples/plugin/hello_dolly.py +0 -64
  91. arelle/examples/plugin/multi.py +0 -58
  92. arelle/examples/plugin/rssSaveOim.py +0 -96
  93. arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
  94. arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
  95. arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
  96. arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
  97. arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
  98. arelle/examples/plugin/validate/XYZ/rules/__init__.py +0 -0
  99. arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -110
  100. arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -59
  101. arelle/scripts-macOS/startWebServer.command +0 -3
  102. arelle/scripts-unix/startWebServer.sh +0 -1
  103. arelle/scripts-windows/startWebServer.bat +0 -5
  104. {arelle_release-2.37.46.dist-info → arelle_release-2.37.48.dist-info}/WHEEL +0 -0
  105. {arelle_release-2.37.46.dist-info → arelle_release-2.37.48.dist-info}/entry_points.txt +0 -0
  106. {arelle_release-2.37.46.dist-info → arelle_release-2.37.48.dist-info}/licenses/LICENSE.md +0 -0
  107. {arelle_release-2.37.46.dist-info → arelle_release-2.37.48.dist-info}/top_level.txt +0 -0
@@ -1,337 +0,0 @@
1
- '''
2
- See COPYRIGHT.md for copyright information.
3
- '''
4
-
5
- from arelle import PluginManager
6
- from arelle.ModelValue import qname
7
- from arelle import XbrlConst
8
- from arelle.Version import copyrightLabel
9
- import regex as re
10
- from collections import defaultdict
11
-
12
- def compile(list, traceRows):
13
- if traceRows:
14
- # compile so each row can be traced by separate expression (slow)
15
- return [(rowNbr, re.compile(r"(^|\s)" + pattern + r"($|\W+)", re.IGNORECASE))
16
- for rowNbr, pattern in list]
17
- else:
18
- # compile single expression for fast execution
19
- return re.compile(r"(^|\s)" + # always be sure first word starts at start or after space
20
- r"($|\W+)|(^|\s)".join(pattern for rowNbr, pattern in list)
21
- .replace(r" ",r"\W+") + r"($|\W+)",
22
- re.IGNORECASE)
23
-
24
- def setup(val, traceRows=False, *args, **kwargs):
25
- if not val.validateLoggingSemantic: # all checks herein are SEMANTIC
26
- return
27
- # determiniation of two way concept label based on pattern
28
- # definitions (from documentation label) are used if present, otherwise standard label for these tests
29
- val.twoWayPriItemDefLabelPattern = compile([
30
- # from http://www.sec.gov/spotlight/xbrl/staff-review-observations-061511.shtml
31
- # Cash Flow
32
- (4, r"increase (\w+ )?decrease"),
33
- (5, r"provided by (\w+ )?used in"),
34
- (7, r"net cash inflow or outflow"),
35
- (6, r"net"),
36
- (8, r"change in"),
37
- (9, r"proceeds from (\w+ )?payments (for|to)"),
38
- # Income statement
39
- (13, r"(gain|profit) loss"),
40
- (16, r"income (expense|loss)"),
41
- (18, r"per share"),
42
- # Statement of Stockholders Equity
43
- (22, r"equity"),
44
- (23, r"retained earnings"),
45
- # removed? r"conversion of units",
46
- ], traceRows)
47
- # standard label tests, indicate two-way label
48
- val.twoWayPriItemStdLabelPattern = compile([
49
- # from Eric Cohen
50
- (4, r"Increase \(Decrease\)"),
51
- (5, r"Provided by \(Used in\)"),
52
- (6, r"Net"),
53
- (8, r"Change in"),
54
- (9, r"Proceeds from \(Payments for\)"),
55
- (10, r"Proceeds from \(Payments to\)"),
56
- (11, r"Payments for \(Proceeds from\)"),
57
- (12, r"Proceeds from \(Repayments of\)"),
58
- (13, r"Gain \(Loss\)"),
59
- (14, r"Profit \(Loss\)"),
60
- (15, r"Loss \(Gain\)"),
61
- (16, r"Income \(Loss\)"),
62
- (17, r"Income \(Expense\)"),
63
- (18, r"Per Share"),
64
- (19, r"Per Basic Share"),
65
- (20, r"Per Diluted Share"),
66
- (21, r"Per Basic and Diluted"),
67
- (24, r"Appreciation \(Depreciation\)"),
68
- (25, r"Asset \(Liability\)"),
69
- (26, r"Assets Acquired \(Liabilities Assumed\)"),
70
- (27, r"Benefit \(Expense\)"),
71
- (28, r"Expense \(Benefit\)"),
72
- (29, r"Cost[s] \(Credit[s]\)"),
73
- (30, r"Deductions \(Charges\)"),
74
- (31, r"Discount \(Premium\)"),
75
- (32, r"Due from \(to\)"),
76
- (33, r"Earnings \(Losses\)"),
77
- (34, r"Earnings \(Deficit\)"),
78
- (35, r"Excess \(Shortage\)"),
79
- (36, r"Gains \(Losses\)"),
80
- (37, r"Impairment \(Recovery\)"),
81
- (38, r"Income \(Loss\)"),
82
- (39, r"Liability \(Refund\)"),
83
- (40, r"Loss \(Recovery\)"),
84
- (41, r"Obligation[s] \(Asset[s]\)"),
85
- (42, r"Proceeds from \(Repayments of\)"),
86
- (43, r"Proceeds from \(Repurchase of\)"),
87
- (44, r"Provided by \(Used in\)"),
88
- (45, r"Provisions \(Recoveries\)"),
89
- (46, r"Retained Earnings \(Accumulated Deficit\)"),
90
- (47, r"per (\w+ )+"),
91
- (70, r"Conversion of Units"),
92
- (71, r"Effective (\w+ )?Rate"),
93
- ], traceRows)
94
- # determination of a one-way concept based on standard label
95
- val.oneWayPriItemDefLabelPattern = compile([
96
- (49, r"dividend (\w+ )*(paid|received)"),
97
- ], traceRows)
98
-
99
- val.oneWayPriItemStdLabelPattern = compile([
100
- (48, r"Payments of (\w+ )*\((Dividends|Capital)\)"),
101
- (49, r"Dividends (\w+ )*\((Pay(ment)?|Receive|Outstanding)\)"),
102
- (50, r"(Stock|Shares) Issued"),
103
- (51, r"Stock (\w+ )*Repurchased"),
104
- (52, r"(Stock|Shares) (\w+ )*Repurchase[d]?"),
105
- (53, r"Treasury Stock (\w+ )*(Beginning (\w+ )*Balance[s]?|Ending (\w+ )*Balance[s]?)"),
106
- (54, r"Treasury Stock (\w+ )*Acquired"),
107
- (55, r"Treasury Stock (\w+ )*Reissued"),
108
- (56, r"Treasury Stock (\w+ )*Retired"),
109
- (57, r"Accumulated Depreciation (\w+ )*Amortization"),
110
- (58, r"Accumulated Other Than Temporary Impairments"),
111
- (59, r"Allowance (\w+ )*Doubtful Accounts"),
112
- (60, r"Amortization (\w+ )*Pension Costs"),
113
- (61, r"Available for Sale Securities (\w+ )*Continuous Loss Position"),
114
- (62, r"Available for Sale Securities Bross Unrealized Losses"),
115
- (63, r"Accounts"),
116
- ], traceRows)
117
- # determination of a two way fact based on any of fact's dimension member label
118
- val.twoWayMemberStdLabelPattern = compile([
119
- # per Eric Cohen
120
- (64, r"Change (in|during) \w+"), # don't match word with change in it like exchange
121
- (65, r"\w+ Elimination \w+"),
122
- (66, r"Adjustment"),
123
- (67, r"Effect\s"),
124
- (68, r"Gain(s)? (\w+ )*Loss(es)?"),
125
- (69, r"Income \(Loss\)"),
126
- (70, r"Net(ting)?"), # don't want to match word with net in it like internet
127
- ], traceRows)
128
- val.schedules = {}
129
- val.elrMatches = (("1statement", re.compile(r"-\s+Statement\s+-\s+", re.IGNORECASE)),
130
- ("2disclosure", re.compile(r"-\s+Disclosure\s+-\s+", re.IGNORECASE)),
131
- ("3schedule", re.compile(r"-\s+Schedule\s+-\s+", re.IGNORECASE)))
132
-
133
- def schedules(val, concept):
134
- try:
135
- return val.schedules[concept.qname]
136
- except KeyError:
137
- schedules = defaultdict(int)
138
- for rel in val.modelXbrl.relationshipSet(XbrlConst.parentChild).toModelObject(concept):
139
- for roleType in val.modelXbrl.roleTypes.get(rel.linkrole,()):
140
- for elrType, elrPattern in val.elrMatches:
141
- if elrPattern.search(roleType.definition):
142
- schedules[elrType] += 1
143
- scheduleStr = ""
144
- for elrType, num in sorted(schedules.items()):
145
- scheduleStr += ", {0} {1}{2}".format(num, elrType[1:], "s" if num > 1 else "")
146
- val.schedules[concept.qname] = scheduleStr
147
- return scheduleStr
148
-
149
-
150
- def factCheck(val, fact, *args, **kwargs):
151
- if not val.validateLoggingSemantic: # all checks herein are SEMANTIC
152
- return
153
- concept = fact.concept
154
- context = fact.context
155
- stdLabel = concept.label(lang="en-US", fallbackToQname=False)
156
- defLabel = concept.label(preferredLabel=XbrlConst.documentationLabel, lang="en-US", fallbackToQname=False)
157
-
158
- try:
159
- if fact.isNumeric and not fact.isNil and fact.xValue is not None and fact.xValue < 0:
160
- # is fact an explicit non neg
161
- if ((defLabel is not None and val.oneWayPriItemDefLabelPattern.search(defLabel)) or
162
- (stdLabel is not None and val.oneWayPriItemStdLabelPattern.search(stdLabel))):
163
- if context.qnameDims: # if fact has a member
164
- if any((val.twoWayMemberStdLabelPattern.search(dim.member.label(lang="en-US", fallbackToQname=False))
165
- for dim in context.qnameDims.values()
166
- if dim.isExplicit)): # any two way exception member
167
- val.modelXbrl.log('INFO-SEMANTIC', "secStaffObservation.nonNegativeFact.info.A",
168
- _("Negative fact of an explicit non-negative concept is tagged with a member expected to allow negative values: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s"),
169
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
170
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
171
- else:
172
- val.modelXbrl.log('WARNING-SEMANTIC', "secStaffObservation.nonNegativeFact.warning.B",
173
- _("Negative fact of an explicit non-negative concept, member may or not justify a negative value: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s"),
174
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
175
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
176
- else: # no member
177
- val.modelXbrl.log('INCONSISTENCY', "secStaffObservation.nonNegativeFact.inconsistency.C",
178
- _("Negative fact of an explicit non-negative concept: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s %(elrTypes)s"),
179
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
180
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
181
- # else test if fact meets two way rules
182
- elif ((defLabel is not None and val.twoWayPriItemDefLabelPattern.search(defLabel)) or
183
- (stdLabel is not None and val.twoWayPriItemStdLabelPattern.search(stdLabel))):
184
- val.modelXbrl.log('INFO-SEMANTIC', "secStaffObservation.nonNegativeFact.info.D",
185
- _("Negative fact of concept expected to have positive and negative values: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s"),
186
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
187
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
188
- else:
189
- if context.qnameDims: # if fact has a member
190
- if any((val.twoWayMemberStdLabelPattern.search(dim.member.label(lang="en-US", fallbackToQname=False))
191
- for dim in context.qnameDims.values()
192
- if dim.isExplicit)): # any two way exception member
193
- val.modelXbrl.log('INFO-SEMANTIC', "secStaffObservation.nonNegativeFact.info.E",
194
- _("Negative fact for typically non-negative concept, but tagged with a member expected to allow negative values: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s"),
195
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
196
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
197
- else:
198
- val.modelXbrl.log('WARNING-SEMANTIC', "secStaffObservation.nonNegativeFact.warning.F",
199
- _("Negative fact of a typically non-negative concept, member may or not justify a negative value: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s"),
200
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
201
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
202
- else: # no member
203
- val.modelXbrl.log('INCONSISTENCY', "secStaffObservation.nonNegativeFact.inconsistency.G",
204
- _("Negative fact of a \"presumed by default\" non-negative concept: %(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s"),
205
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
206
- value=fact.effectiveValue, elrTypes=schedules(val,concept))
207
- except Exception as ex:
208
- val.modelXbrl.log('WARNING-SEMANTIC', "arelle:nonNegFactTestException",
209
- _("%(fact)s in context %(contextID)s unit %(unitID)s value %(value)s%(elrTypes)s cannot be tested nonnegative"),
210
- modelObject=fact, fact=fact.qname, contextID=fact.contextID, unitID=fact.unitID,
211
- value=fact.effectiveValue, elrTypes=schedules(val,fact))
212
-
213
- def final(val, conceptsUsed, *args, **kwargs):
214
- if not val.validateLoggingSemantic: # all checks herein are SEMANTIC
215
- return
216
- del val.twoWayPriItemDefLabelPattern
217
- del val.twoWayPriItemStdLabelPattern
218
- del val.oneWayPriItemStdLabelPattern
219
- del val.twoWayMemberStdLabelPattern
220
- del val.schedules
221
-
222
-
223
- def saveDtsMatches(dts, secDtsTagMatchesFile):
224
- setup(dts, True)
225
- import sys, csv
226
- csvOpenMode = 'w'
227
- csvOpenNewline = ''
228
- csvFile = open(secDtsTagMatchesFile, csvOpenMode, newline=csvOpenNewline)
229
- csvWriter = csv.writer(csvFile, dialect="excel")
230
- csvWriter.writerow(("Concept", "Rule", "Row", "Pattern", "Label", "Documentation"))
231
- num1wayConcepts = 0
232
- num2wayConcepts = 0
233
- num2wayMembers = 0
234
-
235
- for qname, concept in sorted(dts.qnameConcepts.items(), key=lambda item: item[0]):
236
- if concept.isItem and concept.isPrimaryItem: # both pri item and domain members
237
- stdLabel = concept.label(lang="en-US", fallbackToQname=False)
238
- defLabel = concept.label(preferredLabel=XbrlConst.documentationLabel, lang="en-US", fallbackToQname=False)
239
- if concept.type is not None and concept.type.isDomainItemType:
240
- if stdLabel is not None:
241
- for rowNbr, pattern in dts.twoWayMemberStdLabelPattern:
242
- if pattern.search(stdLabel):
243
- csvWriter.writerow((str(qname), "member-2-way", rowNbr, pattern.pattern[6:-7], stdLabel, defLabel))
244
- num2wayMembers += 1
245
- elif concept.isNumeric and not concept.isAbstract: # not dimension domain/member
246
- if defLabel is not None:
247
- for rowNbr, pattern in dts.twoWayPriItemDefLabelPattern:
248
- if pattern.search(defLabel):
249
- csvWriter.writerow((str(qname), "concept-2-way-doc", rowNbr, pattern.pattern[6:-7], stdLabel, defLabel))
250
- num2wayConcepts += 1
251
- for rowNbr, pattern in dts.oneWayPriItemDefLabelPattern:
252
- if pattern.search(defLabel):
253
- csvWriter.writerow((str(qname), "concept-1-way-doc", rowNbr, pattern.pattern[6:-7], stdLabel, defLabel))
254
- num1wayConcepts += 1
255
- if stdLabel is not None:
256
- for rowNbr, pattern in dts.twoWayPriItemStdLabelPattern:
257
- if pattern.search(stdLabel):
258
- csvWriter.writerow((str(qname), "concept-2-way-lbl", rowNbr, pattern.pattern[6:-7], stdLabel, defLabel))
259
- num2wayConcepts += 1
260
- for rowNbr, pattern in dts.oneWayPriItemStdLabelPattern:
261
- if pattern.search(stdLabel):
262
- csvWriter.writerow((str(qname), "concept-1-way-lbl", rowNbr, pattern.pattern[6:-7], stdLabel, defLabel))
263
- num1wayConcepts += 1
264
-
265
- csvFile.close()
266
-
267
- dts.log('INFO-SEMANTIC', "info:saveSecDtsTagMatches",
268
- _("SecDtsTagMatches entry %(entryFile)s has %(numberOfTwoWayPriItems)s two way primary items, %(numberOfOneWayPriItems)s one way primary items, %(numberOfTwoWayMembers)s two way members in output file %(secDtsTagMatchesFile)s."),
269
- modelObject=dts,
270
- entryFile=dts.uri,
271
- numberOfTwoWayPriItems=num2wayConcepts,
272
- numberOfOneWayPriItems=num1wayConcepts,
273
- numberOfTwoWayMembers=num2wayMembers,
274
- secDtsTagMatchesFile=secDtsTagMatchesFile)
275
-
276
- final(dts)
277
-
278
- def saveDtsMatchesMenuEntender(cntlr, menu, *args, **kwargs):
279
- # Extend menu with an item for the savedts plugin
280
- menu.add_command(label="Save SEC tag matches",
281
- underline=0,
282
- command=lambda: saveDtsMatchesMenuCommand(cntlr) )
283
-
284
- def saveDtsMatchesMenuCommand(cntlr):
285
- # save DTS menu item has been invoked
286
- if cntlr.modelManager is None or cntlr.modelManager.modelXbrl is None:
287
- cntlr.addToLog("No taxonomy loaded.")
288
- return
289
-
290
- # get file name into which to save log file while in foreground thread
291
- secDtsTagMatchesFile = cntlr.uiFileDialog("save",
292
- title=_("Save SEC DTS tag matches file"),
293
- filetypes=[(_("DTS tag matches .csv file"), "*.csv")],
294
- defaultextension=".txt")
295
- if not secDtsTagMatchesFile:
296
- return False
297
-
298
- try:
299
- saveDtsMatches(cntlr.modelManager.modelXbrl, secDtsTagMatchesFile)
300
- except Exception as ex:
301
- dts = cntlr.modelManager.modelXbrl
302
- dts.error("exception",
303
- _("SEC DTS Tags Matches exception: %(error)s"), error=ex,
304
- modelXbrl=dts,
305
- exc_info=True)
306
-
307
- def saveDtsMatchesCommandLineOptionExtender(parser, *args, **kwargs):
308
- # extend command line options with a save DTS option
309
- parser.add_option("--save-sec-tag-dts-matches",
310
- action="store",
311
- dest="secDtsTagMatchesFile",
312
- help=_("Save SEC DTS tag matches CSV file."))
313
-
314
- def saveDtsMatchesCommandLineXbrlRun(cntlr, options, modelXbrl, *args, **kwargs):
315
- # extend XBRL-loaded run processing for this option
316
- if getattr(options, "secDtsTagMatchesFile", False):
317
- if cntlr.modelManager is None or cntlr.modelManager.modelXbrl is None:
318
- cntlr.addToLog("No taxonomy loaded.")
319
- return
320
- saveDtsMatches(cntlr.modelManager.modelXbrl, options.secDtsTagMatchesFile)
321
-
322
- __pluginInfo__ = {
323
- # Do not use _( ) in pluginInfo itself (it is applied later, after loading
324
- 'name': 'Validate US SEC Tagging',
325
- 'version': '0.9',
326
- 'description': '''US SEC Tagging Validation. Includes non-negative rules.''',
327
- 'license': 'Apache-2',
328
- 'author': 'Ewe S. Gap',
329
- 'copyright': copyrightLabel,
330
- # classes of mount points (required)
331
- 'Validate.EFM.Start': setup,
332
- 'Validate.EFM.Fact': factCheck,
333
- 'Validate.EFM.Finally': final,
334
- 'CntlrWinMain.Menu.Tools': saveDtsMatchesMenuEntender,
335
- 'CntlrCmdLine.Options': saveDtsMatchesCommandLineOptionExtender,
336
- 'CntlrCmdLine.Xbrl.Run': saveDtsMatchesCommandLineXbrlRun,
337
- }
@@ -1,77 +0,0 @@
1
- '''
2
- See COPYRIGHT.md for copyright information.
3
- '''
4
- import os
5
- from arelle import ModelDocument, XbrlConst
6
- from arelle.Version import authorLabel, copyrightLabel
7
-
8
- def dislosureSystemTypes(disclosureSystem, *args, **kwargs):
9
- # return ((disclosure system name, variable name), ...)
10
- return (("XDC", "XDCplugin"),)
11
-
12
- def disclosureSystemConfigURL(disclosureSystem, *args, **kwargs):
13
- return os.path.join(os.path.dirname(__file__), "config.xml")
14
-
15
- def validateXbrlStart(val, parameters=None, *args, **kwargs):
16
- val.validateXDCplugin = val.validateDisclosureSystem and getattr(val.disclosureSystem, "XDCplugin", False)
17
- if not (val.validateXDCplugin):
18
- return
19
-
20
-
21
- def validateXbrlFinally(val, *args, **kwargs):
22
- if not (val.validateXDCplugin):
23
- return
24
-
25
- modelXbrl = val.modelXbrl
26
- modelDocument = modelXbrl.modelDocument
27
-
28
- _statusMsg = _("validating {0} filing rules").format(val.disclosureSystem.name)
29
- modelXbrl.profileActivity()
30
- modelXbrl.modelManager.showStatus(_statusMsg)
31
-
32
- if modelDocument.type in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL):
33
-
34
-
35
- parentChildRels = modelXbrl.relationshipSet(XbrlConst.parentChild)
36
- referenceRels = modelXbrl.relationshipSet(XbrlConst.conceptReference)
37
-
38
- for qn, facts in modelXbrl.factsByQname.items():
39
- concept = modelXbrl.qnameConcepts[qn]
40
- if not parentChildRels.toModelObject(concept):
41
- modelXbrl.error("XDC:factElementNotPresented",
42
- _("Element %(concept)s is used in a fact in the instance, but is not in any presentation relationships."),
43
- modelObject=facts, concept=qn)
44
-
45
- requiredConcepts = set(preRel.toModelObject.qname
46
- for preRel in parentChildRels.modelRelationships
47
- for refRel in referenceRels.fromModelObject(preRel.toModelObject)
48
- if refRel.toModelObject.role == "http://www.changhong.com/XDC/role/definitionalAttribute"
49
- for refPart in refRel.toModelObject.iterchildren()
50
- if refPart.localName == "RequiredInDocument"
51
- if refPart.textValue.strip().lower() == "true")
52
-
53
- missingConcepts = requiredConcepts - modelXbrl.factsByQname.keys()
54
- if missingConcepts:
55
- modelXbrl.error("XDC:missingRequiredFacts",
56
- _("Required facts missing from document: %(concepts)s."),
57
- modelObject=modelXbrl, concepts=", ".join(sorted(str(qn) for qn in missingConcepts)))
58
-
59
- modelXbrl.profileActivity(_statusMsg, minTimeToShow=0.0)
60
- modelXbrl.modelManager.showStatus(None)
61
-
62
-
63
- __pluginInfo__ = {
64
- # Do not use _( ) in pluginInfo itself (it is applied later, after loading
65
- 'name': 'Validate XDC',
66
- 'version': '1.0',
67
- 'description': '''XDC Validation.''',
68
- 'license': 'Apache-2',
69
- 'author': authorLabel,
70
- 'copyright': copyrightLabel,
71
- # classes of mount points (required)
72
- 'DisclosureSystem.Types': dislosureSystemTypes,
73
- 'DisclosureSystem.ConfigURL': disclosureSystemConfigURL,
74
-
75
- 'Validate.XBRL.Start': validateXbrlStart,
76
- 'Validate.XBRL.Finally': validateXbrlFinally,
77
- }
@@ -1,20 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <DisclosureSystems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
- xsi:noNamespaceSchemaLocation="../../../config/disclosuresystems.xsd" >
4
- <!-- see ../config/disclosuresystem.xml for full comments -->
5
-
6
- <DisclosureSystem
7
- names="XDC (China)|xdc"
8
- description="XDC Validation Checks\n
9
- Default language cn\n
10
- Disallowed references are processed"
11
- validationType="XDC"
12
- blockDisallowedReferences="false"
13
- defaultXmlLang="cn"
14
- defaultLanguage="Chinese"
15
- validateFileText="false"
16
- contextElement="segment"
17
- />
18
-
19
-
20
- </DisclosureSystems>
@@ -1,64 +0,0 @@
1
- '''
2
- XBRL Formula language syntax checker using ebnf parser
3
-
4
- for execution of xf formula, please instead use plug-in formulaLoader.py
5
-
6
- requires xf.py from XII conformance-formula/tf/syntax
7
-
8
- See COPYRIGHT.md for copyright information.
9
- '''
10
-
11
- import os
12
- from arelle.Version import authorLabel, copyrightLabel
13
-
14
-
15
- # interfaces for Arelle plugin operation
16
- def isXfLoadable(modelXbrl, mappedUri, normalizedUri, filepath, **kwargs):
17
- return os.path.splitext(mappedUri)[1] == ".xf"
18
-
19
- def xfLoader(modelXbrl, mappedUri, filepath, *args, **kwargs):
20
- if os.path.splitext(filepath)[1] != ".xf":
21
- return None # not an XBRL formula syntax file
22
-
23
- cntlr = modelXbrl.modelManager.cntlr
24
- cntlr.showStatus(_("Loading XBRL Formula file: {0}").format(os.path.basename(filepath)))
25
-
26
- try:
27
- import tatsu.exceptions
28
- except ImportError:
29
- modelXbrl.error("xf:missingTatsu",
30
- "Python library module Tatsu must be installed.")
31
- from .xf import XFParser
32
- with open(filepath, "r") as f:
33
- xf = f.read()
34
- parser = XFParser()
35
- try:
36
- ast = parser.parse(xf, rule_name='module')
37
- except tatsu.exceptions.FailedParse as err:
38
- modelXbrl.error("xf:syntax",
39
- "Unrecoverable error: %(error)s",
40
- modelObject=modelXbrl, error=err)
41
-
42
- # create dummy modelDocument for successful plugin execution by ModelDopcument
43
- from arelle.ModelDocument import Type, create as createModelDocument
44
- doc = createModelDocument(modelXbrl, Type.LINKBASE, filepath, documentEncoding="utf-8", initialXml='''
45
- <!-- Dummy linkbase -->
46
- <link:linkbase
47
- xmlns:link="http://www.xbrl.org/2003/linkbase"
48
- xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd"
49
- />
50
- ''')
51
- return doc
52
-
53
- __pluginInfo__ = {
54
- # Do not use _( ) in pluginInfo itself (it is applied later, after loading
55
- 'name': 'Validate XF Syntax',
56
- 'version': '1.0',
57
- 'description': '''XBRL Formula XF Syntax Validation only, not execution of formulae.''',
58
- 'license': 'Apache-2',
59
- 'author': authorLabel,
60
- 'copyright': copyrightLabel,
61
- # classes of mount points (required)
62
- 'ModelDocument.IsPullLoadable': isXfLoadable,
63
- 'ModelDocument.PullLoader': xfLoader,
64
- }