arelle-release 2.37.47__py3-none-any.whl → 2.37.49__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 (100) hide show
  1. arelle/CntlrCmdLine.py +5 -1
  2. arelle/ModelObjectFactory.py +18 -2
  3. arelle/_version.py +2 -2
  4. arelle/plugin/validate/EDINET/Constants.py +6 -0
  5. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +134 -7
  6. arelle/plugin/validate/EDINET/Statement.py +139 -0
  7. arelle/plugin/validate/EDINET/rules/contexts.py +5 -10
  8. arelle/plugin/validate/EDINET/rules/edinet.py +89 -51
  9. arelle/plugin/validate/EDINET/rules/gfm.py +41 -0
  10. {arelle_release-2.37.47.dist-info → arelle_release-2.37.49.dist-info}/METADATA +3 -1
  11. {arelle_release-2.37.47.dist-info → arelle_release-2.37.49.dist-info}/RECORD +15 -99
  12. arelle/archive/CustomLogger.py +0 -43
  13. arelle/archive/LoadEFMvalidate.py +0 -32
  14. arelle/archive/LoadSavePreLbCsv.py +0 -26
  15. arelle/archive/LoadValidate.cs +0 -31
  16. arelle/archive/LoadValidate.py +0 -36
  17. arelle/archive/LoadValidateCmdLine.java +0 -69
  18. arelle/archive/LoadValidatePostedZip.java +0 -57
  19. arelle/archive/LoadValidateWebService.java +0 -34
  20. arelle/archive/SaveTableToExelle.py +0 -140
  21. arelle/archive/TR3toTR4.py +0 -88
  22. arelle/archive/plugin/ESEF_2022/__init__.py +0 -47
  23. arelle/archive/plugin/bigInstance.py +0 -394
  24. arelle/archive/plugin/cmdWebServerExtension.py +0 -43
  25. arelle/archive/plugin/crashTest.py +0 -38
  26. arelle/archive/plugin/functionsXmlCreation.py +0 -106
  27. arelle/archive/plugin/hello_i18n.pot +0 -26
  28. arelle/archive/plugin/hello_i18n.py +0 -32
  29. arelle/archive/plugin/importTestChild1.py +0 -21
  30. arelle/archive/plugin/importTestChild2.py +0 -22
  31. arelle/archive/plugin/importTestGrandchild1.py +0 -21
  32. arelle/archive/plugin/importTestGrandchild2.py +0 -21
  33. arelle/archive/plugin/importTestImported1.py +0 -23
  34. arelle/archive/plugin/importTestImported11.py +0 -22
  35. arelle/archive/plugin/importTestParent.py +0 -48
  36. arelle/archive/plugin/instanceInfo.py +0 -306
  37. arelle/archive/plugin/loadFromOIM-2018.py +0 -1282
  38. arelle/archive/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
  39. arelle/archive/plugin/objectmaker.py +0 -285
  40. arelle/archive/plugin/packagedImportTest/__init__.py +0 -47
  41. arelle/archive/plugin/packagedImportTest/importTestChild1.py +0 -21
  42. arelle/archive/plugin/packagedImportTest/importTestChild2.py +0 -22
  43. arelle/archive/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
  44. arelle/archive/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
  45. arelle/archive/plugin/packagedImportTest/importTestImported1.py +0 -24
  46. arelle/archive/plugin/packagedImportTest/importTestImported11.py +0 -21
  47. arelle/archive/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
  48. arelle/archive/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
  49. arelle/archive/plugin/sakaCalendar.py +0 -215
  50. arelle/archive/plugin/saveInstanceInfoset.py +0 -121
  51. arelle/archive/plugin/sphinx/FormulaGenerator.py +0 -823
  52. arelle/archive/plugin/sphinx/SphinxContext.py +0 -404
  53. arelle/archive/plugin/sphinx/SphinxEvaluator.py +0 -783
  54. arelle/archive/plugin/sphinx/SphinxMethods.py +0 -1287
  55. arelle/archive/plugin/sphinx/SphinxParser.py +0 -1093
  56. arelle/archive/plugin/sphinx/SphinxValidator.py +0 -163
  57. arelle/archive/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
  58. arelle/archive/plugin/sphinx/__init__.py +0 -285
  59. arelle/archive/plugin/streamingExtensions.py +0 -335
  60. arelle/archive/plugin/updateTableLB.py +0 -242
  61. arelle/archive/plugin/validate/SBRnl/CustomLoader.py +0 -19
  62. arelle/archive/plugin/validate/SBRnl/DTS.py +0 -305
  63. arelle/archive/plugin/validate/SBRnl/Dimensions.py +0 -357
  64. arelle/archive/plugin/validate/SBRnl/Document.py +0 -799
  65. arelle/archive/plugin/validate/SBRnl/Filing.py +0 -467
  66. arelle/archive/plugin/validate/SBRnl/__init__.py +0 -75
  67. arelle/archive/plugin/validate/SBRnl/config.xml +0 -26
  68. arelle/archive/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
  69. arelle/archive/plugin/validate/USBestPractices.py +0 -570
  70. arelle/archive/plugin/validate/USCorpAction.py +0 -557
  71. arelle/archive/plugin/validate/USSecTagging.py +0 -337
  72. arelle/archive/plugin/validate/XDC/__init__.py +0 -77
  73. arelle/archive/plugin/validate/XDC/config.xml +0 -20
  74. arelle/archive/plugin/validate/XFsyntax/__init__.py +0 -64
  75. arelle/archive/plugin/validate/XFsyntax/xf.py +0 -2227
  76. arelle/archive/plugin/validate/calc2.py +0 -536
  77. arelle/archive/plugin/validateSchemaLxml.py +0 -156
  78. arelle/archive/plugin/validateTableInfoset.py +0 -52
  79. arelle/archive/us-gaap-dei-docType-extraction-frm.xml +0 -90
  80. arelle/archive/us-gaap-dei-ratio-cash-frm.xml +0 -150
  81. arelle/examples/plugin/formulaSuiteConverter.py +0 -212
  82. arelle/examples/plugin/functionsCustom.py +0 -59
  83. arelle/examples/plugin/hello_dolly.py +0 -64
  84. arelle/examples/plugin/multi.py +0 -58
  85. arelle/examples/plugin/rssSaveOim.py +0 -96
  86. arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
  87. arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
  88. arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -50
  89. arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
  90. arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
  91. arelle/examples/plugin/validate/XYZ/rules/__init__.py +0 -0
  92. arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -110
  93. arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -59
  94. arelle/scripts-macOS/startWebServer.command +0 -3
  95. arelle/scripts-unix/startWebServer.sh +0 -1
  96. arelle/scripts-windows/startWebServer.bat +0 -5
  97. {arelle_release-2.37.47.dist-info → arelle_release-2.37.49.dist-info}/WHEEL +0 -0
  98. {arelle_release-2.37.47.dist-info → arelle_release-2.37.49.dist-info}/entry_points.txt +0 -0
  99. {arelle_release-2.37.47.dist-info → arelle_release-2.37.49.dist-info}/licenses/LICENSE.md +0 -0
  100. {arelle_release-2.37.47.dist-info → arelle_release-2.37.49.dist-info}/top_level.txt +0 -0
@@ -1,404 +0,0 @@
1
- '''
2
- sphinxContext provides the validation and execution context for Sphinx language expressions.
3
-
4
- See COPYRIGHT.md for copyright information.
5
-
6
- Sphinx is a Rules Language for XBRL described by a Sphinx 2 Primer
7
- (c) Copyright 2012 CoreFiling, Oxford UK.
8
- Sphinx copyright applies to the Sphinx language, not to this software.
9
- Workiva, Inc. conveys neither rights nor license for the Sphinx language.
10
- '''
11
-
12
- from collections import OrderedDict
13
- from .SphinxParser import astNode, astWith
14
- from arelle.ModelFormulaObject import aspectModels, Aspect, aspectStr
15
- from arelle.ModelInstanceObject import ModelFact, ModelDimensionValue
16
- from arelle.formula.FormulaEvaluator import implicitFilter, aspectsMatch
17
- from arelle.ModelValue import QName
18
- from arelle.ModelXbrl import DEFAULT, NONDEFAULT
19
- from arelle import XmlUtil
20
-
21
- class SphinxContext:
22
- def __init__(self, sphinxProgs, modelXbrl=None):
23
- self.modelXbrl = modelXbrl # the DTS and input instance (if any)
24
- self.sphinxProgs = sphinxProgs
25
- self.rules = []
26
- self.transformQnames = {}
27
- self.transformNamespaces = {}
28
- self.constants = {}
29
- self.taggedConstants = {}
30
- self.functions = {}
31
- self.preconditions = {}
32
- self.localVariables = {}
33
- self.tags = {}
34
- self.hyperspaceBindings = None
35
- self.staticSeverity = None
36
- self.dynamicSeverity = None
37
- self.dimensionIsExplicit = {} # qname of dimension (axis), True if explicit, False if typed
38
- if modelXbrl is not None:
39
- self.formulaOptions = modelXbrl.modelManager.formulaOptions
40
- self.defaultDimensionAspects = set(modelXbrl.qnameDimensionDefaults.keys())
41
-
42
- def close(self):
43
- # dereference grammar
44
- for prog in self.sphinxProgs:
45
- for node in prog:
46
- if isinstance(node, astNode):
47
- node.clear()
48
- prog.clear
49
- del self.sphinxProgs[:]
50
- self.__dict__.clear() # delete local attributes
51
-
52
- class HyperspaceBindings:
53
- def __init__(self, sphinxContext):
54
- self.sCtx = sphinxContext
55
- self.parentHyperspaceBindings = sphinxContext.hyperspaceBindings
56
- sphinxContext.hyperspaceBindings = self
57
- self.hyperspaceBindings = []
58
- self.nodeBindings = {}
59
- self.withRestrictionBindings = []
60
- self.aspectBoundFacts = {}
61
- self.aggregationNode = None
62
- self.isValuesIteration = False
63
-
64
- def close(self):
65
- if self.sCtx.hyperspaceBindings is self:
66
- self.sCtx.hyperspaceBindings = self.parentHyperspaceBindings
67
- for hsBinding in self.hyperspaceBindings:
68
- hsBinding.close()
69
- self.__dict__.clear() # dereference
70
-
71
- def nodeBinding(self, node, isWithRestrictionNode=False):
72
- if node in self.nodeBindings:
73
- return self.nodeBindings[node]
74
- if self.aggregationNode and self.aggregationNode not in self.nodeBindings and not self.isValuesIteration:
75
- agrgBalNode = HyperspaceBinding(self, node, isBalancingBinding=True)
76
- self.nodeBindings[self.aggregationNode] = agrgBalNode
77
- nodeBinding = HyperspaceBinding(self, node, isWithRestrictionNode=isWithRestrictionNode)
78
- self.nodeBindings[node] = nodeBinding
79
- self.hyperspaceBindings.append(nodeBinding)
80
- return nodeBinding
81
-
82
- def forBinding(self, node):
83
- if node in self.nodeBindings:
84
- return self.nodeBindings[node]
85
- nodeBinding = ForBinding(self, node)
86
- self.nodeBindings[node] = nodeBinding
87
- self.hyperspaceBindings.append(nodeBinding)
88
- return nodeBinding
89
-
90
- def next(self, iterateAbove=-1, bindingsLen=-1):
91
- # iterate hyperspace bindings
92
- if not self.hyperspaceBindings:
93
- raise StopIteration
94
- hsBsToReset = []
95
- if bindingsLen == -1:
96
- bindingsLen = len(self.hyperspaceBindings)
97
- for iHsB in range(bindingsLen - 1, iterateAbove, -1):
98
- hsB = self.hyperspaceBindings[iHsB]
99
- try:
100
- hsB.next()
101
- for hsB in hsBsToReset:
102
- hsB.reset()
103
- return # hsB has another value to return
104
- except StopIteration:
105
- hsBsToReset.insert(0, hsB) # reset after outer iterator advanced
106
- raise StopIteration # no more outermost loop of iteration
107
-
108
- @property
109
- def boundFacts(self):
110
- return [binding.yieldedFact
111
- for binding in self.hyperspaceBindings
112
- if isinstance(binding, HyperspaceBinding) and
113
- not binding.fallenBack and binding.yieldedFact is not None]
114
-
115
- class HyperspaceBinding:
116
- def __init__(self, hyperspaceBindings, node, fallback=False, isWithRestrictionNode=False, isBalancingBinding=False):
117
- self.hyperspaceBindings = hyperspaceBindings
118
- self.sCtx = hyperspaceBindings.sCtx
119
- self.node = node
120
- self.isWithRestrictionNode = isWithRestrictionNode
121
- self.isBalancingBinding = isBalancingBinding
122
- self.isValuesIteration = hyperspaceBindings.isValuesIteration
123
- self.fallback = fallback
124
- self.aspectsQualified = set()
125
- self.aspectsDefined = set(aspectModels["dimensional"])
126
- if hyperspaceBindings.withRestrictionBindings:
127
- withAspectsQualified = hyperspaceBindings.withRestrictionBindings[-1].aspectsQualified
128
- else:
129
- withAspectsQualified = set()
130
- # axes from macros need to be expanded
131
- self.aspectAxisTuples = []
132
- self.axesAspects = set()
133
- for hsAxis in node.axes:
134
- if hsAxis.aspect: # no aspect if just a where clause
135
- aspect = evaluate(hsAxis.aspect, self.sCtx, value=True)
136
- if aspect not in self.aspectsDefined and not isinstance(aspect, QName):
137
- raise SphinxException(node, "sphinx:aspectValue",
138
- _("Hyperspace aspect indeterminate %(aspect)s"),
139
- aspect=aspect)
140
- if isinstance(aspect, QName):
141
- if aspect not in self.sCtx.dimensionIsExplicit: # probably dynamic macro aspect
142
- concept = self.sCtx.modelXbrl.qnameConcepts.get(aspect)
143
- if concept is None or not concept.isDimensionItem:
144
- raise SphinxException(node, "sphinxDynamicHyperspace:axisNotDimension",
145
- _("Axis aspect is not a dimension in the DTS %(aspect)s"),
146
- aspect=aspect)
147
- self.sCtx.dimensionIsExplicit[aspect] = concept.isExplicitDimension
148
- self.axesAspects.add(aspect) # resolved aspect value
149
- self.aspectAxisTuples.append( (aspect, hsAxis) )
150
- self.aspectsQualified = self.axesAspects | withAspectsQualified
151
- self.reset() # will raise StopIteration if no facts or fallback
152
-
153
- def close(self):
154
- self.__dict__.clear() # dereference
155
-
156
- @property
157
- def value(self):
158
- if self.fallenBack:
159
- return None
160
- if self.yieldedFact is not None:
161
- return self.yieldedFact.xValue
162
- return None
163
-
164
- @property
165
- def var(self): # used in implicitFilter winnowing trace
166
- return []
167
-
168
- @property
169
- def qname(self): # used in implicitFilter winnowing trace
170
- return ''
171
-
172
- def __repr__(self):
173
- if self.fallenBack:
174
- return "fallen-back"
175
- if self.yieldedFact is not None:
176
- return self.yieldedFact.__repr__()
177
- return "none"
178
-
179
- def reset(self):
180
- # start with all facts
181
- if self.hyperspaceBindings.withRestrictionBindings:
182
- facts = self.hyperspaceBindings.withRestrictionBindings[-1].yieldedFactsPartition
183
- else:
184
- facts = self.sCtx.modelXbrl.nonNilFactsInInstance
185
- if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
186
- self.sCtx.modelXbrl.info("sphinx:trace",
187
- _("Hyperspace %(variable)s binding: start with %(factCount)s facts"),
188
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node), factCount=len(facts))
189
- # filter by hyperspace aspects
190
- facts = self.filterFacts(facts)
191
- for fact in facts:
192
- if fact.isItem:
193
- self.aspectsDefined |= fact.context.dimAspects(self.sCtx.defaultDimensionAspects)
194
- self.unQualifiedAspects = self.aspectsDefined - self.aspectsQualified - {Aspect.DIMENSIONS}
195
- # implicitly filter by prior uncoveredAspectFacts
196
- if self.hyperspaceBindings.aspectBoundFacts and not self.isValuesIteration:
197
- facts = implicitFilter(self.sCtx, self, facts, self.unQualifiedAspects, self.hyperspaceBindings.aspectBoundFacts)
198
- if self.sCtx.formulaOptions.traceVariableFiltersResult:
199
- self.sCtx.modelXbrl.info("sphinx:trace",
200
- _("Hyperspace %(variable)s binding: filters result %(factCount)s facts"),
201
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node), factCount=len(facts))
202
- if self.isWithRestrictionNode: # if withNode, combine facts into partitions by qualified aspects
203
- factsPartitions = []
204
- for fact in facts:
205
- matched = False
206
- for partition in factsPartitions:
207
- if aspectsMatch(self.sCtx, fact, partition[0], self.aspectsQualified):
208
- partition.append(fact)
209
- matched = True
210
- break
211
- if not matched:
212
- factsPartitions.append([fact,])
213
- self.factIter = iter([set(p) for p in factsPartitions]) # must be sets
214
- self.yieldedFactsPartition = []
215
- else: # just a hyperspaceExpression node
216
- self.factIter = iter(facts)
217
- self.yieldedFact = None
218
- self.fallenBack = False
219
- self.next()
220
-
221
-
222
- def next(self): # will raise StopIteration if no (more) facts or fallback
223
- uncoveredAspectFacts = self.hyperspaceBindings.aspectBoundFacts
224
- if self.yieldedFact is not None and self.hyperspaceBindings.aggregationNode is None:
225
- for aspect, priorFact in self.evaluationContributedUncoveredAspects.items():
226
- if priorFact == "none":
227
- del uncoveredAspectFacts[aspect]
228
- else:
229
- uncoveredAspectFacts[aspect] = priorFact
230
- self.evaluationContributedUncoveredAspects.clear()
231
- try:
232
- if self.isWithRestrictionNode:
233
- self.yieldedFactsPartition = next(self.factIter)
234
- for self.yieldedFact in self.yieldedFactsPartition:
235
- break
236
- else:
237
- self.yieldedFact = next(self.factIter)
238
- self.evaluationContributedUncoveredAspects = {}
239
- if not self.isValuesIteration:
240
- for aspect in self.unQualifiedAspects: # covered aspects may not be defined e.g., test 12062 v11, undefined aspect is a complemented aspect
241
- if uncoveredAspectFacts.get(aspect) is None:
242
- self.evaluationContributedUncoveredAspects[aspect] = uncoveredAspectFacts.get(aspect,"none")
243
- uncoveredAspectFacts[aspect] = None if aspect in self.axesAspects else self.yieldedFact
244
- if self.sCtx.formulaOptions.traceVariableFiltersResult:
245
- self.sCtx.modelXbrl.info("sphinx:trace",
246
- _("Hyperspace %(variable)s: bound value %(result)s"),
247
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node), result=str(self.yieldedFact))
248
- except StopIteration:
249
- self.yieldedFact = None
250
- if self.isWithRestrictionNode:
251
- self.yieldedFactsPartition = []
252
- if self.fallback and not self.fallenBack:
253
- self.fallenBack = True
254
- if self.sCtx.formulaOptions.traceVariableExpressionResult:
255
- self.sCtx.modelXbrl.info("sphinx:trace",
256
- _("Hyperspace %(variable)s: fallbackValue result %(result)s"),
257
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node), result=0)
258
- else:
259
- raise StopIteration
260
-
261
- def filterFacts(self, facts):
262
- modelXbrl = self.sCtx.modelXbrl
263
- # process with bindings and this node
264
- for i, aspectAxis in enumerate(self.aspectAxisTuples):
265
- aspect, hsAxis = aspectAxis
266
- # value is an astHyperspaceAxis
267
- if hsAxis.restriction:
268
- restriction = evaluate(hsAxis.restriction, self.sCtx, value=True)
269
- if aspect == Aspect.CONCEPT:
270
- aspectQualifiedFacts = [modelXbrl.factsByQname[qn]
271
- for qn in restriction
272
- if isinstance(qn, QName)]
273
- facts = facts & set.union(*aspectQualifiedFacts) if aspectQualifiedFacts else set()
274
- elif aspect == Aspect.PERIOD:
275
- facts = set(f for f in facts if isPeriodEqualTo(f, restriction))
276
- elif aspect == Aspect.ENTITY_IDENTIFIER:
277
- facts = set(f for f in facts if isEntityIdentifierEqualTo(f, restriction))
278
- elif isinstance(aspect, QName):
279
- if self.sCtx.dimensionIsExplicit.get(aspect):
280
- # explicit dim facts (value None will match the default member)
281
- aspectQualifiedFacts = []
282
- for qn in restriction:
283
- if self.isBalancingBinding: # complement dimension for aggregation balancing binding
284
- if isinstance(qn, QName) or qn is NONDEFAULT:
285
- qn = DEFAULT
286
- else:
287
- qn = NONDEFAULT
288
- if qn is NONE:
289
- qn = DEFAULT
290
- elif not (isinstance(qn, QName) or qn is DEFAULT or qn is NONDEFAULT):
291
- continue
292
- aspectQualifiedFacts.append(modelXbrl.factsByDimMemQname(aspect, qn))
293
- facts = facts & set.union(*aspectQualifiedFacts) if aspectQualifiedFacts else set()
294
- else:
295
- facts = facts & set(fact
296
- for fact in facts
297
- for typedDimValue in hsAxis.restriction
298
- if typedDimTest(aspect, typedDimValue, fact))
299
- if hsAxis.whereExpr and facts: # process where against facts passing restriction
300
- whereMatchedFacts = set()
301
- asVars = set()
302
- for fact in facts:
303
- for asAspectAxis in self.aspectAxisTuples[0:i+1]:
304
- asAspect, asHsAxis = asAspectAxis
305
- if asHsAxis.asVariableName:
306
- self.sCtx.localVariables[asHsAxis.asVariableName] = factAspectValue(fact, asAspect)
307
- asVars.add(asHsAxis.asVariableName)
308
- self.sCtx.localVariables["item"] = fact
309
- if evaluate(hsAxis.whereExpr, self.sCtx) ^ self.isBalancingBinding:
310
- whereMatchedFacts.add(fact)
311
- del self.sCtx.localVariables["item"]
312
- for asVar in asVars:
313
- del self.sCtx.localVariables[asVar]
314
- facts = whereMatchedFacts
315
- if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
316
- self.sCtx.modelXbrl.info("sphinx:trace",
317
- _("Hyperspace %(variable)s: %(filter)s filter passes %(factCount)s facts"),
318
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node), filter=aspectStr(aspect), factCount=len(facts))
319
- if self.node.isClosed: # winnow out non-qualified dimension breakdowns
320
- facts = facts - set(fact
321
- for fact in facts
322
- if fact.dimAspects - self.aspectsQualified )
323
- if self.sCtx.formulaOptions.traceVariableFilterWinnowing:
324
- self.sCtx.modelXbrl.info("sphinx:trace",
325
- _("Hyperspace %(variable)s: closed selection filter passes %(factCount)s facts"),
326
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node), factCount=len(facts))
327
- return facts
328
-
329
- def isPeriodEqualTo(fact, periodRestriction):
330
- context = fact.context
331
- if context is not None:
332
- for period in periodRestriction:
333
- if ((context.isInstantPeriod and context.instantDatetime == period) or
334
- (context.isStartEndPeriod and (context.startDatetime, context.endDatetime) == period) or
335
- (context.isForeverPeriod and period == (None, None))):
336
- return True
337
- return False
338
-
339
- def isEntityIdentifierEqualTo(fact, entityIdentifierRestriction):
340
- context = fact.context
341
- if context is not None:
342
- for entityIdentifier in entityIdentifierRestriction:
343
- if context.entityIdentifier == entityIdentifier:
344
- return True
345
- return False
346
-
347
- def typedDimTest(aspect, value, fact):
348
- if fact.context is None:
349
- return False
350
- modelDim = fact.context.dimValue(aspect)
351
- if isinstance(modelDim, ModelDimensionValue):
352
- memElt = modelDim.typedMember
353
- if memElt is None or memElt.get("{http://www.w3.org/2001/XMLSchema-instance}nil") == "true":
354
- return value is NONE or value is DEFAULT
355
- if value is NONDEFAULT:
356
- return True
357
- return memElt.textValue == value
358
- else:
359
- return value is NONE or value is DEFAULT
360
-
361
- class ForBinding:
362
- def __init__(self, hyperspaceBindings, node):
363
- self.hyperspaceBindings = hyperspaceBindings
364
- self.sCtx = hyperspaceBindings.sCtx
365
- self.node = node
366
- self.collection = evaluate(node.collectionExpr, self.sCtx)
367
- self.reset() # will raise StopIteration if no for items
368
-
369
- def close(self):
370
- self.__dict__.clear() # dereference
371
-
372
- @property
373
- def value(self):
374
- if self.yieldedValue is not None:
375
- return self.yieldedValue
376
- return None
377
-
378
- def __repr__(self):
379
- if self.yieldedValue is not None:
380
- return self.yieldedValue.__repr__()
381
- return "none"
382
-
383
- def reset(self):
384
- self.forIter = iter(self.collection)
385
- self.yieldedValue = None
386
- self.next()
387
-
388
-
389
- def next(self): # will raise StopIteration if no (more) facts or fallback
390
- try:
391
- self.yieldedValue = next(self.forIter)
392
- # set next value here as well as in for node, because may be cleared above context of for node
393
- self.sCtx.localVariables[self.node.name] = self.yieldedValue
394
- if self.sCtx.formulaOptions.traceVariableFiltersResult:
395
- self.sCtx.modelXbrl.info("sphinx:trace",
396
- _("For loop %(variable)s: bound value %(result)s"),
397
- sourceFileLine=self.node.sourceFileLine, variable=str(self.node.name), result=str(self.yieldedValue))
398
- except StopIteration:
399
- if self.yieldedValue is not None:
400
- del self.sCtx.localVariables[self.node.name]
401
- self.yieldedValue = None
402
- raise StopIteration
403
-
404
- from .SphinxEvaluator import evaluate, factAspectValue, SphinxException, NONE