arelle-release 2.37.28__py3-none-any.whl → 2.37.29__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 (32) hide show
  1. arelle/ModelTestcaseObject.py +9 -3
  2. arelle/Validate.py +29 -14
  3. arelle/WebCache.py +10 -5
  4. arelle/_version.py +2 -2
  5. arelle/plugin/validate/EDINET/DisclosureSystems.py +1 -0
  6. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +67 -0
  7. arelle/plugin/validate/EDINET/ValidationPluginExtension.py +29 -0
  8. arelle/plugin/validate/EDINET/__init__.py +119 -0
  9. arelle/plugin/validate/EDINET/resources/config.xml +12 -0
  10. arelle/plugin/validate/EDINET/rules/__init__.py +0 -0
  11. arelle/plugin/validate/EDINET/rules/upload.py +153 -0
  12. arelle/plugin/validate/NL/rules/nl_kvk.py +52 -0
  13. arelle/utils/EntryPointDetection.py +6 -0
  14. {arelle_release-2.37.28.dist-info → arelle_release-2.37.29.dist-info}/METADATA +2 -1
  15. {arelle_release-2.37.28.dist-info → arelle_release-2.37.29.dist-info}/RECORD +32 -14
  16. tests/integration_tests/validation/conformance_suite_configs.py +2 -0
  17. tests/integration_tests/validation/conformance_suite_configurations/edinet.py +52 -0
  18. tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py +13 -3
  19. tests/resources/conformance_suites/edinet/EC0121E/index.xml +22 -0
  20. tests/resources/conformance_suites/edinet/EC0121E/invalid01.zip +0 -0
  21. tests/resources/conformance_suites/edinet/EC0124E/index.xml +22 -0
  22. tests/resources/conformance_suites/edinet/EC0124E/invalid01.zip +0 -0
  23. tests/resources/conformance_suites/edinet/EC0132E/index.xml +22 -0
  24. tests/resources/conformance_suites/edinet/EC0132E/invalid01.zip +0 -0
  25. tests/resources/conformance_suites/edinet/README.md +4 -0
  26. tests/resources/conformance_suites/edinet/index.xml +7 -0
  27. tests/resources/conformance_suites/edinet/valid/index.xml +20 -0
  28. tests/resources/conformance_suites/edinet/valid/valid01.zip +0 -0
  29. {arelle_release-2.37.28.dist-info → arelle_release-2.37.29.dist-info}/WHEEL +0 -0
  30. {arelle_release-2.37.28.dist-info → arelle_release-2.37.29.dist-info}/entry_points.txt +0 -0
  31. {arelle_release-2.37.28.dist-info → arelle_release-2.37.29.dist-info}/licenses/LICENSE.md +0 -0
  32. {arelle_release-2.37.28.dist-info → arelle_release-2.37.29.dist-info}/top_level.txt +0 -0
@@ -319,9 +319,15 @@ class ModelTestcaseVariation(ModelObject):
319
319
  errorElements = XmlUtil.descendants(self, None, "error")
320
320
  resultElement = XmlUtil.descendant(self, None, "result")
321
321
  if isinstance(errorElements,list) and len(errorElements) > 0:
322
- return [ModelValue.qname(e, e.stringValue) if not e.get("nonStandardErrorCodes")
323
- else e.stringValue
324
- for e in errorElements]
322
+ errorCodes = []
323
+ for errorElement in errorElements:
324
+ if errorElement.get("nonStandardErrorCodes"):
325
+ errorCode = errorElement.stringValue
326
+ else:
327
+ errorCode = ModelValue.qname(errorElement, errorElement.stringValue)
328
+ num = int(errorElement.attr("num") or 1)
329
+ errorCodes.extend([errorCode] * num)
330
+ return errorCodes
325
331
  #else:
326
332
  # errorElement = errorElements[1]
327
333
  # if errorElement is not None and not errorElement.get("nonStandardErrorCodes"):
arelle/Validate.py CHANGED
@@ -338,17 +338,18 @@ class Validate:
338
338
  loadedModels.append(modelXbrl)
339
339
  PackageManager.packageInfo(self.modelXbrl.modelManager.cntlr, readMeFirstUri, reload=True, errors=modelXbrl.errors)
340
340
  else: # not a multi-schemaRef versioning report
341
+ readMeFirstUriIsArchive = isReportPackageExtension(readMeFirstUri)
341
342
  readMeFirstUriIsEmbeddedZipFile = False
342
343
  if self.useFileSource.isArchive and not isLegacyAbs(readMeFirstUri):
343
- if isReportPackageExtension(readMeFirstUri):
344
+ if readMeFirstUriIsArchive:
344
345
  readMeFirstUriIsEmbeddedZipFile = True
345
346
  else:
346
347
  normalizedReadMeFirstUri = self.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(readMeFirstUri, baseForElement)
347
348
  archivePath = FileSource.archiveFilenameParts(normalizedReadMeFirstUri)
348
349
  if archivePath:
349
350
  with self.useFileSource.fs.open(archivePath[1]) as embeddedFile:
350
- readMeFirstUriIsEmbeddedZipFile = zipfile.is_zipfile(embeddedFile)
351
- if not readMeFirstUriIsEmbeddedZipFile:
351
+ readMeFirstUriIsArchive = readMeFirstUriIsEmbeddedZipFile = zipfile.is_zipfile(embeddedFile)
352
+ if not readMeFirstUriIsArchive:
352
353
  modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
353
354
  readMeFirstUri,
354
355
  _("validating"),
@@ -400,7 +401,16 @@ class Validate:
400
401
  # resolve an IXDS in entrypoints
401
402
  for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
402
403
  pluginXbrlMethod(self, filesource,entrypoints)
403
- filesource.select(entrypoints[0].get("file", None))
404
+ for entrypoint in entrypoints:
405
+ filesource.select(entrypoint.get("file", None))
406
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
407
+ filesource,
408
+ _("validating"),
409
+ base=filesource.basefile + "/",
410
+ errorCaptureLevel=errorCaptureLevel,
411
+ ixdsTarget=modelTestcaseVariation.ixdsTarget,
412
+ errors=preLoadingErrors)
413
+ loadedModels.append(modelXbrl)
404
414
  except Exception as err:
405
415
  self.modelXbrl.error("exception:" + type(err).__name__,
406
416
  _("Testcase variation validation exception: %(error)s, entry URL: %(instance)s"),
@@ -427,15 +437,16 @@ class Validate:
427
437
  # Legacy ESEF conformance suite logic.
428
438
  for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ReportPackageIxds"):
429
439
  filesource.select(pluginXbrlMethod(filesource, **_rptPkgIxdsOptions))
430
- modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
431
- filesource,
432
- _("validating"),
433
- base=baseForElement,
434
- errorCaptureLevel=errorCaptureLevel,
435
- ixdsTarget=modelTestcaseVariation.ixdsTarget,
436
- isLoadable=modelTestcaseVariation.variationDiscoversDTS or filesource.url,
437
- errors=preLoadingErrors)
438
- loadedModels.append(modelXbrl)
440
+ if len(loadedModels) == 0:
441
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
442
+ filesource,
443
+ _("validating"),
444
+ base=baseForElement,
445
+ errorCaptureLevel=errorCaptureLevel,
446
+ ixdsTarget=modelTestcaseVariation.ixdsTarget,
447
+ isLoadable=modelTestcaseVariation.variationDiscoversDTS or filesource.url,
448
+ errors=preLoadingErrors)
449
+ loadedModels.append(modelXbrl)
439
450
 
440
451
  for model in loadedModels:
441
452
  modelXbrl.isTestcaseVariation = True
@@ -730,7 +741,11 @@ class Validate:
730
741
  indexPath = indexPath[len(baseZipFile) + 1:]
731
742
  indexPath = indexPath.replace("\\", "/")
732
743
  variationIdPath = f'{indexPath}:{modelTestcaseVariation.id}'
733
- if userExpectedErrors := testcaseExpectedErrors.get(variationIdPath):
744
+ userExpectedErrors = []
745
+ for userPattern, userErrors in testcaseExpectedErrors.items():
746
+ if fnmatch.fnmatch(variationIdPath, userPattern):
747
+ userExpectedErrors.extend(userErrors)
748
+ if userExpectedErrors:
734
749
  if expected is None:
735
750
  expected = []
736
751
  if isinstance(expected, str):
arelle/WebCache.py CHANGED
@@ -27,6 +27,13 @@ try:
27
27
  import ssl
28
28
  except ImportError:
29
29
  ssl = None
30
+
31
+ try:
32
+ import truststore
33
+ except ImportError:
34
+ # truststore requires Python > 3.9
35
+ truststore = None
36
+
30
37
  from arelle.FileSource import SERVER_WEB_CACHE, archiveFilenameParts
31
38
  from arelle.PluginManager import pluginClassMethods
32
39
  from arelle.UrlUtil import isHttpUrl
@@ -267,12 +274,10 @@ class WebCache:
267
274
  self.http_auth_handler = proxyhandlers.HTTPBasicAuthHandler()
268
275
  proxyHandlers = [self.proxy_handler, self.proxy_auth_handler, self.http_auth_handler]
269
276
  if ssl:
270
- # Attempts to load the default CA certificates from the OS.
271
- context = ssl.create_default_context()
277
+ # Attempt to load the default CA certificates from the OS using truststore if available, else fallback to OpenSSL's default context.
278
+ context = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) if truststore else ssl.create_default_context()
272
279
  # Include certifi certificates (Mozilla’s carefully curated
273
- # collection) for systems with outdated certs and for platforms
274
- # that we're unable to load certs from (macOS and some Linux
275
- # distros.)
280
+ # collection) for systems with outdated certs.
276
281
  context.load_verify_locations(cafile=certifi.where())
277
282
  if self.noCertificateCheck: # this is required in some Akamai environments, such as sec.gov
278
283
  context.check_hostname = False
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.28'
21
- __version_tuple__ = version_tuple = (2, 37, 28)
20
+ __version__ = version = '2.37.29'
21
+ __version_tuple__ = version_tuple = (2, 37, 29)
@@ -0,0 +1 @@
1
+ DISCLOSURE_SYSTEM_EDINET = 'EDINET'
@@ -0,0 +1,67 @@
1
+ """
2
+ See COPYRIGHT.md for copyright information.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ import zipfile
7
+ from dataclasses import dataclass
8
+ from functools import lru_cache
9
+ from pathlib import Path
10
+
11
+ from arelle.ModelXbrl import ModelXbrl
12
+ from arelle.ValidateXbrl import ValidateXbrl
13
+ from arelle.typing import TypeGetText
14
+ from arelle.utils.PluginData import PluginData
15
+
16
+ _: TypeGetText
17
+
18
+
19
+ @dataclass
20
+ class PluginValidationDataExtension(PluginData):
21
+ _primaryModelXbrl: ModelXbrl | None = None
22
+
23
+ # Identity hash for caching.
24
+ def __hash__(self) -> int:
25
+ return id(self)
26
+
27
+ @lru_cache(1)
28
+ def shouldValidateUpload(self, val: ValidateXbrl) -> bool:
29
+ """
30
+ Determine if the upload validation should be performed on this model.
31
+
32
+ Upload validation should not be performed if the target document is
33
+ not a zipfile.
34
+
35
+ Upload validation should only be performed once for the entire package,
36
+ not duplicated for each model. To facilitate this with Arelle's validation
37
+ system which largely prevents referencing other models, we can use `--keepOpen`
38
+ and check if the given model is the first to be loaded.
39
+ :param val: The ValidateXbrl instance with a model to check.
40
+ :return: True if upload validation should be performed, False otherwise.
41
+ """
42
+ modelXbrl = val.modelXbrl
43
+ if modelXbrl == val.testModelXbrl:
44
+ # Not running within a testcase
45
+ if modelXbrl != modelXbrl.modelManager.loadedModelXbrls[0]:
46
+ return False
47
+ if not modelXbrl.fileSource.fs:
48
+ return False # No stream
49
+ if not isinstance(modelXbrl.fileSource.fs, zipfile.ZipFile):
50
+ return False # Not a zipfile
51
+ return True
52
+
53
+ @lru_cache(1)
54
+ def getUploadFilepaths(self, modelXbrl: ModelXbrl) -> list[Path]:
55
+ if not modelXbrl.fileSource.fs or \
56
+ not isinstance(modelXbrl.fileSource.fs, zipfile.ZipFile):
57
+ modelXbrl.warning(
58
+ codes="EDINET.uploadNotValidated",
59
+ msg=_("The target file is not a zip file, so upload validation could not be performed.")
60
+ )
61
+ return []
62
+ paths = set()
63
+ for name in modelXbrl.fileSource.fs.namelist():
64
+ path = Path(name)
65
+ paths.add(path)
66
+ paths.update(path.parents)
67
+ return sorted(paths)
@@ -0,0 +1,29 @@
1
+ """
2
+ See COPYRIGHT.md for copyright information.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ from typing import Any
7
+
8
+ from arelle.ValidateXbrl import ValidateXbrl
9
+ from arelle.typing import TypeGetText
10
+ from arelle.utils.validate.ValidationPlugin import ValidationPlugin
11
+ from .DisclosureSystems import DISCLOSURE_SYSTEM_EDINET
12
+ from .PluginValidationDataExtension import PluginValidationDataExtension
13
+
14
+ _: TypeGetText
15
+
16
+
17
+ class ValidationPluginExtension(ValidationPlugin):
18
+ def newPluginData(self, validateXbrl: ValidateXbrl) -> PluginValidationDataExtension:
19
+ disclosureSystem = validateXbrl.disclosureSystem.name
20
+ if disclosureSystem == DISCLOSURE_SYSTEM_EDINET:
21
+ pass
22
+ else:
23
+ raise ValueError(f'Invalid EDINET disclosure system: {disclosureSystem}')
24
+ return PluginValidationDataExtension(
25
+ self.name,
26
+ )
27
+
28
+ def modelXbrlLoadComplete(self, *args: Any, **kwargs: Any) -> None:
29
+ return None
@@ -0,0 +1,119 @@
1
+ """
2
+ See COPYRIGHT.md for copyright information.
3
+ - [Operation Guides](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WEEK0060.html)
4
+ - [Document Search](https://disclosure2.edinet-fsa.go.jp/week0020.aspx)
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import zipfile
9
+ from collections import defaultdict
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ from lxml import etree
14
+ from lxml.etree import _Element
15
+
16
+ from arelle.FileSource import FileSource
17
+ from arelle.Version import authorLabel, copyrightLabel
18
+ from .ValidationPluginExtension import ValidationPluginExtension
19
+ from .rules import upload
20
+
21
+ PLUGIN_NAME = "Validate EDINET"
22
+ DISCLOSURE_SYSTEM_VALIDATION_TYPE = "EDINET"
23
+
24
+
25
+ validationPlugin = ValidationPluginExtension(
26
+ name=PLUGIN_NAME,
27
+ disclosureSystemConfigUrl=Path(__file__).parent / "resources" / "config.xml",
28
+ validationTypes=[DISCLOSURE_SYSTEM_VALIDATION_TYPE],
29
+ validationRuleModules=[
30
+ upload,
31
+ ],
32
+ )
33
+
34
+
35
+ def disclosureSystemTypes(*args: Any, **kwargs: Any) -> tuple[tuple[str, str], ...]:
36
+ return validationPlugin.disclosureSystemTypes
37
+
38
+
39
+ def disclosureSystemConfigURL(*args: Any, **kwargs: Any) -> str:
40
+ return validationPlugin.disclosureSystemConfigURL
41
+
42
+
43
+ def _parseManifestDoc(xmlRootElement: _Element, base: Path) -> dict[str, list[Path]]:
44
+ sets = defaultdict(list)
45
+ for instanceElt in xmlRootElement.iter(tag="{http://disclosure.edinet-fsa.go.jp/2013/manifest}instance"):
46
+ instanceId = str(instanceElt.attrib["id"])
47
+ for ixbrlElt in instanceElt.iter(tag="{http://disclosure.edinet-fsa.go.jp/2013/manifest}ixbrl"):
48
+ uri = ixbrlElt.text.strip() if ixbrlElt.text is not None else None
49
+ if uri:
50
+ sets[instanceId].append(base / uri)
51
+ return sets
52
+
53
+
54
+ def fileSourceEntrypointFiles(filesource: FileSource, inlineOnly: bool, *args: Any, **kwargs: Any) -> list[dict[str, Any]] | None:
55
+ manifests = {}
56
+ if filesource.isArchive:
57
+ if filesource.isTaxonomyPackage:
58
+ return None
59
+ if filesource.reportPackage is not None:
60
+ return None
61
+ for _archiveFile in (filesource.dir or ()):
62
+ if not Path(_archiveFile).stem.startswith('manifest'):
63
+ continue
64
+ assert isinstance(filesource.fs, zipfile.ZipFile), \
65
+ "The EDINET plugin only supports archives in .zip format."
66
+ with filesource.fs.open(_archiveFile) as manifestDoc:
67
+ base = Path(_archiveFile).parent
68
+ xmlRootElement = etree.fromstring(manifestDoc.read())
69
+ manifests.update(_parseManifestDoc(xmlRootElement, base))
70
+ elif (dirpath := Path(str(filesource.url))).is_dir():
71
+ for file in dirpath.rglob("*"):
72
+ if not file.is_file():
73
+ continue
74
+ if not file.stem.startswith('manifest'):
75
+ continue
76
+ with open(file, 'rb') as manifestDoc:
77
+ base = file.parent
78
+ xmlRootElement = etree.fromstring(manifestDoc.read())
79
+ manifests.update(_parseManifestDoc(xmlRootElement, base))
80
+ if len(manifests) == 0:
81
+ return None
82
+
83
+ entrypointFiles = []
84
+ for instanceId, uris in manifests.items():
85
+ entrypoints = []
86
+ for uri in uris:
87
+ filesource.select(str(uri))
88
+ entrypoints.append({"file": filesource.url})
89
+ entrypointFiles.append({'ixds': entrypoints})
90
+ return entrypointFiles
91
+
92
+
93
+ def modelXbrlLoadComplete(*args: Any, **kwargs: Any) -> None:
94
+ return validationPlugin.modelXbrlLoadComplete(*args, **kwargs)
95
+
96
+
97
+ def validateFinally(*args: Any, **kwargs: Any) -> None:
98
+ return validationPlugin.validateFinally(*args, **kwargs)
99
+
100
+
101
+ def validateXbrlFinally(*args: Any, **kwargs: Any) -> None:
102
+ return validationPlugin.validateXbrlFinally(*args, **kwargs)
103
+
104
+
105
+ __pluginInfo__ = {
106
+ "name": PLUGIN_NAME,
107
+ "version": "0.0.1",
108
+ "description": "Validation plugin for the EDINET taxonomies.",
109
+ "license": "Apache-2",
110
+ "author": authorLabel,
111
+ "copyright": copyrightLabel,
112
+ "import": ("inlineXbrlDocumentSet",),
113
+ "DisclosureSystem.Types": disclosureSystemTypes,
114
+ "DisclosureSystem.ConfigURL": disclosureSystemConfigURL,
115
+ "FileSource.EntrypointFiles": fileSourceEntrypointFiles,
116
+ "ModelXbrl.LoadComplete": modelXbrlLoadComplete,
117
+ "Validate.XBRL.Finally": validateXbrlFinally,
118
+ "ValidateFormula.Finished": validateFinally,
119
+ }
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <DisclosureSystems
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:noNamespaceSchemaLocation="../../../../config/disclosuresystems.xsd">
5
+ <!-- see arelle/config/disclosuresystems.xml for full comments -->
6
+ <DisclosureSystem
7
+ names="EDINET|edinet"
8
+ description="Checks for EDINET."
9
+ validationType="EDINET"
10
+ exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
11
+ />
12
+ </DisclosureSystems>
File without changes
@@ -0,0 +1,153 @@
1
+ """
2
+ See COPYRIGHT.md for copyright information.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ import re
7
+ import zipfile
8
+ from collections.abc import Iterable
9
+ from typing import Any, cast, IO
10
+
11
+ from arelle.ValidateXbrl import ValidateXbrl
12
+ from arelle.typing import TypeGetText
13
+ from arelle.utils.PluginHooks import ValidationHook
14
+ from arelle.utils.validate.Decorator import validation
15
+ from arelle.utils.validate.Validation import Validation
16
+ from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
17
+ from ..PluginValidationDataExtension import PluginValidationDataExtension
18
+
19
+ _: TypeGetText
20
+
21
+ FILENAME_STEM_PATTERN = re.compile(r'[a-zA-Z0-9_-]*')
22
+
23
+
24
+ @validation(
25
+ hook=ValidationHook.XBRL_FINALLY,
26
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
27
+ )
28
+ def rule_EC0121E(
29
+ pluginData: PluginValidationDataExtension,
30
+ val: ValidateXbrl,
31
+ *args: Any,
32
+ **kwargs: Any,
33
+ ) -> Iterable[Validation]:
34
+ """
35
+ EDINET.EC0121E: There is a directory or file that contains more than 31 characters
36
+ or uses characters other than those allowed (alphanumeric characters, '-' and '_').
37
+
38
+ Implementation note: getManifestDirectoryPaths results in this validation only
39
+ considering files that are beneath the same directory as the manifest file that
40
+ the given DTS originated from. This prevents duplicate errors for packages
41
+ with multiple document sets, but can still cause duplicates when a single manifest
42
+ file has multiple document sets, as is often the case with AuditDoc manifests.
43
+ """
44
+ if not pluginData.shouldValidateUpload(val):
45
+ return
46
+ uploadFilepaths = pluginData.getUploadFilepaths(val.modelXbrl)
47
+ for path in uploadFilepaths:
48
+ if len(str(path.name)) > 31 or not FILENAME_STEM_PATTERN.match(path.stem):
49
+ yield Validation.error(
50
+ codes='EDINET.EC0121E',
51
+ msg=_("There is a directory or file in '%(directory)s' that contains more than 31 characters "
52
+ "or uses characters other than those allowed (alphanumeric characters, '-' and '_'). "
53
+ "Directory or file name: '%(basename)s'. "
54
+ "Please change the file name (or folder name) to within 31 characters and to usable "
55
+ "characters, and upload again."),
56
+ directory=str(path.parent),
57
+ basename=path.name,
58
+ file=str(path)
59
+ )
60
+
61
+
62
+ @validation(
63
+ hook=ValidationHook.XBRL_FINALLY,
64
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
65
+ )
66
+ def rule_EC0124E(
67
+ pluginData: PluginValidationDataExtension,
68
+ val: ValidateXbrl,
69
+ *args: Any,
70
+ **kwargs: Any,
71
+ ) -> Iterable[Validation]:
72
+ """
73
+ EDINET.EC0124E: There are no empty directories.
74
+
75
+ See note on EC0121E.
76
+ """
77
+ if not pluginData.shouldValidateUpload(val):
78
+ return
79
+ uploadFilepaths = pluginData.getUploadFilepaths(val.modelXbrl)
80
+ emptyDirectories = []
81
+ for path in uploadFilepaths:
82
+ if path.suffix:
83
+ continue
84
+ if not any(path in p.parents for p in uploadFilepaths):
85
+ emptyDirectories.append(str(path))
86
+ for emptyDirectory in emptyDirectories:
87
+ yield Validation.error(
88
+ codes='EDINET.EC0124E',
89
+ msg=_("There is no file directly under '%(emptyDirectory)s'. "
90
+ "No empty folders. "
91
+ "Please store the file in the appropriate folder or delete the folder and upload again."),
92
+ emptyDirectory=emptyDirectory,
93
+ )
94
+
95
+
96
+ @validation(
97
+ hook=ValidationHook.XBRL_FINALLY,
98
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
99
+ )
100
+ def rule_EC0132E(
101
+ pluginData: PluginValidationDataExtension,
102
+ val: ValidateXbrl,
103
+ *args: Any,
104
+ **kwargs: Any,
105
+ ) -> Iterable[Validation]:
106
+ """
107
+ EDINET.EC0132E: Store the manifest file directly under the relevant folder.
108
+ """
109
+ if not pluginData.shouldValidateUpload(val):
110
+ return
111
+ uploadFilepaths = pluginData.getUploadFilepaths(val.modelXbrl)
112
+ docFolders = ("PublicDoc", "PrivateDoc", "AuditDoc")
113
+ for filepath in uploadFilepaths:
114
+ if filepath.name not in docFolders:
115
+ continue
116
+ expectedManifestName = f'manifest_{filepath.name}.xml'
117
+ expectedManifestPath = filepath / expectedManifestName
118
+ if expectedManifestPath in uploadFilepaths:
119
+ continue
120
+ yield Validation.error(
121
+ codes='EDINET.EC0132E',
122
+ msg=_("'%(expectedManifestName)s' does not exist in '%(expectedManifestFolder)s'. "
123
+ "Please store the manifest file (or cover file) directly under the relevant folder and upload it again. "),
124
+ expectedManifestName=expectedManifestName,
125
+ expectedManifestFolder=str(filepath),
126
+ )
127
+
128
+
129
+ @validation(
130
+ hook=ValidationHook.XBRL_FINALLY,
131
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
132
+ )
133
+ def rule_EC0183E(
134
+ pluginData: PluginValidationDataExtension,
135
+ val: ValidateXbrl,
136
+ *args: Any,
137
+ **kwargs: Any,
138
+ ) -> Iterable[Validation]:
139
+ """
140
+ EDINET.EC0183E: The compressed file size exceeds 55MB.
141
+ """
142
+ if not pluginData.shouldValidateUpload(val):
143
+ return
144
+ zipFile = cast(zipfile.ZipFile, val.modelXbrl.fileSource.fs)
145
+ file = cast(IO[Any], zipFile.fp)
146
+ file.seek(0, 2) # Move to the end of the file
147
+ size = file.tell()
148
+ if size > 55 * 1000 * 1000: # Interpretting MB as megabytes (1,000,000 bytes)
149
+ yield Validation.error(
150
+ codes='EDINET.EC0183E',
151
+ msg=_("The compressed file size exceeds 55MB. "
152
+ "Please compress the file to a size of 55MB or less and upload it again."),
153
+ )
@@ -18,6 +18,7 @@ from arelle.ModelInstanceObject import ModelInlineFact
18
18
  from arelle.ModelObject import ModelObject
19
19
  from arelle.PrototypeDtsObject import PrototypeObject
20
20
  from arelle.ValidateDuplicateFacts import getDuplicateFactSets
21
+ from arelle.XbrlConst import standardLabel
21
22
  from arelle.XmlValidateConst import VALID
22
23
 
23
24
  from arelle import XbrlConst, XmlUtil, ModelDocument
@@ -1896,6 +1897,57 @@ def rule_nl_kvk_RTS_Annex_IV_Par_4_2(
1896
1897
  )
1897
1898
 
1898
1899
 
1900
+ @validation(
1901
+ hook=ValidationHook.XBRL_FINALLY,
1902
+ disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
1903
+ )
1904
+ def rule_nl_kvk_RTS_Annex_IV_Par_4_3(
1905
+ pluginData: PluginValidationDataExtension,
1906
+ val: ValidateXbrl,
1907
+ *args: Any,
1908
+ **kwargs: Any,
1909
+ ) -> Iterable[Validation]:
1910
+ """
1911
+ NL-KVK.RTS_Annex_IV_Par_4_3: Extension elements must be provided with a standard label in the language corresponding to the language of the annual report.
1912
+ """
1913
+ extensionData = pluginData.getExtensionData(val.modelXbrl)
1914
+ extensionConcepts = extensionData.extensionConcepts
1915
+ labelsRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
1916
+ missingLabels = []
1917
+ missingReportingLabels = []
1918
+ noStandardLabels = []
1919
+ for concept in extensionConcepts:
1920
+ if not concept.label(standardLabel,lang=pluginData.getReportXmlLang(val.modelXbrl),fallbackToQname=False):
1921
+ labelRels = labelsRelationshipSet.fromModelObject(concept)
1922
+ if len(labelRels) == 0:
1923
+ missingLabels.append(concept)
1924
+ for labelRel in labelRels:
1925
+ label = cast(ModelResource, labelRel.toModelObject)
1926
+ if label.role == XbrlConst.standardLabel:
1927
+ missingReportingLabels.append(concept)
1928
+ else:
1929
+ noStandardLabels.append(label)
1930
+ message = 'Extension element is missing a standard label or is missing a label in the language of the report. Review to ensure a standard label is defined with at least the language of the report.'
1931
+ if len(missingLabels) > 0:
1932
+ yield Validation.warning(
1933
+ codes='NL.NL-KVK.RTS_Annex_IV_Par_4_3.extensionConceptNoLabel',
1934
+ msg=_(message),
1935
+ modelObject=missingLabels,
1936
+ )
1937
+ if len(missingReportingLabels) > 0:
1938
+ yield Validation.warning(
1939
+ codes='NL.NL-KVK.RTS_Annex_IV_Par_4_3.missingLabelForRoleInReportLanguage',
1940
+ msg=_(message),
1941
+ modelObject=missingReportingLabels,
1942
+ )
1943
+ if len(noStandardLabels) > 0:
1944
+ yield Validation.warning(
1945
+ codes='NL.NL-KVK.RTS_Annex_IV_Par_4_3.extensionConceptNoStandardLabel',
1946
+ msg=_(message),
1947
+ modelObject=noStandardLabels,
1948
+ )
1949
+
1950
+
1899
1951
  @validation(
1900
1952
  hook=ValidationHook.XBRL_FINALLY,
1901
1953
  disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
@@ -9,6 +9,12 @@ from arelle import (
9
9
  def filesourceEntrypointFiles(filesource, entrypointFiles=None, inlineOnly=False):
10
10
  if entrypointFiles is None:
11
11
  entrypointFiles = []
12
+ for pluginXbrlMethod in PluginManager.pluginClassMethods("FileSource.EntrypointFiles"):
13
+ resultEntrypointFiles = pluginXbrlMethod(filesource, inlineOnly)
14
+ if resultEntrypointFiles is not None:
15
+ del entrypointFiles[:] # clear list
16
+ entrypointFiles.extend(resultEntrypointFiles)
17
+ return entrypointFiles
12
18
  if filesource.isArchive:
13
19
  if filesource.isTaxonomyPackage: # if archive is also a taxonomy package, activate mappings
14
20
  filesource.loadTaxonomyPackageMappings()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arelle-release
3
- Version: 2.37.28
3
+ Version: 2.37.29
4
4
  Summary: An open source XBRL platform.
5
5
  Author-email: "arelle.org" <support@arelle.org>
6
6
  License: Apache-2.0
@@ -41,6 +41,7 @@ Requires-Dist: pillow<12,>=10
41
41
  Requires-Dist: pyparsing==3.*
42
42
  Requires-Dist: python-dateutil==2.*
43
43
  Requires-Dist: regex
44
+ Requires-Dist: truststore==0.*; python_version > "3.9"
44
45
  Requires-Dist: typing-extensions==4.*
45
46
  Provides-Extra: crypto
46
47
  Requires-Dist: pycryptodome==3.*; extra == "crypto"
@@ -45,7 +45,7 @@ arelle/ModelRelationshipSet.py,sha256=jlLqEnd0KrLjpRUhDzFLgMPsRmyOwfgl1w13yW3flL
45
45
  arelle/ModelRenderingObject.py,sha256=iPhSUlSBG-FLzAfIdUW06UZDgTCaZJ4K2mxvAtSe2BU,76021
46
46
  arelle/ModelRssItem.py,sha256=GzFkmluOlFsVcrxn9HAyOAcuE7rcHUOGkp4Q6F2IlT8,7713
47
47
  arelle/ModelRssObject.py,sha256=xjuwyJ8pU5sQmNPJFQakDEEnujZg2bMCTaj3zVezHL8,992
48
- arelle/ModelTestcaseObject.py,sha256=sOyIktwv23BWOGyokzcwlJALp7UENsMAKKJmVfAZh6c,22163
48
+ arelle/ModelTestcaseObject.py,sha256=dnCxatJcFPlu5BgTuToqgrQowYNx4YtA5KrmW4vHko4,22432
49
49
  arelle/ModelValue.py,sha256=t0mVl3-EcE4MaXdRL9F94XaBwBfu1xG2DmFuHOczrEk,39447
50
50
  arelle/ModelVersObject.py,sha256=cPD1IzhkCfuV1eMgVFWes88DH_6WkUj5kj7sgGF2M0I,26062
51
51
  arelle/ModelVersReport.py,sha256=bXEA9K3qkH57aABn5l-m3CTY0FAcF1yX6O4fo-URjl8,73326
@@ -65,7 +65,7 @@ arelle/UITkTable.py,sha256=N83cXi5c0lLZLsDbwSKcPrlYoUoGsNavGN5YRx6d9XY,39810
65
65
  arelle/UiUtil.py,sha256=3G0xPclZI8xW_XQDbiFrmylB7Nd5muqi5n2x2oMkMZU,34218
66
66
  arelle/Updater.py,sha256=IZ8cq44Rq88WbQcB1VOpMA6bxdfZxfYQ8rgu9Ehpbes,7448
67
67
  arelle/UrlUtil.py,sha256=HrxZSG59EUMGMMGmWPuZkPi5-0BGqY3jAMkp7V4IdZo,32400
68
- arelle/Validate.py,sha256=XBrKQHsSC7Qz5Fp-M3gODfxwW8a-PWyBzZkCekYrMZM,56920
68
+ arelle/Validate.py,sha256=SxdFqjqNy3Dp2dFZV2YXn61uygZsf2UtSE5gmdqiZY8,58024
69
69
  arelle/ValidateDuplicateFacts.py,sha256=L556J1Dhz4ZmsMlRNoDCMpFgDQYiryd9vuBYDvE0Aq8,21769
70
70
  arelle/ValidateFilingText.py,sha256=xnXc0xgdNiHQk0eyP7VSSpvw7qr-pRFRwqqoUb569is,54051
71
71
  arelle/ValidateInfoset.py,sha256=Rz_XBi5Ha43KpxXYhjLolURcWVx5qmqyjLxw48Yt9Dg,20396
@@ -113,7 +113,7 @@ arelle/ViewWinTupleGrid.py,sha256=Li21jmMSZP3xIkpg8eY8Sq7KTIuAgM57wHu7i7Nu3P0,89
113
113
  arelle/ViewWinVersReport.py,sha256=aYfsOgynVZpMzl6f2EzQCBLzdihYGycwb5SiTghkgMQ,9344
114
114
  arelle/ViewWinXml.py,sha256=4ZGKtjaoCwU9etKYm9ZAS7jSmUxba1rqNEdv0OIyjTY,1250
115
115
  arelle/WatchRss.py,sha256=5Ih4igH2MM4hpOuAXy9eO0QAyZ7jZR3S5bPzo2sdFpw,14097
116
- arelle/WebCache.py,sha256=B62IxIHLX4hcDr_0MJGfmzUXau2ONqiMk6vLVLxAIhA,45057
116
+ arelle/WebCache.py,sha256=HlF4vfjxO0bSFHqMPfjnmkrzc7RK9XT714a7g3XFTDY,45192
117
117
  arelle/XbrlConst.py,sha256=gKYJECjuOEn0z0RRAaHpVCqh2NnBMfPLGxoLohYGGH4,57657
118
118
  arelle/XbrlUtil.py,sha256=s2Vmrh-sZI5TeuqsziKignOc3ao-uUgnCNoelP4dDj0,9212
119
119
  arelle/XhtmlValidate.py,sha256=0gtm7N-kXK0RB5o3c1AQXjfFuRp1w2fKZZAeyruNANw,5727
@@ -123,7 +123,7 @@ arelle/XmlValidateConst.py,sha256=U_wN0Q-nWKwf6dKJtcu_83FXPn9c6P8JjzGA5b0w7P0,33
123
123
  arelle/XmlValidateParticles.py,sha256=Mn6vhFl0ZKC_vag1mBwn1rH_x2jmlusJYqOOuxFPO2k,9231
124
124
  arelle/XmlValidateSchema.py,sha256=6frtZOc1Yrx_5yYF6V6oHbScnglWrVbWr6xW4EHtLQI,7428
125
125
  arelle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
- arelle/_version.py,sha256=uDlB7loGxG6RLMKayI5k_fSkcDz14q8EmlS0IYg5Wns,515
126
+ arelle/_version.py,sha256=qYQGLyu2LukjrzdlSMsUW-PBHLxq_IztqFR9C27E7NQ,515
127
127
  arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
128
128
  arelle/api/Session.py,sha256=5KPjCIPiNuanKrz1MdFdKIx8Bg40Pk9sf2cL9OU4x-E,7770
129
129
  arelle/archive/CustomLogger.py,sha256=v_JXOCQLDZcfaFWzxC9FRcEf9tQi4rCI4Sx7jCuAVQI,1231
@@ -392,6 +392,13 @@ arelle/plugin/validate/DBA/rules/tm.py,sha256=ui9oKBqlAForwkQ9kk9KBiUogTJE5pv1Rb
392
392
  arelle/plugin/validate/DBA/rules/tr.py,sha256=zdi3kQ82whmweVWRLbMvcNpM8sqtUliPsGfd81rgZws,14671
393
393
  arelle/plugin/validate/EBA/__init__.py,sha256=1kW-04W32sStSAL8wvW1ZpXnjlFv6KLbfE4aifYUB2A,46000
394
394
  arelle/plugin/validate/EBA/config.xml,sha256=37wMVUAObK-XEqakqD8zPNog20emYt4a_yfL1AKubF8,2022
395
+ arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
396
+ arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=P_cEzW23rPxivWMN2qGatMPRdw3yy3gybit2pcYmong,2393
397
+ arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=HIGOpBOyuVs5SEh573M3IzdouRdEuNIBkdumieZi8r0,959
398
+ arelle/plugin/validate/EDINET/__init__.py,sha256=1kJUaV2AbNZdakKSa_v3opdyCRKO3gva62RpHVOrpIE,4398
399
+ arelle/plugin/validate/EDINET/resources/config.xml,sha256=7uxn_HZT3USgbs2GQkew-dCUzlEgUGs62PiqEfljPgk,514
400
+ arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
401
+ arelle/plugin/validate/EDINET/rules/upload.py,sha256=KtPt2B04-9Fr8oOHneFpaLgkrntsQgVdVdWYWyL5fMI,5671
395
402
  arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
396
403
  arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
397
404
  arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlxoG21jE,7950
@@ -419,7 +426,7 @@ arelle/plugin/validate/NL/rules/br_kvk.py,sha256=0SwKieWzTDm3YMsXPS6zTdgbk7_Z9Cz
419
426
  arelle/plugin/validate/NL/rules/fg_nl.py,sha256=4Puq5wAjtK_iNd4wisH_R0Z_EKJ7MT2OCai5g4t1MPE,10714
420
427
  arelle/plugin/validate/NL/rules/fr_kvk.py,sha256=kYqXt45S6eM32Yg9ii7pUhOMfJaHurgYqQ73FyQALs8,8171
421
428
  arelle/plugin/validate/NL/rules/fr_nl.py,sha256=-M1WtXp06khhtkfOVPCa-b8UbC281gk4YfDhvtAVlnI,31424
422
- arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=D98uSeScccRRGK0F064yKxOgLJHTkSOSxYUa9k1rJkc,86120
429
+ arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=mMPMeGhhlYEhC9LMHVaFfHzIpqJObl9ukU8cuuitaRU,88446
423
430
  arelle/plugin/validate/ROS/DisclosureSystems.py,sha256=rJ81mwQDYTi6JecFZ_zhqjjz3VNQRgjHNSh0wcQWAQE,18
424
431
  arelle/plugin/validate/ROS/PluginValidationDataExtension.py,sha256=IV7ILhNvgKwQXqbpSA6HRNt9kEnejCyMADI3wyyIgk0,4036
425
432
  arelle/plugin/validate/ROS/ValidationPluginExtension.py,sha256=FBhEp8t396vGdvCbMEimfcxmGiGnhXMen-yVLWnkFaI,758
@@ -729,7 +736,7 @@ arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl,sha256=JrSZRngZFHtw8Svp
729
736
  arelle/scripts-macOS/startWebServer.command,sha256=KXLSwAwchDZBlL-k9PYXdf39RNBtte4vV076_kIz2Ow,91
730
737
  arelle/scripts-unix/startWebServer.sh,sha256=_0puRzaGkdMZoFn3R7hDti9a3ryN6kTZAXwLweeZU1s,42
731
738
  arelle/scripts-windows/startWebServer.bat,sha256=qmnF1yrjNo__bi4QodONWlN0qHShVLTKptJQYyZtgcY,122
732
- arelle/utils/EntryPointDetection.py,sha256=S85pXfCdrxLiX_L5rYVmlGwTNhwqlIE0L7c2g7UUeDc,4369
739
+ arelle/utils/EntryPointDetection.py,sha256=4RzercL0xE4PJrwoeUYq3S-E7PMSD-IspyS9bwK2RYM,4722
733
740
  arelle/utils/PluginData.py,sha256=GUnuZaApm1J4Xm9ZA1U2M1aask-AaNGviLtc0fgXbFg,265
734
741
  arelle/utils/PluginHooks.py,sha256=CeVxti23VjERQl4xWFucDVTW63TCG2PUdnxpjd3x_Ms,31170
735
742
  arelle/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -742,7 +749,7 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
742
749
  arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
743
750
  arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
744
751
  arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
745
- arelle_release-2.37.28.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
752
+ arelle_release-2.37.29.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
746
753
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
747
754
  tests/integration_tests/download_cache.py,sha256=jVMIVICsZjcVc9DCPPu3fCjF9_cWSS3tqSynhFs3oAM,4097
748
755
  tests/integration_tests/integration_test_util.py,sha256=H7mncbv0T9ZeVyrtk9Hohe3k6jgcYykHkt-LGE-Q9aQ,10270
@@ -771,7 +778,7 @@ tests/integration_tests/ui_tests/resources/workiva.zip,sha256=QtZzi1VcKkHhVa8J-I
771
778
  tests/integration_tests/validation/README.md,sha256=O6WYcMEk0x7ee7A9JnESHb6-UYceg_vrL4BhDIEDMI0,3008
772
779
  tests/integration_tests/validation/assets.py,sha256=Ag9qPYrodcC-Ly6aygqapV0vG2Cbn_Tigg4v4F9xX4U,8295
773
780
  tests/integration_tests/validation/conformance_suite_config.py,sha256=LgPO_8H_esM9kQS2o4jKd8CTNi0hiHugZ1hZn7whshI,10383
774
- tests/integration_tests/validation/conformance_suite_configs.py,sha256=vdKMEKQ0bgh1fhajS4B8Fgu59pgDWbJZ7fuaVfnbsLs,7500
781
+ tests/integration_tests/validation/conformance_suite_configs.py,sha256=jM-EqvLDLxq1xIv3UxQonXsSXbBR-AGVd0yAW_XeJUI,7616
775
782
  tests/integration_tests/validation/conftest.py,sha256=rVfmNX9y0JZ1VfoEepeYyIz-ZxzEZ1IJlmbcQSuxgUo,816
776
783
  tests/integration_tests/validation/discover_tests.py,sha256=dSzciVoGJNjw1NkPnAylncDy4_T-dBoZKR5YCmaZTgA,4653
777
784
  tests/integration_tests/validation/download_assets.py,sha256=muHklbrvYEbxqqAM8mU-8FpeemP0BLTWxD11xTYiCMc,7850
@@ -781,6 +788,7 @@ tests/integration_tests/validation/validation_util.py,sha256=_f0gd5BTts44Z9aEKi9
781
788
  tests/integration_tests/validation/conformance_suite_configurations/cipc_current.py,sha256=oLXe3xIsEZLz3cv1cDdMQIuS_NgyI9Uimc9hy0NMWqg,642
782
789
  tests/integration_tests/validation/conformance_suite_configurations/dba_current.py,sha256=j-7jCpzbGXbOzG8HGEyS0ciCYSPZzZLV44VQGhP3Hmc,875
783
790
  tests/integration_tests/validation/conformance_suite_configurations/dba_multi_current.py,sha256=ICkP18Wu7aTDfszfYlrfVnBj9oe7ppXR-8wxQqCPqW0,837
791
+ tests/integration_tests/validation/conformance_suite_configurations/edinet.py,sha256=-oS74t6-MLy5KVKmKOcZTFSRzF5iCJDry2h14jhiY7k,2198
784
792
  tests/integration_tests/validation/conformance_suite_configurations/efm_current.py,sha256=zbZ9c-LoZJDRp0Lobl_oH3xRw4g-2u6oQqU0-oo5NOE,1322
785
793
  tests/integration_tests/validation/conformance_suite_configurations/efm_reg_dqc.py,sha256=HiT8OcRAOVKLsl95Y91L66FeOsIMMMAQCs-DLMG-Lb0,739
786
794
  tests/integration_tests/validation/conformance_suite_configurations/efm_reg_pragmatic.py,sha256=U6dew0sIibjZe4r6na912qyIVAjxljh2HDix-8AwvhM,727
@@ -797,7 +805,7 @@ tests/integration_tests/validation/conformance_suite_configurations/kvk_nt16.py,
797
805
  tests/integration_tests/validation/conformance_suite_configurations/kvk_nt17.py,sha256=lmEZonthFm0YKFmp1dwXtdJ2T7txUeSpL4mbAo8fl4Y,1292
798
806
  tests/integration_tests/validation/conformance_suite_configurations/kvk_nt18.py,sha256=EG2RQVkvFENhzUF3fl3QvDnH7ZPYS1n1Fo8bhfmSczM,1205
799
807
  tests/integration_tests/validation/conformance_suite_configurations/kvk_nt19.py,sha256=FAzf9RhRmn_8yowpplJho2zEspX9FxJiVq8SjZT3Dsc,1199
800
- tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py,sha256=oFDnhrLXsRRGJjpc0wGZMewMwVYo_udKYcLs8vlN-nA,9350
808
+ tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py,sha256=0z-dl7rVT4juYDMYvLyYV5idPxzpakDBECZa3ly6z9E,9487
801
809
  tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024_gaap_other.py,sha256=vtzYSd0-vF9g6eHfrIUpMBz7D0HdR_gi8O0429lOaww,31667
802
810
  tests/integration_tests/validation/conformance_suite_configurations/nl_nt16.py,sha256=O_LFVBZPkjxmbrU7_C7VTLtrdoCUx2bYXOXw6_MlRtQ,846
803
811
  tests/integration_tests/validation/conformance_suite_configurations/nl_nt17.py,sha256=aTN3Ez6lPsZsuypHZP84DneOtYxUZSjUiGypHy6ofHQ,846
@@ -1142,6 +1150,16 @@ tests/resources/conformance_suites/dba_multi/tr/tr17-invalid.xhtml,sha256=Kp3MYJ
1142
1150
  tests/resources/conformance_suites/dba_multi/tr/tr17-testcase.xml,sha256=zzu0az0IfE8O21OMxDpGHzRbPbRyt5e7m8XTr4GdPgs,894
1143
1151
  tests/resources/conformance_suites/dba_multi/tr/valid-ixbrl-001.xhtml,sha256=weldGT9zOEsSYhbVmpz-MR66Bd4jMMqsKoWTM6GLXag,1652016
1144
1152
  tests/resources/conformance_suites/dba_multi/tr/valid-testcase.xml,sha256=KmH_iJFEFdCATYn9QWevbgCOTaGDR9r80NhdsYdGKsA,895
1153
+ tests/resources/conformance_suites/edinet/README.md,sha256=uO7RiidAUp8xEkP7obmggpxhfgdsnACoKplgYqqPON0,333
1154
+ tests/resources/conformance_suites/edinet/index.xml,sha256=_BE23o3QkqQ5AtkwdKMzZS5axiTCn7dmYNQHUOZFey0,240
1155
+ tests/resources/conformance_suites/edinet/EC0121E/index.xml,sha256=PYxVpU9Q_vDBCkeUkGxPfsfaMevnpVLD14iCwCLdnuk,980
1156
+ tests/resources/conformance_suites/edinet/EC0121E/invalid01.zip,sha256=XvIBDtvvNWFEAdI9N7G6xeH23t4m7_lCW3ViOBFv0o4,443326
1157
+ tests/resources/conformance_suites/edinet/EC0124E/index.xml,sha256=QpDcbJCZmroWiIoeyd1PpTZkIOTCJ1ryKvDbg2BDbg0,814
1158
+ tests/resources/conformance_suites/edinet/EC0124E/invalid01.zip,sha256=mD2DuFFAAHfbLiS76BsR-xLJsJP5ffFmkvFoHDa-J9o,459293
1159
+ tests/resources/conformance_suites/edinet/EC0132E/index.xml,sha256=Ym1yllYc0h1NzL1sy67qLYTh5E99F6kjYLBln3VcvQ8,873
1160
+ tests/resources/conformance_suites/edinet/EC0132E/invalid01.zip,sha256=UgteWlkzeTZm0VnDeE8c0bH4k8qB_AIoy2-9O8fICsA,457579
1161
+ tests/resources/conformance_suites/edinet/valid/index.xml,sha256=VFzHe8fWPOnZy2V85N9w_SlwBqMBQEpM68zUHdMP_k4,813
1162
+ tests/resources/conformance_suites/edinet/valid/valid01.zip,sha256=XvIBDtvvNWFEAdI9N7G6xeH23t4m7_lCW3ViOBFv0o4,443326
1145
1163
  tests/resources/conformance_suites/nl_nt16/index.xml,sha256=FFSSMokLcdhMroNeSSbm28pi-RKRURdVcKhqHdj44f0,2010
1146
1164
  tests/resources/conformance_suites/nl_nt16/mock-taxonomy.xsd,sha256=1uRNZClgrtNvL1Gx27MEAntSzeszICUhVXO01jqoavQ,1377
1147
1165
  tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-invalid-period.xbrl,sha256=WeUb_M6vNrLG9jjbNTDv7qiPnAYyfYXlZvDbVlHh11g,4127
@@ -1596,8 +1614,8 @@ tests/unit_tests/arelle/oim/test_load.py,sha256=NxiUauQwJVfWAHbbpsMHGSU2d3Br8Pki
1596
1614
  tests/unit_tests/arelle/plugin/test_plugin_imports.py,sha256=bdhIs9frAnFsdGU113yBk09_jis-z43dwUItMFYuSYM,1064
1597
1615
  tests/unit_tests/arelle/plugin/validate/ESEF/ESEF_Current/test_validate_css_url.py,sha256=H0ndmQ0sFO5WVMzAxPCH1WciRhCg_HgKUtQCg0xlmtg,1238
1598
1616
  tests/unit_tests/arelle/utils/validate/test_decorator.py,sha256=ZS8FqIY1g-2FCbjF4UYm609dwViax6qBMRJSi0vfuhY,2482
1599
- arelle_release-2.37.28.dist-info/METADATA,sha256=o_8uoE9BcBj-NHm4HoyFGxWuzjOaVWKFPJWYvtBtUDo,9134
1600
- arelle_release-2.37.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1601
- arelle_release-2.37.28.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
1602
- arelle_release-2.37.28.dist-info/top_level.txt,sha256=ZYmYGmhW5Jvo3vJ4iXBZPUI29LvYhntom04w90esJvU,13
1603
- arelle_release-2.37.28.dist-info/RECORD,,
1617
+ arelle_release-2.37.29.dist-info/METADATA,sha256=QyeOsfUCuvJazWgFYNmOci7pK1EkNxh61foj7xkHQdY,9189
1618
+ arelle_release-2.37.29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1619
+ arelle_release-2.37.29.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
1620
+ arelle_release-2.37.29.dist-info/top_level.txt,sha256=ZYmYGmhW5Jvo3vJ4iXBZPUI29LvYhntom04w90esJvU,13
1621
+ arelle_release-2.37.29.dist-info/RECORD,,
@@ -4,6 +4,7 @@ from tests.integration_tests.validation.conformance_suite_config import Conforma
4
4
  from tests.integration_tests.validation.conformance_suite_configurations.cipc_current import config as cipc_current
5
5
  from tests.integration_tests.validation.conformance_suite_configurations.dba_current import config as dba_current
6
6
  from tests.integration_tests.validation.conformance_suite_configurations.dba_multi_current import config as dba_multi_current
7
+ from tests.integration_tests.validation.conformance_suite_configurations.edinet import config as edinet
7
8
  from tests.integration_tests.validation.conformance_suite_configurations.efm_current import config as efm_current
8
9
  from tests.integration_tests.validation.conformance_suite_configurations.efm_reg_dqc import config as efm_reg_dqc
9
10
  from tests.integration_tests.validation.conformance_suite_configurations.efm_reg_pragmatic import config as efm_reg_pragmatic
@@ -54,6 +55,7 @@ ALL_CONFORMANCE_SUITE_CONFIGS: tuple[ConformanceSuiteConfig, ...] = (
54
55
  cipc_current,
55
56
  dba_current,
56
57
  dba_multi_current,
58
+ edinet,
57
59
  efm_current,
58
60
  efm_reg_dqc,
59
61
  efm_reg_pragmatic,
@@ -0,0 +1,52 @@
1
+ from pathlib import PurePath, Path
2
+
3
+ from tests.integration_tests.validation.conformance_suite_config import ConformanceSuiteConfig, ConformanceSuiteAssetConfig
4
+
5
+ config = ConformanceSuiteConfig(
6
+ args=[
7
+ '--disclosureSystem', 'EDINET',
8
+ ],
9
+ assets=[
10
+ ConformanceSuiteAssetConfig.local_conformance_suite(
11
+ Path('edinet'),
12
+ entry_point=Path('index.xml'),
13
+ ),
14
+ ],
15
+ cache_version_id='MkGD3D8lKJN_y0a0fH75EeZHKAO7V.iJ',
16
+ # Duplicate errors: Running EDINET validations in a testcase context
17
+ # prevents us from detecting when two models are being validated
18
+ # from the same variation, so `shouldValidateUpload` always returns `True`.
19
+ # This leads to any rule that validates at the package level (rather than the
20
+ # instance level) firing once for each instance. Normal validation runs
21
+ # do not have this issue.
22
+ # TODO: Prevent duplicate runs in testcase context.
23
+ # EC0121E: 31-character limit is violated by every example we've seen. Likely
24
+ # misunderstanding of the rule or the example filings we're working with. Expect
25
+ # to be resolved at some point.
26
+ expected_additional_testcase_errors={f"*/{s}": val for s, val in {
27
+ 'valid/index.xml:valid01': {
28
+ # See "Duplicate errors", "EC0121E" notes above.
29
+ 'EDINET.EC0121E': 114,
30
+ },
31
+ 'EC0121E/index.xml:invalid01': {
32
+ # See "Duplicate errors", "EC0121E" notes above.
33
+ # 38 expected, 2 sets of duplicates
34
+ 'EDINET.EC0121E': 76,
35
+ },
36
+ 'EC0124E/index.xml:invalid01': {
37
+ # See "Duplicate errors", "EC0121E" notes above.
38
+ 'EDINET.EC0121E': 114,
39
+ 'EDINET.EC0124E': 2,
40
+ },
41
+ 'EC0132E/index.xml:invalid01': {
42
+ # See "EC0121E" note above (single instance, not duplicated)
43
+ 'EDINET.EC0121E': 38,
44
+ },
45
+ }.items()},
46
+ expected_failure_ids=frozenset([]),
47
+ info_url='https://disclosure2.edinet-fsa.go.jp/weee0020.aspx',
48
+ name=PurePath(__file__).stem,
49
+ network_or_cache_required=False,
50
+ plugins=frozenset({'validate/EDINET', 'inlineXbrlDocumentSet'}),
51
+ test_case_result_options='match-all',
52
+ )
@@ -30,6 +30,9 @@ config = ConformanceSuiteConfig(
30
30
  # This is the expected error, but we return two of them, slightly different.
31
31
  'imageFormatNotSupported': 1,
32
32
  },
33
+ 'G3-5-2_3/index.xml:TC2_invalid': {
34
+ 'missingLabelForRoleInReportLanguage': 1,
35
+ },
33
36
  'G3-5-3_1/index.xml:TC2_invalid': {
34
37
  'arelle:ixdsTargetNotDefined': 1,
35
38
  'extensionTaxonomyWrongFilesStructure': 2,
@@ -46,6 +49,9 @@ config = ConformanceSuiteConfig(
46
49
  'message:valueKvKIdentifier': 13,
47
50
  'nonIdenticalIdentifier': 1,
48
51
  },
52
+ 'G4-1-1_1/index.xml:TC3_invalid': {
53
+ 'extensionConceptNoLabel': 1,
54
+ },
49
55
  'G4-1-1_1/index.xml:TC4_invalid': {
50
56
  'extensionTaxonomyWrongFilesStructure': 1,
51
57
  },
@@ -70,8 +76,12 @@ config = ConformanceSuiteConfig(
70
76
  'UsableConceptsNotAppliedByTaggedFacts': 1, # Also fails 4.4.6.1
71
77
  'extensionTaxonomyLineItemNotLinkedToAnyHypercube': 10,
72
78
  },
79
+ 'G4-2-0_1/index.xml:TC2_invalid': {
80
+ 'extensionConceptNoLabel': 1,
81
+ },
73
82
  'G4-2-3_1/index.xml:TC2_invalid': {
74
83
  'extensionTaxonomyLineItemNotLinkedToAnyHypercube': 1,
84
+ 'extensionConceptNoLabel': 1,
75
85
  },
76
86
  'G4-4-2_1/index.xml:TC2_invalid': {
77
87
  'closedNegativeHypercubeInDefinitionLinkbase': 1, # Also fails 4.4.2.3
@@ -94,6 +104,9 @@ config = ConformanceSuiteConfig(
94
104
  'message:lei-identifier-format': 105,
95
105
  'message:valueKvKIdentifierScheme': 105,
96
106
  },
107
+ 'RTS_Annex_IV_Par_4_3/index.xml:TC4_invalid': {
108
+ 'extensionTaxonomyWrongFilesStructure': 1,
109
+ },
97
110
  'RTS_Annex_IV_Par_6/index.xml:TC2_valid': {
98
111
  'undefinedLanguageForTextFact': 1,
99
112
  'taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport': 5,
@@ -142,9 +155,6 @@ config = ConformanceSuiteConfig(
142
155
  'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_III_Par_1/index.xml:TC3_invalid',
143
156
  'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_IV_Par_12_G3-2-4_1/index.xml:TC4_invalid',
144
157
  'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_IV_Par_14_G3-5-1_1/index.xml:TC2_invalid',
145
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_IV_Par_4_3/index.xml:TC3_invalid',
146
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_IV_Par_4_3/index.xml:TC4_invalid',
147
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_IV_Par_4_3/index.xml:TC5_invalid',
148
158
  ]),
149
159
  info_url='https://www.sbr-nl.nl/sbr-domeinen/handelsregister/uitbreiding-elektronische-deponering-handelsregister',
150
160
  name=PurePath(__file__).stem,
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <?xml-stylesheet type="text/xsl" href="../testcase.xsl"?>
3
+ <testcase
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xmlns="http://xbrl.org/2005/conformance"
6
+ name="EDINET.EC0121E"
7
+ description="EDINET.EC0121E: Directory and file names (excluding extensions) SHALL NOT be more than 31 characters or use any characters other than alphanumeric characters, '-' and '_'."
8
+ outpath=''
9
+ owner="support@arelle.org"
10
+ xsi:schemaLocation="http://xbrl.org/2005/conformance https://www.xbrl.org/2005/conformance.xsd">
11
+ <variation id="invalid01" name="invalid01">
12
+ <description>
13
+ Filenames exceed 31 characters or contain invalid characters.
14
+ </description>
15
+ <data>
16
+ <instance readMeFirst="true">invalid01.zip</instance>
17
+ </data>
18
+ <result>
19
+ <error num="38">EDINET.EC0121E</error>
20
+ </result>
21
+ </variation>
22
+ </testcase>
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <?xml-stylesheet type="text/xsl" href="../testcase.xsl"?>
3
+ <testcase
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xmlns="http://xbrl.org/2005/conformance"
6
+ name="EDINET.EC0124E"
7
+ description="EDINET.EC0124E: There are no empty directories."
8
+ outpath=''
9
+ owner="support@arelle.org"
10
+ xsi:schemaLocation="http://xbrl.org/2005/conformance https://www.xbrl.org/2005/conformance.xsd">
11
+ <variation id="invalid01" name="invalid01">
12
+ <description>
13
+ There are empty directories.
14
+ </description>
15
+ <data>
16
+ <instance readMeFirst="true">invalid01.zip</instance>
17
+ </data>
18
+ <result>
19
+ <error>EDINET.EC0124E</error>
20
+ </result>
21
+ </variation>
22
+ </testcase>
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <?xml-stylesheet type="text/xsl" href="../testcase.xsl"?>
3
+ <testcase
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xmlns="http://xbrl.org/2005/conformance"
6
+ name="EDINET.EC0132E"
7
+ description="EDINET.EC0132E: Store the manifest file directly under the relevant folder."
8
+ outpath=''
9
+ owner="support@arelle.org"
10
+ xsi:schemaLocation="http://xbrl.org/2005/conformance https://www.xbrl.org/2005/conformance.xsd">
11
+ <variation id="invalid01" name="invalid01">
12
+ <description>
13
+ Missing 'manifest_AuditDoc.xml' under 'AuditDoc' directory.
14
+ </description>
15
+ <data>
16
+ <instance readMeFirst="true">invalid01.zip</instance>
17
+ </data>
18
+ <result>
19
+ <error>EDINET.EC0132E</error>
20
+ </result>
21
+ </variation>
22
+ </testcase>
@@ -0,0 +1,4 @@
1
+ ### Disclaimer
2
+ Files in this conformance suite are provided for regression testing only.
3
+ Files may be copied from other sources (such as https://disclosure2.edinet-fsa.go.jp/week0020.aspx) with their comments included and may or may not be modified for testing purposes.
4
+ No rights or responsibilities conveyed, assumed, or provided.
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <testcases name="EDINET">
3
+ <testcase uri="EC0121E/index.xml" />
4
+ <testcase uri="EC0124E/index.xml" />
5
+ <testcase uri="EC0132E/index.xml" />
6
+ <testcase uri="valid/index.xml" />
7
+ </testcases>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <?xml-stylesheet type="text/xsl" href="../testcase.xsl"?>
3
+ <testcase
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xmlns="http://xbrl.org/2005/conformance"
6
+ name="EDINET.valid"
7
+ description="EDINET.valid: These variations are valid EDINET filings. They are not expected to produce any errors."
8
+ outpath=''
9
+ owner="support@arelle.org"
10
+ xsi:schemaLocation="http://xbrl.org/2005/conformance https://www.xbrl.org/2005/conformance.xsd">
11
+ <variation id="valid01" name="valid01">
12
+ <description>
13
+ A valid filing package.
14
+ </description>
15
+ <data>
16
+ <instance readMeFirst="true">valid01.zip</instance>
17
+ </data>
18
+ <result expected="valid"/>
19
+ </variation>
20
+ </testcase>