arelle-release 2.37.18__py3-none-any.whl → 2.37.20__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.
- arelle/CntlrWinMain.py +4 -1
- arelle/FileSource.py +2 -2
- arelle/ModelInstanceObject.py +1 -1
- arelle/ModelValue.py +1 -0
- arelle/ModelXbrl.py +1 -1
- arelle/PythonUtil.py +132 -24
- arelle/ViewWinTree.py +15 -9
- arelle/_version.py +2 -2
- arelle/formula/XPathContext.py +22 -22
- arelle/formula/XPathParser.py +2 -2
- arelle/plugin/OimTaxonomy/ModelValueMore.py +15 -0
- arelle/plugin/OimTaxonomy/ValidateDTS.py +484 -0
- arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +239 -0
- arelle/plugin/OimTaxonomy/XbrlAbstract.py +16 -0
- arelle/plugin/OimTaxonomy/XbrlConcept.py +68 -0
- arelle/plugin/OimTaxonomy/XbrlConst.py +261 -0
- arelle/plugin/OimTaxonomy/XbrlCube.py +91 -0
- arelle/plugin/OimTaxonomy/XbrlDimension.py +38 -0
- arelle/plugin/OimTaxonomy/XbrlDts.py +152 -0
- arelle/plugin/OimTaxonomy/XbrlEntity.py +16 -0
- arelle/plugin/OimTaxonomy/XbrlGroup.py +22 -0
- arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +22 -0
- arelle/plugin/OimTaxonomy/XbrlLabel.py +31 -0
- arelle/plugin/OimTaxonomy/XbrlNetwork.py +100 -0
- arelle/plugin/OimTaxonomy/XbrlProperty.py +28 -0
- arelle/plugin/OimTaxonomy/XbrlReference.py +33 -0
- arelle/plugin/OimTaxonomy/XbrlReport.py +24 -0
- arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +35 -0
- arelle/plugin/OimTaxonomy/XbrlTaxonomy.py +93 -0
- arelle/plugin/OimTaxonomy/XbrlTaxonomyObject.py +154 -0
- arelle/plugin/OimTaxonomy/XbrlTransform.py +17 -0
- arelle/plugin/OimTaxonomy/XbrlTypes.py +23 -0
- arelle/plugin/OimTaxonomy/XbrlUnit.py +17 -0
- arelle/plugin/OimTaxonomy/__init__.py +1037 -0
- arelle/plugin/OimTaxonomy/resources/iso4217.json +4479 -0
- arelle/plugin/OimTaxonomy/resources/oim-taxonomy-schema.json +935 -0
- arelle/plugin/OimTaxonomy/resources/ref.json +333 -0
- arelle/plugin/OimTaxonomy/resources/transform-types.json +2481 -0
- arelle/plugin/OimTaxonomy/resources/types.json +727 -0
- arelle/plugin/OimTaxonomy/resources/utr.json +3046 -0
- arelle/plugin/OimTaxonomy/resources/xbrlSpec.json +1082 -0
- arelle/plugin/saveOIMTaxonomy.py +311 -0
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +35 -1
- arelle/plugin/validate/NL/__init__.py +7 -0
- arelle/plugin/validate/NL/rules/nl_kvk.py +144 -2
- {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/METADATA +3 -1
- {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/RECORD +59 -24
- tests/integration_tests/validation/README.md +2 -0
- tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py +19 -5
- tests/integration_tests/validation/run_conformance_suites.py +10 -1
- tests/integration_tests/validation/validation_util.py +10 -5
- tests/unit_tests/arelle/test_frozen_dict.py +176 -0
- tests/unit_tests/arelle/test_frozen_ordered_set.py +315 -0
- tests/unit_tests/arelle/test_import.py +1 -0
- tests/unit_tests/arelle/test_ordered_set.py +272 -0
- {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
'''
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
'''
|
|
4
|
+
from typing import Union, get_origin
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from decimal import Decimal
|
|
7
|
+
from typing import GenericAlias
|
|
8
|
+
from arelle import ViewWinTree, XbrlConst
|
|
9
|
+
from arelle.FunctionFn import false
|
|
10
|
+
from arelle.ModelValue import qname
|
|
11
|
+
from arelle.PythonUtil import OrderedSet
|
|
12
|
+
from .XbrlCube import XbrlCube, XbrlPeriodConstraint
|
|
13
|
+
from .XbrlDimension import XbrlDomain
|
|
14
|
+
from .XbrlGroup import XbrlGroup
|
|
15
|
+
from .XbrlNetwork import XbrlNetwork
|
|
16
|
+
from .XbrlTaxonomyObject import EMPTY_DICT, XbrlTaxonomyObject
|
|
17
|
+
from .XbrlConst import qnStdLabel
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def viewXbrlTxmyObj(xbrlDts, objClass, tabWin, header, additionalViews=None):
|
|
21
|
+
xbrlDts.modelManager.showStatus(_("viewing concepts"))
|
|
22
|
+
view = ViewXbrlTxmyObj(xbrlDts, objClass, tabWin, header)
|
|
23
|
+
view.propNameTypes = []
|
|
24
|
+
initialParentObjProp = True
|
|
25
|
+
for propName, propType in getattr(objClass, "__annotations__", {}).items():
|
|
26
|
+
if initialParentObjProp:
|
|
27
|
+
initialParentProp = False
|
|
28
|
+
if isinstance(propType, str):
|
|
29
|
+
continue
|
|
30
|
+
elif get_origin(propType) is Union:
|
|
31
|
+
if any(arg.__name__.startswith("Xbrl") for arg in propType.__args__):
|
|
32
|
+
continue
|
|
33
|
+
elif propType.__name__.startswith("Xbrl"): # skip taxonomy alias type
|
|
34
|
+
continue
|
|
35
|
+
if not isinstance(propType, GenericAlias): # set, dict, etc
|
|
36
|
+
view.propNameTypes.append((propName, propType))
|
|
37
|
+
# add label col if first col is name for Concepts pane
|
|
38
|
+
if view.propNameTypes and view.propNameTypes[0][0] == "name":
|
|
39
|
+
if objClass.__name__ in ("XbrlConcept", "XbrlFact"):
|
|
40
|
+
view.propNameTypes.insert(0, ("label", str))
|
|
41
|
+
else:
|
|
42
|
+
view.propNameTypes[0] = ("name", view.propNameTypes[0][1])
|
|
43
|
+
# check nested object types
|
|
44
|
+
for i in range(len(view.propNameTypes),10):
|
|
45
|
+
view.propNameTypes.append( (f"col{i+1}",str))
|
|
46
|
+
view.colNames = tuple(propName for propName, _propType in view.propNameTypes[1:])
|
|
47
|
+
view.treeView["columns"] = view.colNames
|
|
48
|
+
firstCol = True
|
|
49
|
+
for propName, propType in view.propNameTypes:
|
|
50
|
+
colName = propName
|
|
51
|
+
if firstCol:
|
|
52
|
+
firstCol = False
|
|
53
|
+
colName = "#0"
|
|
54
|
+
w = 360
|
|
55
|
+
elif isinstance(propType, (int,float,Decimal)):
|
|
56
|
+
w = 50
|
|
57
|
+
else:
|
|
58
|
+
w = 120
|
|
59
|
+
view.treeView.column(colName, width=w, anchor="w")
|
|
60
|
+
view.treeView.heading(colName, text=propName)
|
|
61
|
+
view.treeView["displaycolumns"] = view.colNames
|
|
62
|
+
if objClass.__name__ == "XbrlReference":
|
|
63
|
+
view.labelRole = None
|
|
64
|
+
else:
|
|
65
|
+
view.labelrole = qnStdLabel
|
|
66
|
+
view.view()
|
|
67
|
+
view.blockSelectEvent = 1
|
|
68
|
+
view.blockViewModelObject = 0
|
|
69
|
+
view.treeView.bind("<<TreeviewSelect>>", view.treeviewSelect, '+')
|
|
70
|
+
view.treeView.bind("<Enter>", view.treeviewEnter, '+')
|
|
71
|
+
view.treeView.bind("<Leave>", view.treeviewLeave, '+')
|
|
72
|
+
|
|
73
|
+
# languages menu
|
|
74
|
+
menu = view.contextMenu()
|
|
75
|
+
if objClass.__name__ != "XbrlConcept":
|
|
76
|
+
view.menuAddExpandCollapse() # for tree view panes but not for Concept table pane
|
|
77
|
+
view.menuAddClipboard()
|
|
78
|
+
view.menuAddLangs()
|
|
79
|
+
|
|
80
|
+
view.menuAddLabelRoles(usedLabelroles=
|
|
81
|
+
(("1Name",XbrlConst.conceptNameLabelRole),
|
|
82
|
+
("2Standard Label", qnStdLabel)) +
|
|
83
|
+
tuple((f"3{t}", t) for t in sorted(xbrlDts.labelTypes) if t != qnStdLabel))
|
|
84
|
+
view.menuAddNameStyle()
|
|
85
|
+
view.menuAddViews(addClose=False, additionalViews=additionalViews, additionalViewMethod=viewXbrlTxmyObj)
|
|
86
|
+
|
|
87
|
+
class ViewXbrlTxmyObj(ViewWinTree.ViewTree):
|
|
88
|
+
def __init__(self, xbrlDts, objClass, tabWin, header):
|
|
89
|
+
super(ViewXbrlTxmyObj, self).__init__(xbrlDts, tabWin, header, True, None)
|
|
90
|
+
self.xbrlDts = xbrlDts
|
|
91
|
+
self.objClass = objClass
|
|
92
|
+
|
|
93
|
+
def view(self):
|
|
94
|
+
# sort by labels
|
|
95
|
+
self.setColumnsSortable()
|
|
96
|
+
self.tag_has = defaultdict(list)
|
|
97
|
+
lbls = defaultdict(list)
|
|
98
|
+
role = self.labelrole
|
|
99
|
+
lang = self.lang
|
|
100
|
+
self.clearTreeView()
|
|
101
|
+
self.id = 1
|
|
102
|
+
nodeNum = 0
|
|
103
|
+
excludedNamespaces = XbrlConst.ixbrlAll.union(
|
|
104
|
+
(XbrlConst.xbrli, XbrlConst.link, XbrlConst.xlink, XbrlConst.xl,
|
|
105
|
+
XbrlConst.xbrldt,
|
|
106
|
+
XbrlConst.xhtml))
|
|
107
|
+
for obj in self.xbrlDts.filterNamedObjects(self.objClass, role, lang): # this is a yield generator
|
|
108
|
+
propName = self.propNameTypes[0][0]
|
|
109
|
+
node = self.treeView.insert("", "end",
|
|
110
|
+
f"_{self.id}_{obj.dtsObjectIndex}",
|
|
111
|
+
text=str(self.xbrlDts.labelValue(obj.getProperty(propName, self.labelrole), self.labelrole, self.lang)),
|
|
112
|
+
tags=("odd" if nodeNum & 1 else "even",))
|
|
113
|
+
self.tag_has[f"_{obj.dtsObjectIndex}"].append(node)
|
|
114
|
+
self.id += 1
|
|
115
|
+
nodeNum += 1
|
|
116
|
+
for propName, _propType in self.propNameTypes[1:]:
|
|
117
|
+
self.treeView.set(node, propName, str(obj.getProperty(propName)))
|
|
118
|
+
if isinstance(obj, XbrlGroup):
|
|
119
|
+
self.viewGroupContent(node, nodeNum, obj)
|
|
120
|
+
elif isinstance(obj, XbrlCube):
|
|
121
|
+
self.viewDims(node, nodeNum, obj)
|
|
122
|
+
elif isinstance(obj, (XbrlNetwork, XbrlDomain)):
|
|
123
|
+
self.viewRoots(node, nodeNum, obj)
|
|
124
|
+
|
|
125
|
+
def viewProps(self, parentNode, nodeNum, obj):
|
|
126
|
+
propView = obj.propertyView
|
|
127
|
+
node = self.treeView.insert(parentNode, "end",
|
|
128
|
+
f"_{self.id}_{obj.dtsObjectIndex}",
|
|
129
|
+
text=propView[0][1],
|
|
130
|
+
tags=("odd" if nodeNum & 1 else "even",))
|
|
131
|
+
self.tag_has[f"_{obj.dtsObjectIndex}"].append(node)
|
|
132
|
+
nodeNum += 1
|
|
133
|
+
self.id += 1
|
|
134
|
+
for i, propViewEntry in enumerate(propView[1:]):
|
|
135
|
+
if i >= len(self.colNames):
|
|
136
|
+
print(f"i problem {i}")
|
|
137
|
+
if len(propViewEntry) < 2:
|
|
138
|
+
print(f"propViewEntry problem {propViewEntry} class {type(obj).__name__}")
|
|
139
|
+
self.treeView.set(node, self.colNames[i], propViewEntry[1])
|
|
140
|
+
# process nested objects
|
|
141
|
+
for propName, propType in getattr(type(obj), "__annotations__", EMPTY_DICT).items():
|
|
142
|
+
childObj = getattr(obj, propName, None)
|
|
143
|
+
if isinstance(getattr(propType, "__origin__", None), type(Union)): # Optional[ ] type
|
|
144
|
+
if isinstance(propType.__args__[0], XbrlTaxonomyObject): # e.g. dateResolution object
|
|
145
|
+
childObj = getattr(obj, propName, None)
|
|
146
|
+
if childObj is not None:
|
|
147
|
+
self.viewProps(node, nodeNum, childObj)
|
|
148
|
+
elif getattr(propType, "__origin__", None) in (set, OrderedSet) and issubclass(propType.__args__[0], XbrlTaxonomyObject):
|
|
149
|
+
if childObj is not None and len(childObj) > 0 and propName != "relationships":
|
|
150
|
+
for childObjObj in childObj:
|
|
151
|
+
self.viewProps(node, nodeNum, childObjObj)
|
|
152
|
+
return node
|
|
153
|
+
|
|
154
|
+
def viewGroupContent(self, parentNode, nodeNum, obj):
|
|
155
|
+
# related content for the Group object are under tagged content
|
|
156
|
+
for relatedObjQn in self.xbrlDts.groupContents.get(obj.name, ()):
|
|
157
|
+
relatedObj = self.xbrlDts.namedObjects.get(relatedObjQn)
|
|
158
|
+
if relatedObj is not None:
|
|
159
|
+
node = self.viewProps(parentNode, nodeNum, relatedObj)
|
|
160
|
+
nodeNum += 1
|
|
161
|
+
if isinstance(relatedObj, XbrlCube):
|
|
162
|
+
self.viewDims(node, nodeNum, relatedObj)
|
|
163
|
+
elif isinstance(relatedObj, (XbrlNetwork, XbrlDomain)):
|
|
164
|
+
self.viewRoots(node, nodeNum, relatedObj)
|
|
165
|
+
|
|
166
|
+
def viewDims(self, parentNode, nodeNum, obj):
|
|
167
|
+
for cubeDim in obj.cubeDimensions:
|
|
168
|
+
node = self.viewProps(parentNode, nodeNum, cubeDim)
|
|
169
|
+
nodeNum += 1
|
|
170
|
+
domName = getattr(cubeDim, "domainName", None)
|
|
171
|
+
if domName:
|
|
172
|
+
domObj = self.xbrlDts.namedObjects.get(domName)
|
|
173
|
+
if domObj is not None:
|
|
174
|
+
domNode = self.viewProps(node, nodeNum, domObj)
|
|
175
|
+
nodeNum += 1
|
|
176
|
+
self.viewRoots(domNode, nodeNum, domObj)
|
|
177
|
+
|
|
178
|
+
def viewRoots(self, parentNode, nodeNum, obj):
|
|
179
|
+
for qn in obj.relationshipRoots:
|
|
180
|
+
rootObj = self.xbrlDts.namedObjects.get(qn)
|
|
181
|
+
if rootObj is not None:
|
|
182
|
+
node = self.treeView.insert(parentNode, "end",
|
|
183
|
+
f"_{self.id}_{rootObj.dtsObjectIndex}",
|
|
184
|
+
text=str(rootObj.getProperty("label", self.labelrole, self.lang, "")),
|
|
185
|
+
tags=("odd" if nodeNum & 1 else "even",))
|
|
186
|
+
self.id += 1
|
|
187
|
+
nodeNum += 1
|
|
188
|
+
for relObj in obj.relationshipsFrom.get(qn, ()):
|
|
189
|
+
self.viewRelationships(node, nodeNum, obj, relObj, set())
|
|
190
|
+
|
|
191
|
+
def viewRelationships(self, parentNode, nodeNum, obj, relObj, visited):
|
|
192
|
+
target = relObj.target
|
|
193
|
+
qnObj = self.xbrlDts.namedObjects.get(target)
|
|
194
|
+
if qnObj is not None:
|
|
195
|
+
loop = target in visited
|
|
196
|
+
txt = self.xbrlDts.labelValue(relObj.target, self.labelrole, self.lang)
|
|
197
|
+
if loop:
|
|
198
|
+
txt = "(loop) " + txt
|
|
199
|
+
node = self.treeView.insert(parentNode, "end",
|
|
200
|
+
f"_{self.id}_{qnObj.dtsObjectIndex}",
|
|
201
|
+
text=txt,
|
|
202
|
+
tags=("odd" if nodeNum & 1 else "even",))
|
|
203
|
+
self.id += 1
|
|
204
|
+
nodeNum += 1
|
|
205
|
+
if not loop:
|
|
206
|
+
visited.add(target)
|
|
207
|
+
for relTgtObj in obj.relationshipsFrom.get(relObj.target, ()):
|
|
208
|
+
self.viewRelationships(node, nodeNum, obj, relTgtObj, visited)
|
|
209
|
+
visited.remove(target)
|
|
210
|
+
|
|
211
|
+
def treeviewEnter(self, *args):
|
|
212
|
+
self.blockSelectEvent = 0
|
|
213
|
+
|
|
214
|
+
def treeviewLeave(self, *args):
|
|
215
|
+
self.blockSelectEvent = 1
|
|
216
|
+
|
|
217
|
+
def treeviewSelect(self, event):
|
|
218
|
+
if self.blockSelectEvent == 0 and self.blockViewModelObject == 0:
|
|
219
|
+
self.blockViewModelObject += 1
|
|
220
|
+
#self.modelXbrl.viewModelObject(self.nodeToObjectId[self.treeView.selection()[0]])
|
|
221
|
+
selection = self.treeView.selection()
|
|
222
|
+
if selection is not None and len(selection)>0:
|
|
223
|
+
self.xbrlDts.viewTaxonomyObject(selection[0])
|
|
224
|
+
self.blockViewModelObject -= 1
|
|
225
|
+
|
|
226
|
+
def viewModelObject(self, txmyObj):
|
|
227
|
+
if self.blockViewModelObject == 0:
|
|
228
|
+
self.blockViewModelObject += 1
|
|
229
|
+
try:
|
|
230
|
+
items = self.tag_has.get(f"_{txmyObj.dtsObjectIndex}")
|
|
231
|
+
if items:
|
|
232
|
+
for item in items:
|
|
233
|
+
if self.treeView.exists(item):
|
|
234
|
+
self.treeView.see(item)
|
|
235
|
+
self.treeView.selection_set(item)
|
|
236
|
+
break
|
|
237
|
+
except (AttributeError, KeyError, ValueError):
|
|
238
|
+
self.treeView.selection_set(())
|
|
239
|
+
self.blockViewModelObject -= 1
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Set
|
|
6
|
+
|
|
7
|
+
from arelle.ModelValue import QName
|
|
8
|
+
from arelle.PythonUtil import OrderedSet
|
|
9
|
+
from .XbrlProperty import XbrlProperty
|
|
10
|
+
from .XbrlTypes import XbrlTaxonomyType, QNameKeyType
|
|
11
|
+
from .XbrlTaxonomyObject import XbrlReferencableTaxonomyObject
|
|
12
|
+
|
|
13
|
+
class XbrlAbstract(XbrlReferencableTaxonomyObject):
|
|
14
|
+
taxonomy: XbrlTaxonomyType
|
|
15
|
+
name: QNameKeyType # (required) The name is a QName that uniquely identifies the abstract object.
|
|
16
|
+
properties: OrderedSet[XbrlProperty] # (optional) ordered set of property objects used to specify additional properties associated with the concept using the property object. Only immutable properties as defined in the propertyType object can be added to a concept.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Optional, Any
|
|
6
|
+
from typing_extensions import TypeAlias
|
|
7
|
+
from decimal import Decimal
|
|
8
|
+
|
|
9
|
+
from arelle.ModelValue import QName
|
|
10
|
+
from arelle.PythonUtil import OrderedSet
|
|
11
|
+
from arelle.XbrlConst import xsd
|
|
12
|
+
from .XbrlProperty import XbrlProperty
|
|
13
|
+
from .XbrlTypes import XbrlTaxonomyType, QNameKeyType
|
|
14
|
+
from .XbrlTaxonomyObject import XbrlTaxonomyObject, XbrlReferencableTaxonomyObject
|
|
15
|
+
|
|
16
|
+
XbrlUnitTypeType: TypeAlias = "XbrlUnitType"
|
|
17
|
+
|
|
18
|
+
class XbrlConcept(XbrlReferencableTaxonomyObject):
|
|
19
|
+
taxonomy: XbrlTaxonomyType
|
|
20
|
+
name: QNameKeyType # (required) The name is a QName that uniquely identifies the concept object.
|
|
21
|
+
dataType: QName # (required) Indicates the dataType of the concept. These are provided as a QName based on the datatypes specified in the XBRL 2.1 specification and any custom datatype defined in the taxonomy.
|
|
22
|
+
periodType: str # (required) Indicates the period type of the concept. The property values can be either instant or duration. If the concept can be an atemporal value it must be defined as a duration. (i.e. the value does not change with the passage of time)
|
|
23
|
+
enumerationDomain: Optional[QName] # (optional) Used to specify enumerated domain members that are associated with a domain defined in the taxonomy.
|
|
24
|
+
nillable: Optional[bool] # (optional) Used to specify if the concept can have a nill value. The default value is true.
|
|
25
|
+
properties: OrderedSet[XbrlProperty] # (optional) ordered set of property objects used to specify additional properties associated with the concept using the property object. Only immutable properties as defined in the propertyType object can be added to a concept.
|
|
26
|
+
|
|
27
|
+
class XbrlDataType(XbrlReferencableTaxonomyObject):
|
|
28
|
+
taxonomy: XbrlTaxonomyType
|
|
29
|
+
name: QNameKeyType # (required) The name is a QName that uniquely identifies the datatype object.
|
|
30
|
+
baseType: QName # (required) The base type is a QName that uniquely identifies the base datatype the datatype is based on.
|
|
31
|
+
enumeration: OrderedSet[Any] # (optional) Defines an ordered set of enumerated values of the datatype if applicable
|
|
32
|
+
minInclusive: Optional[Decimal] # (optional) Defines a decimal value to indicate a min inclusive cardinal value for a type. Only applies to types based on float, double and decimal.
|
|
33
|
+
maxInclusive: Optional[Decimal] # (optional) Defines a decimal value to indicate a max inclusive cardinal value for a type. Only applies to types based on float, double and decimal.
|
|
34
|
+
minExclusive: Optional[Decimal] # (optional) Defines a decimal value to indicate a min exclusive cardinal value for a type. Only applies to types based on float, double and decimal.
|
|
35
|
+
maxExclusive: Optional[Decimal] # (optional) Defines a decimal value to indicate a max exclusive cardinal value for a type. Only applies to types based on float, double and decimal.
|
|
36
|
+
totalDigits: Optional[int] # (optional) Defines an int value to indicate total digits of a value. Only applies to types based on float, double and decimal.
|
|
37
|
+
fractionDigits: Optional[int] # (optional) Defines an int of digits to the right of the decimal place. Only applies to types based on float, double and decimal.
|
|
38
|
+
length: Optional[int] # (optional) Defines an int value used to define the length of a string value.
|
|
39
|
+
minLength: Optional[int] # (optional) Defines an int used to define minimum length of a string value.
|
|
40
|
+
maxLength: Optional[int] # (optional) Defines an int used to define maximum length of a string value.
|
|
41
|
+
whiteSpace: Optional[str] # (optional) Defines a string one of preserve, replace or collapse.
|
|
42
|
+
patterns: set[str] # (optional) Defines a string as a single regex expressions. At least one of the regex patterns must match. (Uses XML regex)
|
|
43
|
+
unitTypes: OrderedSet[XbrlUnitTypeType] # unitType comprising a dataType expressed as a value of the datatype. For example xbrli:flow has unit datatypes of xbrli:volume and xbrli:time
|
|
44
|
+
|
|
45
|
+
def xsBaseType(self, dts, visitedTypes=None): # find base types thru dataType hierarchy
|
|
46
|
+
if not visitedTypes: visitedTypes = set() # might be a loop
|
|
47
|
+
if self.baseType.namespaceURI == xsd:
|
|
48
|
+
return self.baseType.localName
|
|
49
|
+
elif self not in visitedTypes:
|
|
50
|
+
visitedTypes.add(self)
|
|
51
|
+
baseTypeObj = dts.namedObjects.get(self.baseType)
|
|
52
|
+
if isinstance(baseTypeObj, XbrlDataType):
|
|
53
|
+
return baseTypeObj.xsBaseType(dts, visitedTypes)
|
|
54
|
+
visitedTypes.remove(self)
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
def xsFacets(self):
|
|
58
|
+
facets = {}
|
|
59
|
+
for facet in ("enumeration", "minInclusive", "maxInclusive", "minExclusive", "maxExclusive", "totalDigits", "fractionDigits", "length", "minLength", "maxLength", "whiteSpace", "patterns"):
|
|
60
|
+
value = getattr(self, facet, None)
|
|
61
|
+
if value is not None and not(isinstance(value, (set,list,OrderedSet)) and not value):
|
|
62
|
+
facets[facet] = value
|
|
63
|
+
return facets
|
|
64
|
+
|
|
65
|
+
class XbrlUnitType(XbrlTaxonomyObject):
|
|
66
|
+
dataTypeNumerator: Optional[XbrlDataType] # (optional) Defines the numerator datatype of of the datatype
|
|
67
|
+
dataTypeDenominator: Optional[XbrlDataType] # (optional) Defines the denominator datatype used by a unit used to define a value of the datatype
|
|
68
|
+
dataTypeMutiplier: Optional[XbrlDataType] # (optional) Defines a mutiplier datatype used by a unit used to define a value of the datatype
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
import regex as re
|
|
5
|
+
from arelle.ModelValue import qname
|
|
6
|
+
from arelle.XbrlConst import xsd
|
|
7
|
+
|
|
8
|
+
# MERGE TO arelle.XbrlConst when promoting plugin to infrastructure
|
|
9
|
+
|
|
10
|
+
oimTaxonomyDocTypePattern = re.compile(r"\s*\{.*\"documentType\"\s*:\s*\"https://xbrl.org/[0-9]{4}/taxonomy\"", flags=re.DOTALL)
|
|
11
|
+
oimTaxonomyDocTypes = (
|
|
12
|
+
"https://xbrl.org/2025/taxonomy",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
xbrl = "https://xbrl.org/2025"
|
|
16
|
+
|
|
17
|
+
qnStdLabel = qname(xbrl, "xbrli:label")
|
|
18
|
+
qnXsDate = qname(xsd, "xs:date")
|
|
19
|
+
qnXsDateTime = qname(xsd, "xs:dateTime")
|
|
20
|
+
qnXsDuration = qname(xsd, "xs:duration")
|
|
21
|
+
qnXsQName = qname(xsd, "xs:QName")
|
|
22
|
+
|
|
23
|
+
qnXbrlLabelObj = qname(xbrl, "xbrl:labelObject")
|
|
24
|
+
|
|
25
|
+
objectsWithProperties = {
|
|
26
|
+
qname(xbrl, "xbrl:taxonomyObject"),
|
|
27
|
+
qname(xbrl, "xbrl:conceptObject"),
|
|
28
|
+
qname(xbrl, "xbrl:abstractObject"),
|
|
29
|
+
qname(xbrl, "xbrl:cubeObject"),
|
|
30
|
+
qname(xbrl, "xbrl:dimensionObject"),
|
|
31
|
+
qname(xbrl, "xbrl:domainObject"),
|
|
32
|
+
qname(xbrl, "xbrl:entityObject"),
|
|
33
|
+
qname(xbrl, "xbrl:groupObject"),
|
|
34
|
+
qname(xbrl, "xbrl:networkObject"),
|
|
35
|
+
qnXbrlLabelObj,
|
|
36
|
+
qname(xbrl, "xbrl:memberObject"),
|
|
37
|
+
qname(xbrl, "xbrl:referenceObject"),
|
|
38
|
+
qname(xbrl, "xbrl:relationshipObject"),
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
xbrlTaxonomyObjects = {
|
|
42
|
+
"documentInfo": {
|
|
43
|
+
"documentType": oimTaxonomyDocTypes[0],
|
|
44
|
+
"namespaces": {
|
|
45
|
+
"xbrl": xbrl,
|
|
46
|
+
"xbrli": "https://xbrl.org/2025/instance",
|
|
47
|
+
"xs": xsd
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"taxonomy": {
|
|
51
|
+
"name": "xbrl:BuiltInCoreObjectsTaxonomy",
|
|
52
|
+
"frameworkName": "types",
|
|
53
|
+
"version": "2025",
|
|
54
|
+
"resolved": False,
|
|
55
|
+
"dataTypes": [
|
|
56
|
+
{
|
|
57
|
+
"name": "xs:string",
|
|
58
|
+
"baseType": "xs:string"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "xs:boolean",
|
|
62
|
+
"baseType": "xs:boolean"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "xs:decimal",
|
|
66
|
+
"baseType": "xs:decimal"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "xs:float",
|
|
70
|
+
"baseType": "xs:float"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "xs:double",
|
|
74
|
+
"baseType": "xs:double"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "xs:duration",
|
|
78
|
+
"baseType": "xs:duration"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "xs:dateTime",
|
|
82
|
+
"baseType": "xs:dateTime"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "xs:time",
|
|
86
|
+
"baseType": "xs:time"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "xs:date",
|
|
90
|
+
"baseType": "xs:date"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "xs:gYearMonth",
|
|
94
|
+
"baseType": "xs:gYearMonth"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "xs:gYear",
|
|
98
|
+
"baseType": "xs:gYear"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "xs:gMonthDay",
|
|
102
|
+
"baseType": "xs:gMonthDay"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "xs:gDay",
|
|
106
|
+
"baseType": "xs:gDay"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "xs:gMonth",
|
|
110
|
+
"baseType": "xs:gMonth"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "xs:hexBinary",
|
|
114
|
+
"baseType": "xs:hexBinary"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "xs:base64Binary",
|
|
118
|
+
"baseType": "xs:base64Binary"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "xs:anyURI",
|
|
122
|
+
"baseType": "xs:anyURI"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "xs:QName",
|
|
126
|
+
"baseType": "xs:QName"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"name": "xs:NOTATION",
|
|
130
|
+
"baseType": "xs:NOTATION"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "xs:normalizedString",
|
|
134
|
+
"baseType": "xs:string"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "xs:token",
|
|
138
|
+
"baseType": "xs:normalizedString"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"name": "xs:language",
|
|
142
|
+
"baseType": "xs:token"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "xs:NMTOKEN",
|
|
146
|
+
"baseType": "xs:token"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "xs:NMTOKENS",
|
|
150
|
+
"baseType": "xs:NMTOKEN"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "xs:Name",
|
|
154
|
+
"baseType": "xs:token"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "xs:NCName",
|
|
158
|
+
"baseType": "xs:Name"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"name": "xs:ID",
|
|
162
|
+
"baseType": "xs:NCName"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"name": "xs:IDREF",
|
|
166
|
+
"baseType": "xs:NCName"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"name": "xs:IDREFS",
|
|
170
|
+
"baseType": "xs:IDREF"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "xs:ENTITY",
|
|
174
|
+
"baseType": "xs:IDREF"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"name": "xs:ENTITIES",
|
|
178
|
+
"baseType": "xs:ENTITY"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "xs:integer",
|
|
182
|
+
"baseType": "xs:decimal"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"name": "xs:nonPositiveInteger",
|
|
186
|
+
"baseType": "xs:integer",
|
|
187
|
+
"maxInclusive": 0
|
|
188
|
+
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"name": "xs:negativeInteger",
|
|
192
|
+
"baseType": "xs:nonPositiveInteger",
|
|
193
|
+
"maxInclusive": -1
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "xs:long",
|
|
197
|
+
"baseType": "xs:integer"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "xs:int",
|
|
201
|
+
"baseType": "xs:long",
|
|
202
|
+
"maxInclusive": 2147483647,
|
|
203
|
+
"minInclusive": -2147483648
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"name": "xs:short",
|
|
207
|
+
"baseType": "xs:int",
|
|
208
|
+
"maxInclusive": 32767,
|
|
209
|
+
"minInclusive": -32768
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "xs:byte",
|
|
213
|
+
"baseType": "xs:short",
|
|
214
|
+
"maxInclusive": 127,
|
|
215
|
+
"minInclusive": -128
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"name": "xs:nonNegativeInteger",
|
|
219
|
+
"baseType": "xs:integer",
|
|
220
|
+
"minInclusive": 0
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"name": "xs:unsignedLong",
|
|
224
|
+
"baseType": "xs:nonNegativeInteger",
|
|
225
|
+
"maxInclusive": 18446744073709551615
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"name": "xs:unsignedInt",
|
|
229
|
+
"baseType": "xs:unsignedInt",
|
|
230
|
+
"maxInclusive": 4294967295
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"name": "xs:unsignedShort",
|
|
234
|
+
"baseType": "xs:unsignedInt",
|
|
235
|
+
"maxInclusive": 65535
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"name": "xs:unsignedByte",
|
|
239
|
+
"baseType": "xs:unsignedShort",
|
|
240
|
+
"maxInclusive": 255
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"name": "xs:positiveInteger",
|
|
244
|
+
"baseType": "xs:nonNegativeInteger",
|
|
245
|
+
"minInclusive": 1
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"name": "xs:yearMonthDuration",
|
|
249
|
+
"baseType": "xs:duration"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"name": "xs:dayTimeDuration",
|
|
253
|
+
"baseType": "xs:duration"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "xs:dateTimeStamp",
|
|
257
|
+
"baseType": "xs:dateTime"
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
}
|