arelle-release 2.37.19__py3-none-any.whl → 2.37.21__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 (36) hide show
  1. arelle/CntlrCmdLine.py +8 -0
  2. arelle/FileSource.py +2 -2
  3. arelle/ModelInstanceObject.py +1 -1
  4. arelle/ModelXbrl.py +1 -1
  5. arelle/RuntimeOptions.py +0 -6
  6. arelle/XbrlConst.py +2 -0
  7. arelle/_version.py +2 -2
  8. arelle/api/Session.py +7 -5
  9. arelle/formula/XPathContext.py +22 -22
  10. arelle/formula/XPathParser.py +2 -2
  11. arelle/plugin/OimTaxonomy/ModelValueMore.py +2 -2
  12. arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +2 -3
  13. arelle/plugin/OimTaxonomy/XbrlConcept.py +2 -1
  14. arelle/plugin/OimTaxonomy/XbrlCube.py +8 -8
  15. arelle/plugin/OimTaxonomy/XbrlDts.py +5 -5
  16. arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +3 -3
  17. arelle/plugin/OimTaxonomy/XbrlNetwork.py +3 -3
  18. arelle/plugin/OimTaxonomy/XbrlProperty.py +3 -3
  19. arelle/plugin/OimTaxonomy/XbrlReport.py +3 -3
  20. arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +3 -3
  21. arelle/plugin/OimTaxonomy/XbrlTypes.py +1 -1
  22. arelle/plugin/OimTaxonomy/__init__.py +4 -5
  23. arelle/plugin/validate/NL/LinkbaseType.py +77 -0
  24. arelle/plugin/validate/NL/PluginValidationDataExtension.py +195 -26
  25. arelle/plugin/validate/NL/ValidationPluginExtension.py +1 -0
  26. arelle/plugin/validate/NL/__init__.py +3 -3
  27. arelle/plugin/validate/NL/rules/nl_kvk.py +465 -17
  28. {arelle_release-2.37.19.dist-info → arelle_release-2.37.21.dist-info}/METADATA +2 -1
  29. {arelle_release-2.37.19.dist-info → arelle_release-2.37.21.dist-info}/RECORD +36 -35
  30. tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py +23 -17
  31. tests/unit_tests/arelle/test_import.py +0 -30
  32. tests/unit_tests/arelle/test_runtimeoptions.py +0 -13
  33. {arelle_release-2.37.19.dist-info → arelle_release-2.37.21.dist-info}/WHEEL +0 -0
  34. {arelle_release-2.37.19.dist-info → arelle_release-2.37.21.dist-info}/entry_points.txt +0 -0
  35. {arelle_release-2.37.19.dist-info → arelle_release-2.37.21.dist-info}/licenses/LICENSE.md +0 -0
  36. {arelle_release-2.37.19.dist-info → arelle_release-2.37.21.dist-info}/top_level.txt +0 -0
arelle/CntlrCmdLine.py CHANGED
@@ -537,6 +537,14 @@ def parseArgs(args):
537
537
  runtimeOptions = RuntimeOptions(pluginOptions=pluginOptions, **baseOptions)
538
538
  except RuntimeOptionsException as e:
539
539
  parser.error(f"{e}, please try\n python CntlrCmdLine.py --help")
540
+ if (
541
+ runtimeOptions.entrypointFile is None and
542
+ not runtimeOptions.proxy and
543
+ not runtimeOptions.plugins and
544
+ not pluginOptions and
545
+ not runtimeOptions.webserver
546
+ ):
547
+ parser.error("No entrypoint specified, please try\n python CntlrCmdLine.py --help")
540
548
  return runtimeOptions, arellePluginModules
541
549
 
542
550
 
arelle/FileSource.py CHANGED
@@ -13,7 +13,7 @@ import struct
13
13
  import tarfile
14
14
  import zipfile
15
15
  import zlib
16
- from typing import IO, TYPE_CHECKING, Any, TextIO, cast
16
+ from typing import IO, TYPE_CHECKING, Any, Optional, TextIO, cast
17
17
 
18
18
  import regex as re
19
19
  from lxml import etree
@@ -452,7 +452,7 @@ class FileSource:
452
452
  def reportPackage(self) -> ReportPackage | None:
453
453
  try:
454
454
  self._reportPackage: ReportPackage | None
455
- return self._reportPackage
455
+ return cast(Optional[ReportPackage], self._reportPackage)
456
456
  except AttributeError:
457
457
  self._reportPackage = ReportPackage.fromFileSource(self)
458
458
  return self._reportPackage
@@ -1133,7 +1133,7 @@ class ModelContext(ModelObject):
1133
1133
  dimValue = self.modelXbrl.qnameDimensionDefaults.get(dimQname)
1134
1134
  return dimValue
1135
1135
 
1136
- def dimMemberQname(self, dimQname, includeDefaults=False):
1136
+ def dimMemberQname(self, dimQname: ModelValue.QName, includeDefaults: bool = False) -> ModelValue.QName | None:
1137
1137
  """(QName) -- QName of explicit dimension if reported (or defaulted if includeDefaults is True), else None"""
1138
1138
  dimValue = self.dimValue(dimQname)
1139
1139
  if isinstance(dimValue, (ModelDimensionValue,DimValuePrototype)) and dimValue.isExplicit:
arelle/ModelXbrl.py CHANGED
@@ -878,7 +878,7 @@ class ModelXbrl:
878
878
  def dimensionsInUse(self) -> set[Any]:
879
879
  self._dimensionsInUse: set[Any]
880
880
  try:
881
- return self._dimensionsInUse
881
+ return cast(set[Any], self._dimensionsInUse)
882
882
  except AttributeError:
883
883
  self._dimensionsInUse = set(dim.dimension
884
884
  for cntx in self.contexts.values() # use contextsInUse? slower?
arelle/RuntimeOptions.py CHANGED
@@ -183,12 +183,6 @@ class RuntimeOptions:
183
183
  raise RuntimeOptionsException('Provided plugin options already exist as base options {}'.format(existingBaseOptions))
184
184
  for optionName, optionValue in pluginOptions.items():
185
185
  setattr(self, optionName, optionValue)
186
- if (self.entrypointFile is None and
187
- not self.proxy and
188
- not self.plugins and
189
- not pluginOptions and
190
- not self.webserver):
191
- raise RuntimeOptionsException('Incorrect arguments')
192
186
  if self.webserver and not hasWebServer():
193
187
  raise RuntimeOptionsException("Webserver option requires webserver module")
194
188
  if self.webserver and any((
arelle/XbrlConst.py CHANGED
@@ -101,6 +101,7 @@ elementLabel = "http://xbrl.org/arcrole/2008/element-label"
101
101
  genLabel = "http://xbrl.org/2008/label"
102
102
  qnGenLabel = qname("{http://xbrl.org/2008/label}label")
103
103
  xbrldt = "http://xbrl.org/2005/xbrldt"
104
+ qnXbrldtClosed = qname("{http://xbrl.org/2005/xbrldt}xbrldt:closed")
104
105
  qnXbrldtHypercubeItem = qname("{http://xbrl.org/2005/xbrldt}xbrldt:hypercubeItem")
105
106
  qnXbrldtDimensionItem = qname("{http://xbrl.org/2005/xbrldt}xbrldt:dimensionItem")
106
107
  qnXbrldtContextElement = qname("{http://xbrl.org/2005/xbrldt}xbrldt:contextElement")
@@ -108,6 +109,7 @@ xbrldi = "http://xbrl.org/2006/xbrldi"
108
109
  qnXbrldiExplicitMember = qname("{http://xbrl.org/2006/xbrldi}xbrldi:explicitMember")
109
110
  qnXbrldiTypedMember = qname("{http://xbrl.org/2006/xbrldi}xbrldi:typedMember")
110
111
  xlink = "http://www.w3.org/1999/xlink"
112
+ qnXlinkArcRole = qname("{http://www.w3.org/1999/xlink}xlink:arcrole")
111
113
  xl = "http://www.xbrl.org/2003/XLink"
112
114
  qnXlExtended = qname("{http://www.xbrl.org/2003/XLink}xl:extended")
113
115
  qnXlLocator = qname("{http://www.xbrl.org/2003/XLink}xl:locator")
arelle/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.37.19'
21
- __version_tuple__ = version_tuple = (2, 37, 19)
20
+ __version__ = version = '2.37.21'
21
+ __version_tuple__ = version_tuple = (2, 37, 21)
arelle/api/Session.py CHANGED
@@ -1,10 +1,7 @@
1
1
  """
2
2
  See COPYRIGHT.md for copyright information.
3
3
 
4
- The Arelle Python Beta API (located in `arelle.api` module) is an in-progress API module.
5
- A roadmap for this API is in development.
6
-
7
- Users of this API should expect changes in future releases.
4
+ The `arelle.api` module is the supported method for integrating Arelle into other Python applications.
8
5
  """
9
6
  from __future__ import annotations
10
7
 
@@ -12,7 +9,7 @@ import logging
12
9
  from types import TracebackType
13
10
  from typing import Any, BinaryIO
14
11
 
15
- from arelle import PluginManager, PackageManager
12
+ from arelle import PackageManager, PluginManager
16
13
  from arelle.CntlrCmdLine import CntlrCmdLine, createCntlrAndPreloadPlugins
17
14
  from arelle.ModelXbrl import ModelXbrl
18
15
  from arelle.RuntimeOptions import RuntimeOptions
@@ -81,6 +78,7 @@ class Session:
81
78
  responseZipStream: BinaryIO | None = None,
82
79
  logHandler: logging.Handler | None = None,
83
80
  logFilters: list[logging.Filter] | None = None,
81
+ sourceZipStreamFileName: str | None = None,
84
82
  ) -> bool:
85
83
  """
86
84
  Perform a run using the given options.
@@ -88,8 +86,11 @@ class Session:
88
86
  :param sourceZipStream: Optional stream to read source data from.
89
87
  :param responseZipStream: Options stream to write response data to.
90
88
  :param logHandler: Optional log handler to use for logging.
89
+ :param sourceZipStreamFileName: Optional file name to use for the passed zip stream.
91
90
  :return: True if the run was successful, False otherwise.
92
91
  """
92
+ if sourceZipStreamFileName is not None and sourceZipStream is None:
93
+ raise ValueError("sourceZipStreamFileName may only be provided if sourceZipStream is not None.")
93
94
  PackageManager.reset()
94
95
  PluginManager.reset()
95
96
  if self._cntlr is None:
@@ -143,4 +144,5 @@ class Session:
143
144
  options,
144
145
  sourceZipStream=sourceZipStream,
145
146
  responseZipStream=responseZipStream,
147
+ sourceZipStreamFileName=sourceZipStreamFileName,
146
148
  )
@@ -351,8 +351,8 @@ class XPathContext:
351
351
  raise XPathException(p, 'err:XPST0017', _('Function named {0} does not have a custom or built-in implementation.').format(op))
352
352
  elif op in VALUE_OPS:
353
353
  # binary arithmetic operations and value comparisons
354
- s1 = self.atomize(p, resultStack.pop()) if len(resultStack) > 0 else []
355
- s2 = self.atomize(p, self.evaluate(p.args, contextItem=contextItem))
354
+ s1: Sequence[ContextItem] = self.atomize(p, resultStack.pop()) if len(resultStack) > 0 else []
355
+ s2: Sequence[ContextItem] = self.atomize(p, self.evaluate(p.args, contextItem=contextItem))
356
356
  # value comparisons
357
357
  if len(s1) > 1 or len(s2) > 1:
358
358
  raise XPathException(p, 'err:XPTY0004', _("Value operation '{0}' sequence length error").format(op))
@@ -383,35 +383,35 @@ class XPathContext:
383
383
  elif isinstance(op2, Decimal) and isinstance(op1, float):
384
384
  op2 = float(op2)
385
385
  if op == '+':
386
- result = op1 + op2
386
+ result = op1 + op2 # type: ignore[assignment,operator]
387
387
  elif op == '-':
388
- result = op1 - op2
388
+ result = op1 - op2 # type: ignore[assignment,operator]
389
389
  elif op == '*':
390
- result = op1 * op2
390
+ result = op1 * op2 # type: ignore[assignment,operator]
391
391
  elif op in ('div', 'idiv', "mod"):
392
392
  try:
393
393
  if op == 'div':
394
- result = op1 / op2
394
+ result = op1 / op2 # type: ignore[assignment,operator]
395
395
  elif op == 'idiv':
396
- result = op1 // op2
396
+ result = op1 // op2 # type: ignore[assignment,operator]
397
397
  elif op == 'mod':
398
- result = op1 % op2
398
+ result = op1 % op2 # type: ignore[assignment,operator]
399
399
  except ZeroDivisionError:
400
400
  raise XPathException(p, 'err:FOAR0001', _('Attempt to divide by zero: {0} {1} {2}.').format(op1, op, op2))
401
401
  elif op == 'ge':
402
- result = op1 >= op2
402
+ result = op1 >= op2 # type: ignore[operator]
403
403
  elif op == 'gt':
404
- result = op1 > op2
404
+ result = op1 > op2 # type: ignore[operator]
405
405
  elif op == 'le':
406
- result = op1 <= op2
406
+ result = op1 <= op2 # type: ignore[operator]
407
407
  elif op == 'lt':
408
- result = op1 < op2
408
+ result = op1 < op2 # type: ignore[operator]
409
409
  elif op == 'eq':
410
410
  result = op1 == op2
411
411
  elif op == 'ne':
412
412
  result = op1 != op2
413
413
  elif op == 'to':
414
- result = range(int(op1), int(op2) + 1)
414
+ result = range(int(op1), int(op2) + 1) # type: ignore[arg-type]
415
415
  elif op in GENERALCOMPARISON_OPS:
416
416
  # general comparisons
417
417
  s1 = self.atomize(p, resultStack.pop()) if len(resultStack) > 0 else []
@@ -440,23 +440,23 @@ class XPathContext:
440
440
  elif op in NODECOMPARISON_OPS:
441
441
  # node comparisons
442
442
  s1 = resultStack.pop() if len(resultStack) > 0 else []
443
- s2 = self.evaluate(p.args, contextItem=contextItem)
444
- if len(s1) > 1 or len(s2) > 1 or not self.isNodeSequence(s1) or not self.isNodeSequence(s2[0]):
443
+ _s2 = self.evaluate(p.args, contextItem=contextItem)
444
+ if len(s1) > 1 or len(_s2) > 1 or not self.isNodeSequence(s1) or not self.isNodeSequence(_s2[0]):
445
445
  raise XPathException(p, 'err:XPTY0004', _('Node comparison sequence error'))
446
- if len(s1) == 0 or len(s2[0]) == 0:
446
+ if len(s1) == 0 or len(_s2[0]) == 0:
447
447
  result = []
448
448
  else:
449
449
  n1 = s1[0]
450
- n2 = s2[0][0]
450
+ n2 = _s2[0][0]
451
451
  result = False
452
452
  for op1 in s1:
453
- for op2 in s2:
453
+ for _op2 in _s2:
454
454
  if op == 'is':
455
455
  result = n1 == n2
456
456
  elif op == '>>':
457
- result = op1 > op2
457
+ result = op1 > _op2 # type: ignore[operator]
458
458
  elif op == '<<':
459
- result = op1 <= op2
459
+ result = op1 <= _op2 # type: ignore[operator]
460
460
  if result:
461
461
  break
462
462
  elif op in COMBINING_OPS:
@@ -503,7 +503,7 @@ class XPathContext:
503
503
  if op == 'u+':
504
504
  result = op1
505
505
  elif op == 'u-':
506
- result = -op1
506
+ result = -op1 # type: ignore[assignment,operator]
507
507
  elif op == 'instance':
508
508
  result = False
509
509
  s1 = self.flattenSequence(resultStack.pop()) if len(resultStack) > 0 else []
@@ -671,7 +671,7 @@ class XPathContext:
671
671
  if hasPrevValue:
672
672
  prevValue = self.inScopeVars[rvQname]
673
673
  for rv in r:
674
- self.inScopeVars[rvQname] = rv # type: ignore[assignment]
674
+ self.inScopeVars[rvQname] = rv
675
675
  self.evaluateRangeVars(op, args[0], args[1:], contextItem, result)
676
676
  if op != 'for' and len(result) > 0:
677
677
  break # short circuit evaluation
@@ -9,7 +9,7 @@ import time
9
9
  import traceback
10
10
  from collections.abc import Iterable, Sequence
11
11
  from decimal import Decimal
12
- from typing import Any, TYPE_CHECKING, Union
12
+ from typing import Any, TYPE_CHECKING, Union, cast
13
13
  from xml.dom import minidom
14
14
 
15
15
  from pyparsing import (
@@ -954,7 +954,7 @@ def staticExpressionFunctionContext() -> minidom.Element:
954
954
  ' xmlns:fn="http://www.w3.org/2005/xpath-functions"'
955
955
  '/>'
956
956
  ).documentElement
957
- return _staticExpressionFunctionContext
957
+ return cast(minidom.Element, _staticExpressionFunctionContext)
958
958
 
959
959
 
960
960
  def parse(
@@ -2,12 +2,12 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, Set, Any
5
+ from typing import TYPE_CHECKING, Optional, Set, Any
6
6
 
7
7
  from arelle.ModelValue import QName
8
8
 
9
9
  class QNameAt(QName):
10
- def __init__(self, prefix: str | None, namespaceURI: str | None, localName: str, atSuffix:str = "end") -> None:
10
+ def __init__(self, prefix: Optional[str], namespaceURI: Optional[str], localName: str, atSuffix:str = "end") -> None:
11
11
  super(QNameAt, self).__init__(prefix, namespaceURI, localName)
12
12
  self.atSuffix: str = atSuffix # The context suffix must be either @end or @start. If an @ value is not provided then the suffix defaults to @end.
13
13
 
@@ -1,8 +1,7 @@
1
1
  '''
2
2
  See COPYRIGHT.md for copyright information.
3
3
  '''
4
- from typing import Union
5
- from types import UnionType
4
+ from typing import Union, get_origin
6
5
  from collections import defaultdict
7
6
  from decimal import Decimal
8
7
  from typing import GenericAlias
@@ -28,7 +27,7 @@ def viewXbrlTxmyObj(xbrlDts, objClass, tabWin, header, additionalViews=None):
28
27
  initialParentProp = False
29
28
  if isinstance(propType, str):
30
29
  continue
31
- elif isinstance(propType, UnionType):
30
+ elif get_origin(propType) is Union:
32
31
  if any(arg.__name__.startswith("Xbrl") for arg in propType.__args__):
33
32
  continue
34
33
  elif propType.__name__.startswith("Xbrl"): # skip taxonomy alias type
@@ -2,7 +2,8 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, TypeAlias, Optional, Any
5
+ from typing import TYPE_CHECKING, Optional, Any
6
+ from typing_extensions import TypeAlias
6
7
  from decimal import Decimal
7
8
 
8
9
  from arelle.ModelValue import QName
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, Optional
5
+ from typing import TYPE_CHECKING, Optional, Union
6
6
 
7
7
  from arelle.ModelValue import qname, QName, DateTime, YearMonthDayTimeDuration
8
8
  from arelle.PythonUtil import OrderedSet
@@ -32,7 +32,7 @@ class XbrlCubeDimension(XbrlTaxonomyObject):
32
32
  dimensionName: QName # (required) The QName of the dimension object that is used to identify the dimension. For the core dimensions of concept, period, entity and unit, the core dimension QNames of xbrl:concept, xbrl:period, xbrl:entity, xbrl:unit and xbrl:language are used. The dimension object indicates if the dimension is typed or explicit.
33
33
  domainName: Optional[QName] # (required if explicit dimension) The QName of the domain object that is used to identify the domain associated with the dimension. Only one domain can be associated with a dimension. The domain name cannot be provided for a typed dimension or the period core dimension.
34
34
  domainSort: Optional[str] # (optional if typed dimension) A string value that indicates the sort order of the typed dimension. The values can be either asc or desc. The values are case insensitive. This indicates if the cube is viewed the order of the values shown on the typed dimension. This cannot be used on an explicit dimension.
35
- allowDomainFacts: bool | DefaultFalse # (optional ) A boolean value that indicates if facts not identified with the dimension are included in the cube. For typed and explicit dimensions the value defaults to false. A value of true for a typed or explicit dimension will include facts that don't use the dimension in the cube. For the period core dimension, forever facts or facts with no period dimension are included when this value is set to true. For units, this is a unit with no units such as a string or date. For the entity core dimension, it is fact values with no entity. This property cannot be used on the concept core dimension.
35
+ allowDomainFacts: Union[bool, DefaultFalse] # (optional ) A boolean value that indicates if facts not identified with the dimension are included in the cube. For typed and explicit dimensions the value defaults to false. A value of true for a typed or explicit dimension will include facts that don't use the dimension in the cube. For the period core dimension, forever facts or facts with no period dimension are included when this value is set to true. For units, this is a unit with no units such as a string or date. For the entity core dimension, it is fact values with no entity. This property cannot be used on the concept core dimension.
36
36
  periodConstraints: set[XbrlPeriodConstraint] # (optional only for period core dimension) Defines an ordered set of periodConstraint objects to restrict fact values in a cube to fact values with a specified period.
37
37
 
38
38
  class XbrlCube(XbrlReferencableTaxonomyObject):
@@ -49,7 +49,7 @@ class XbrlAllowedCubeDimension(XbrlTaxonomyObject):
49
49
  dimensionName: Optional[QName] # (optional) The dimension QName that identifies the taxonomy defined dimension.
50
50
  dimensionType: Optional[str] # (optional) The dimension QName that identifies the taxonomy defined dimension.
51
51
  dimensionDataType: Optional[QName] # (optional) The dimension QName that identifies the taxonomy defined dimension.
52
- required: bool | DefaultFalse # (optional) The dimension QName that identifies the taxonomy defined dimension.
52
+ required: Union[bool, DefaultFalse] # (optional) The dimension QName that identifies the taxonomy defined dimension.
53
53
 
54
54
  class XbrlRequiredCubeRelationship(XbrlTaxonomyObject):
55
55
  relationshipTypeName: QName # (required) The relationship type QName of a relationship. This requires that at lease one of these relationship types exist on the cube.
@@ -59,11 +59,11 @@ class XbrlRequiredCubeRelationship(XbrlTaxonomyObject):
59
59
  class XbrlCubeType(XbrlReferencableTaxonomyObject):
60
60
  taxonomy: XbrlTaxonomyType
61
61
  name: QNameKeyType # (required) The name is a QName that uniquely identifies the cube type object.
62
- baseCubeType: bool | DefaultTrue # (optional) Base cube type that the cube object is based on. Uses the QName of a cubeType object. The property only allows restriction rather than expansion of the baseCubeTape.
63
- periodDimension: bool | DefaultTrue # (optional) boolean to indicate if the period core dimension is included in the cube. Defaults to true.
64
- entityDimension: bool | DefaultTrue # (optional) boolean to indicate if the entity core dimension is included in the cube. Defaults to true.
65
- unitDimension: bool | DefaultTrue # (optional) boolean to indicate if the unit core dimension is included in the cube. Defaults to true.
66
- taxonomyDefinedDimension: bool | DefaultTrue # (optional) boolean to indicate if taxonomy defined dimensions are included in the cube. Defaults to true.
62
+ baseCubeType: Union[bool, DefaultTrue] # (optional) Base cube type that the cube object is based on. Uses the QName of a cubeType object. The property only allows restriction rather than expansion of the baseCubeTape.
63
+ periodDimension: Union[bool, DefaultTrue] # (optional) boolean to indicate if the period core dimension is included in the cube. Defaults to true.
64
+ entityDimension: Union[bool, DefaultTrue] # (optional) boolean to indicate if the entity core dimension is included in the cube. Defaults to true.
65
+ unitDimension: Union[bool, DefaultTrue] # (optional) boolean to indicate if the unit core dimension is included in the cube. Defaults to true.
66
+ taxonomyDefinedDimension: Union[bool, DefaultTrue] # (optional) boolean to indicate if taxonomy defined dimensions are included in the cube. Defaults to true.
67
67
  allowedCubeDimensions: OrderedSet[XbrlAllowedCubeDimension] # (optional) An ordered set of allowedCubeDimension objects that are permitted to be used on the cube. If the property is not defined then any dimensions can be associated with the cube.
68
68
  requiredCubeRelationships: OrderedSet[XbrlRequiredCubeRelationship] # (optional) An ordered set of requiredCubeRelationship objects that at a minimum must be associated with the cube.
69
69
 
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, cast, Any, ClassVar
5
+ from typing import TYPE_CHECKING, Optional, Union, cast, Any, ClassVar
6
6
  from collections import OrderedDict, defaultdict # OrderedDict is not same as dict, has additional key order features
7
7
  import sys, traceback
8
8
  from arelle.ModelValue import QName, AnyURI
@@ -58,7 +58,7 @@ class XbrlDts(ModelXbrl): # complete wrapper for ModelXbrl
58
58
  def referenceTypes(self):
59
59
  return set(obj.referenceType for l in self.tagObjects.values() for obj in l if hasattr(obj, "referenceType"))
60
60
 
61
- def labelValue(self, name: QName, labelType: QName, lang: str | None = None, fallbackToName: bool = True) -> str | None:
61
+ def labelValue(self, name: QName, labelType: QName, lang: Optional[str] = None, fallbackToName: bool = True) -> Optional[str]:
62
62
  if labelType == XbrlConst.conceptNameLabelRole:
63
63
  return str(name)
64
64
  if lang is None:
@@ -76,7 +76,7 @@ class XbrlDts(ModelXbrl): # complete wrapper for ModelXbrl
76
76
  return str(name)
77
77
  return None
78
78
 
79
- def referenceProperties(self, name: QName, referenceType: QName | None, lang: str | None = None) -> list[XbrlPropertyType]:
79
+ def referenceProperties(self, name: QName, referenceType: Optional[QName], lang: Optional[str] = None) -> list[XbrlPropertyType]:
80
80
  refProperties = defaultdict(list)
81
81
  if lang is None:
82
82
  lang = self.modelXbrl.modelManager.defaultLang
@@ -90,11 +90,11 @@ class XbrlDts(ModelXbrl): # complete wrapper for ModelXbrl
90
90
 
91
91
 
92
92
  # UI thread viewTaxonomyObject
93
- def viewTaxonomyObject(self, objectId: str | int) -> None:
93
+ def viewTaxonomyObject(self, objectId: Union[str, int]) -> None:
94
94
  """Finds taxonomy object, if any, and synchronizes any views displaying it to bring the model object into scrollable view region and highlight it
95
95
  :param objectId: string which includes _ordinalNumber, produced by ModelObject.objectId(), or integer object index
96
96
  """
97
- xbrlObj: XbrlObject | str | int = ""
97
+ xbrlObj: Union[XbrlObject, str, int] = ""
98
98
  try:
99
99
  if isinstance(objectId, XbrlObject):
100
100
  xbrlObj = objectId
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, Union
6
6
 
7
7
  from arelle.ModelValue import QName, AnyURI
8
8
  from arelle.PythonUtil import OrderedSet
@@ -18,5 +18,5 @@ class XbrlImportedTaxonomy(XbrlTaxonomyObject):
18
18
  taxonomyName: QNameKeyType # (required) The QName of the taxonomy to import. The location of the taxonomy QName is resolved by referencing the namespace map which includes the url of the namespace. When importing XBRL 2.1 taxonomies a QName comprising the namespace of the taxonomy to import and a local name of taxonomy is defined. i.e. ifrs:Taxonomy.
19
19
  includeObjects: set[QName] # (optional) A set of object QNames that should be imported from the taxonomyName location property. Only the objects defined in the include and any dependent objects are added to the dts. This property can only be used for taxonomy files using the OIM specification. The dependents of each object are defined in this specification.
20
20
  includeObjectTypes: set[QName] # (optional) A set of object type QNames that should be imported from the taxonomyName location property. Examples include xbrl:conceptObject and xbrl:memberObject. All objects of the specified object types from the taxonomyName and any dependent objects will be imported. This property can only be used for taxonomy files using the OIM specification. The includeObjectTypes cannot include the label object.
21
- excludeLabels: bool | DefaultTrue # (optional) If set to true any labels attached to the objects comprising the dts deriving from the taxonomyName property will be excluded from the dts. The default value is false.
22
- followImport: bool | DefaultFalse # (optional) If set to false the dts resolution will not import taxonomies defined in descendant ImportedTaxonomyObjects. These imports will be excluded from the dts. The default value is true. This means if a taxonomy QName is provided all imprtedTaxonomy objects will be brought into the dts.
21
+ excludeLabels: Union[bool, DefaultTrue] # (optional) If set to true any labels attached to the objects comprising the dts deriving from the taxonomyName property will be excluded from the dts. The default value is false.
22
+ followImport: Union[bool, DefaultFalse] # (optional) If set to false the dts resolution will not import taxonomies defined in descendant ImportedTaxonomyObjects. These imports will be excluded from the dts. The default value is true. This means if a taxonomy QName is provided all imprtedTaxonomy objects will be brought into the dts.
@@ -37,9 +37,9 @@ class XbrlRelationship(XbrlTaxonomyObject):
37
37
  return ("relationship", f"{str(self.source)}\u2192{self.target}", tuple(nestedProperties))
38
38
 
39
39
  class XbrlRelationshipSet:
40
- _relationshipsFrom: dict[QName, list[XbrlRelationship]] | None
41
- _relationshipsTo: dict[QName, list[XbrlRelationship]] | None
42
- _roots: OrderedSet[QName] | None
40
+ _relationshipsFrom: Optional[dict[QName, list[XbrlRelationship]]]
41
+ _relationshipsTo: Optional[dict[QName, list[XbrlRelationship]]]
42
+ _roots: Optional[OrderedSet[QName]]
43
43
 
44
44
  def __init__(self):
45
45
  self._relationshipsFrom = self._relationshipsTo = self._roots = None
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, Any, Optional
5
+ from typing import TYPE_CHECKING, Any, Optional, Union
6
6
 
7
7
  from arelle.ModelValue import QName
8
8
  from arelle.PythonUtil import OrderedSet
@@ -23,6 +23,6 @@ class XbrlPropertyType(XbrlReferencableTaxonomyObject):
23
23
  name: QNameKeyType # (required) The name is a QName that uniquely identifies the property type object.
24
24
  dataType: QName # (required) Indicates the dataType of the property value. 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.
25
25
  enumerationDomain: Optional[QName] # (optional) Used to specify the QName of a domain object that is used to derive enumerated domain members QNames that can be used for the property.
26
- definitional: bool | DefaultFalse # (optional) Indicates if the property is definitional. If changes to the property change the meaning of the object it is definitional, if the property provides extra information about the object it is not definitional. If no value is provided the attribute defaults to false.
26
+ definitional: Union[bool, DefaultFalse] # (optional) Indicates if the property is definitional. If changes to the property change the meaning of the object it is definitional, if the property provides extra information about the object it is not definitional. If no value is provided the attribute defaults to false.
27
27
  allowedObjects: set[QName] # (optional) List of allowable objects that the property can be used with. For example the balance property can only be used with concept objects.
28
- allowedAsLinkProperty: bool | DefaultFalse # (optional) Indicates if the property can be used a a properton the link between two objects in a relationship. If no value is provided the attribute defaults to false.
28
+ allowedAsLinkProperty: Union[bool, DefaultFalse] # (optional) Indicates if the property can be used a a properton the link between two objects in a relationship. If no value is provided the attribute defaults to false.
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, Optional, Any
5
+ from typing import TYPE_CHECKING, Optional, Any, Union
6
6
  from collections import OrderedDict
7
7
  from arelle.ModelValue import QName, AnyURI
8
8
  from arelle.PythonUtil import OrderedSet
@@ -12,9 +12,9 @@ from .XbrlTaxonomyObject import XbrlReportObject
12
12
  class XbrlFact(XbrlReportObject):
13
13
  report: XbrlDtsType
14
14
  id: Optional[str] # synthesized id (from fact key in JSON), marked Optional because it's a key, not value, in json source.
15
- value: str | None # (required) The value of the {value} property of the fact. The value MUST be represented as (xbrlje:invalidFactValue):
15
+ value: Optional[str] # (required) The value of the {value} property of the fact. The value MUST be represented as (xbrlje:invalidFactValue):
16
16
  decimals: Optional[int] # An integer providing the value of the {decimals} property, or absent if the value is infinitely precise or not applicable (for nil or non-numeric facts).
17
- dimensions: dict[QName | str, str] # (required) A dimensions object with properties corresponding to the members of the {dimensions} property.
17
+ dimensions: dict[Union[QName, str], str] # (required) A dimensions object with properties corresponding to the members of the {dimensions} property.
18
18
  links: dict[str, dict[str, list[str]]] # A links object, cormesponding to the link groups associated with the fact. This member MAY be absent if there are no link groups associated with the fact.
19
19
 
20
20
 
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TYPE_CHECKING, Optional
5
+ from typing import TYPE_CHECKING, Optional, Union
6
6
  from decimal import Decimal
7
7
 
8
8
  from arelle.ModelValue import QName
@@ -20,8 +20,8 @@ class XbrlTableTemplate(XbrlReferencableTaxonomyObject):
20
20
 
21
21
  class XbrlAxisDimensions(XbrlTaxonomyObject):
22
22
  dimensionName: QName # (required) The QName of a dimension defined by the cubeName property.
23
- showTotal: bool | DefaultFalse # (optional) Indicates if the total of the dimension is shown in the axis. This is the value associated with the dimension absent. If no value is provided the default is false. The concept dimension defaults to false and cannot be set to true.
24
- showAncestorColumns: bool | DefaultFalse # (optional) Define members on an explicit dimension that are not leaf values that are included on the axis. If not provided only leaf members on the axis will show.
23
+ showTotal: Union[bool, DefaultFalse] # (optional) Indicates if the total of the dimension is shown in the axis. This is the value associated with the dimension absent. If no value is provided the default is false. The concept dimension defaults to false and cannot be set to true.
24
+ showAncestorColumns: Union[bool, DefaultFalse] # (optional) Define members on an explicit dimension that are not leaf values that are included on the axis. If not provided only leaf members on the axis will show.
25
25
  totalLocation: Optional[str] # (optional) Indicates if the total is at the start or at the end when shown on the axis. The default value is end. The totalLocation attribute can only have a value of start or end.
26
26
  periodAlign: OrderedSet[str] # (optional) the period align attribute can only be used with the period dimension. This attribute is used to align time values of facts in a dimension rather than being created as seperate columns or rows. The values @start and @end are used to indicate if instant values are aligned with duration values. These values are used to support roll-forwards in a datatgrid and will align duration values and instant values with the same start and end dates.
27
27
 
@@ -2,7 +2,7 @@
2
2
  See COPYRIGHT.md for copyright information.
3
3
  """
4
4
 
5
- from typing import TypeAlias
5
+ from typing_extensions import TypeAlias
6
6
  from arelle.ModelValue import QName
7
7
 
8
8
  XbrlDtsType: TypeAlias = "XbrlDts"
@@ -16,8 +16,7 @@ For debugging, saves the xsd objects loaded from the OIM taxonomy if
16
16
 
17
17
  """
18
18
 
19
- from typing import TYPE_CHECKING, cast, GenericAlias, Union, _UnionGenericAlias
20
- from types import UnionType
19
+ from typing import TYPE_CHECKING, cast, GenericAlias, Union, _UnionGenericAlias, get_origin
21
20
 
22
21
  import os, io, json, sys, time, traceback
23
22
  import jsonschema
@@ -377,7 +376,7 @@ def loadOIMTaxonomy(cntlr, error, warning, modelXbrl, oimFile, mappedUri, **kwar
377
376
  eltClass = propType.__args__[0]
378
377
  if isinstance(jsonValue, list):
379
378
  for iObj, listObj in enumerate(jsonValue):
380
- if isinstance(eltClass, str) or eltClass.__name__.startswith("Xbrl"): # nested Xbrl objects
379
+ if isinstance(eltClass, str) or getattr(eltClass, "__name__", "").startswith("Xbrl"): # nested Xbrl objects
381
380
  if isinstance(listObj, dict):
382
381
  # this handles lists of dict objects. For dicts of key-value dict objects see above.
383
382
  createTaxonomyObjects(propName, listObj, newObj, pathParts + [f'{propName}[{iObj}]'])
@@ -401,7 +400,7 @@ def loadOIMTaxonomy(cntlr, error, warning, modelXbrl, oimFile, mappedUri, **kwar
401
400
  collectionProp.append(listObj)
402
401
  elif isinstance(jsonValue, dict) and keyClass:
403
402
  for iObj, (valKey, valVal) in enumerate(jsonValue.items()):
404
- if isinstance(_keyClass, UnionType):
403
+ if get_origin(_keyClass) is Union:
405
404
  if QName in _keyClass.__args__ and ":" in valKey:
406
405
  _valKey = qname(listObj, prefixNamespaces)
407
406
  if _valKey is None:
@@ -447,7 +446,7 @@ def loadOIMTaxonomy(cntlr, error, warning, modelXbrl, oimFile, mappedUri, **kwar
447
446
  keyValue = jsonValue # e.g. the QNAme of the new object for parent object collection
448
447
  elif propType in (type(oimParentObj), type(oimParentObj).__name__): # propType may be a TypeAlias which is a string name of class
449
448
  setattr(newObj, propName, oimParentObj)
450
- elif ((isinstance(propType, (UnionType,_UnionGenericAlias)) or isinstance(getattr(propType, "__origin__", None), type(Union))) and # Optional[ ] type
449
+ elif (((get_origin(propType) is Union) or isinstance(get_origin(propType), type(Union))) and # Optional[ ] type
451
450
  propType.__args__[-1] in (type(None), DefaultTrue, DefaultFalse, DefaultZero)):
452
451
  setattr(newObj, propName, {type(None): None, DefaultTrue: True, DefaultFalse: False, DefaultZero:0}[propType.__args__[-1]]) # use first of union for prop value creation
453
452
  else: # absent json element
@@ -0,0 +1,77 @@
1
+ '''
2
+ See COPYRIGHT.md for copyright information.
3
+ '''
4
+ from __future__ import annotations
5
+
6
+ from enum import Enum
7
+
8
+ from arelle import XbrlConst
9
+ from arelle.ModelValue import QName
10
+
11
+
12
+ class LinkbaseType(Enum):
13
+ CALCULATION = "calculation"
14
+ DEFINITION = "definition"
15
+ LABEL = "label"
16
+ PRESENTATION = "presentation"
17
+ REFERENCE = "reference"
18
+
19
+ @staticmethod
20
+ def fromRefUri(refUri: str | None) -> LinkbaseType | None:
21
+ """
22
+ Returns the LinkbaseType corresponding to the given ref URI.
23
+ If the URI does not match any known linkbase reference type, returns None.
24
+ """
25
+ if refUri is None:
26
+ return None
27
+ return LINKBASE_TYPE_BY_REF_URI.get(refUri, None)
28
+
29
+ def getArcQn(self) -> QName:
30
+ """
31
+ Returns the qname of the arc associated with this LinkbaseType.
32
+ """
33
+ return LINKBASE_ARC_QN[self]
34
+
35
+ def getLinkQn(self) -> QName:
36
+ """
37
+ Returns the qname of the link associated with this LinkbaseType.
38
+ """
39
+ return LINKBASE_LINK_QN[self]
40
+
41
+ def getLowerName(self) -> str:
42
+ """
43
+ Returns the lower-case name of this LinkbaseType.
44
+ """
45
+ return self.value.lower()
46
+
47
+ def getRefUri(self) -> str:
48
+ """
49
+ Returns the ref URI associated with this LinkbaseType.
50
+ """
51
+ return LINKBASE_REF_URIS[self]
52
+
53
+
54
+ LINKBASE_ARC_QN = {
55
+ LinkbaseType.CALCULATION: XbrlConst.qnLinkCalculationArc,
56
+ LinkbaseType.DEFINITION: XbrlConst.qnLinkDefinitionArc,
57
+ LinkbaseType.LABEL: XbrlConst.qnLinkLabelArc,
58
+ LinkbaseType.PRESENTATION: XbrlConst.qnLinkPresentationArc,
59
+ LinkbaseType.REFERENCE: XbrlConst.qnLinkReferenceArc,
60
+ }
61
+
62
+ LINKBASE_LINK_QN = {
63
+ LinkbaseType.CALCULATION: XbrlConst.qnLinkCalculationLink,
64
+ LinkbaseType.DEFINITION: XbrlConst.qnLinkDefinitionLink,
65
+ LinkbaseType.LABEL: XbrlConst.qnLinkLabelLink,
66
+ LinkbaseType.PRESENTATION: XbrlConst.qnLinkPresentationLink,
67
+ LinkbaseType.REFERENCE: XbrlConst.qnLinkReferenceLink,
68
+ }
69
+
70
+ LINKBASE_REF_URIS = {
71
+ LinkbaseType.CALCULATION: "http://www.xbrl.org/2003/role/calculationLinkbaseRef",
72
+ LinkbaseType.DEFINITION: "http://www.xbrl.org/2003/role/definitionLinkbaseRef",
73
+ LinkbaseType.LABEL: "http://www.xbrl.org/2003/role/labelLinkbaseRef",
74
+ LinkbaseType.PRESENTATION: "http://www.xbrl.org/2003/role/presentationLinkbaseRef",
75
+ LinkbaseType.REFERENCE: "http://www.xbrl.org/2003/role/referenceLinkbaseRef",
76
+ }
77
+ LINKBASE_TYPE_BY_REF_URI = {v: k for k, v in LINKBASE_REF_URIS.items()}