arelle-release 2.37.61__py3-none-any.whl → 2.37.63__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 (38) hide show
  1. arelle/DisclosureSystem.py +5 -0
  2. arelle/FileSource.py +4 -1
  3. arelle/HtmlUtil.py +5 -4
  4. arelle/ValidateDuplicateFacts.py +2 -0
  5. arelle/ValidateXbrl.py +3 -1
  6. arelle/ValidateXbrlDTS.py +1 -1
  7. arelle/XbrlConst.py +18 -0
  8. arelle/_version.py +2 -2
  9. arelle/api/Session.py +6 -0
  10. arelle/config/disclosuresystems.xsd +1 -0
  11. arelle/plugin/validate/EDINET/Constants.py +95 -0
  12. arelle/plugin/validate/EDINET/ControllerPluginData.py +14 -3
  13. arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
  14. arelle/plugin/validate/EDINET/{CoverPageRequirements.py → DeiRequirements.py} +24 -24
  15. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +209 -43
  16. arelle/plugin/validate/EDINET/ReportFolderType.py +61 -0
  17. arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +493 -0
  18. arelle/plugin/validate/EDINET/__init__.py +13 -2
  19. arelle/plugin/validate/EDINET/resources/config.xml +6 -0
  20. arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
  21. arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +2 -0
  22. arelle/plugin/validate/EDINET/rules/contexts.py +61 -1
  23. arelle/plugin/validate/EDINET/rules/edinet.py +278 -4
  24. arelle/plugin/validate/EDINET/rules/frta.py +122 -3
  25. arelle/plugin/validate/EDINET/rules/gfm.py +681 -5
  26. arelle/plugin/validate/EDINET/rules/upload.py +231 -192
  27. arelle/plugin/validate/NL/PluginValidationDataExtension.py +6 -8
  28. arelle/plugin/validate/NL/ValidationPluginExtension.py +0 -3
  29. arelle/plugin/validate/NL/rules/nl_kvk.py +1 -2
  30. arelle/utils/validate/ValidationPlugin.py +1 -1
  31. arelle/utils/validate/ValidationUtil.py +1 -2
  32. {arelle_release-2.37.61.dist-info → arelle_release-2.37.63.dist-info}/METADATA +2 -1
  33. {arelle_release-2.37.61.dist-info → arelle_release-2.37.63.dist-info}/RECORD +38 -35
  34. /arelle/plugin/validate/EDINET/resources/{cover-page-requirements.csv → dei-requirements.csv} +0 -0
  35. {arelle_release-2.37.61.dist-info → arelle_release-2.37.63.dist-info}/WHEEL +0 -0
  36. {arelle_release-2.37.61.dist-info → arelle_release-2.37.63.dist-info}/entry_points.txt +0 -0
  37. {arelle_release-2.37.61.dist-info → arelle_release-2.37.63.dist-info}/licenses/LICENSE.md +0 -0
  38. {arelle_release-2.37.61.dist-info → arelle_release-2.37.63.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,8 @@ from typing import Any, cast, Iterable
9
9
 
10
10
  import regex
11
11
 
12
- from arelle import XbrlConst, XmlUtil
12
+ from arelle import ModelDocument, XbrlConst, XmlUtil
13
+ from arelle.HtmlUtil import attrValue
13
14
  from arelle.LinkbaseType import LinkbaseType
14
15
  from arelle.ModelDtsObject import ModelConcept
15
16
  from arelle.ModelInstanceObject import ModelFact, ModelInlineFootnote
@@ -27,8 +28,7 @@ from arelle.utils.PluginHooks import ValidationHook
27
28
  from arelle.utils.Units import getDuplicateUnitGroups
28
29
  from arelle.utils.validate.Decorator import validation
29
30
  from arelle.utils.validate.Validation import Validation
30
- from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
31
- from ..Constants import NUMERIC_LABEL_ROLES, domainItemTypeQname
31
+ from ..Constants import JAPAN_LANGUAGE_CODES, NUMERIC_LABEL_ROLES, domainItemTypeQname
32
32
  from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
33
33
  from ..PluginValidationDataExtension import PluginValidationDataExtension
34
34
 
@@ -36,6 +36,7 @@ from ..PluginValidationDataExtension import PluginValidationDataExtension
36
36
  _: TypeGetText
37
37
 
38
38
  DISALLOWED_LABEL_WHITE_SPACE_CHARACTERS = regex.compile(r'\s{2,}')
39
+ XBRLI_IDENTIFIER_PATTERN = regex.compile(r"^[A-Z]\d{5}-\d{3}$")
39
40
  GFM_CONTEXT_DATE_PATTERN = regex.compile(r"^[12][0-9]{3}-[01][0-9]-[0-3][0-9]$")
40
41
  GFM_RECOMMENDED_NAMESPACE_PREFIXES = {
41
42
  XbrlConst.xbrli: ("xbrli",),
@@ -85,9 +86,14 @@ def rule_gfm_1_1_3(
85
86
  for elt in rootElt.iterdescendants(XbrlConst.qnLinkLinkbase.clarkNotation):
86
87
  uri = elt.attrib.get(XbrlConst.qnXsiSchemaLocation.clarkNotation)
87
88
  values.append((modelDocument, elt, uri))
89
+ for elt in rootElt.iterdescendants(XbrlConst.qnLinkLinkbaseRef.clarkNotation):
90
+ uri = elt.attrib.get(XbrlConst.qnXlinkHref.clarkNotation)
91
+ values.append((modelDocument, elt, uri))
88
92
  for modelDocument, elt, uri in values:
89
93
  if uri is None:
90
94
  continue
95
+ if uri in val.modelXbrl.urlUnloadableDocs:
96
+ continue # Already blocked, error fired.
91
97
  if not isHttpUrl(uri):
92
98
  if '/' not in uri:
93
99
  continue # Valid relative path
@@ -111,6 +117,33 @@ def rule_gfm_1_1_3(
111
117
  )
112
118
 
113
119
 
120
+ @validation(
121
+ hook=ValidationHook.XBRL_FINALLY,
122
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
123
+ )
124
+ def rule_gfm_1_1_6(
125
+ pluginData: PluginValidationDataExtension,
126
+ val: ValidateXbrl,
127
+ *args: Any,
128
+ **kwargs: Any,
129
+ ) -> Iterable[Validation]:
130
+ """
131
+ EDINET.EC5700W: [GFM 1.1.6] Filing must have one or more submitter specific(extension) taxonomies
132
+ """
133
+ if not hasattr(val, 'hasExtensionSchema'):
134
+ val.hasExtensionSchema = False
135
+ for modelDocument in val.modelXbrl.urlDocs.values():
136
+ if pluginData.isExtensionUri(modelDocument.uri, val.modelXbrl) and modelDocument.type == ModelDocument.Type.SCHEMA:
137
+ val.hasExtensionSchema = True
138
+ break
139
+ if not val.hasExtensionSchema:
140
+ yield Validation.warning(
141
+ codes='EDINET.EC5700W.GFM.1.1.6',
142
+ msg=_("Filing is missing an extension taxonomy."),
143
+ modelObject=val.modelXbrl,
144
+ )
145
+
146
+
114
147
  @validation(
115
148
  hook=ValidationHook.XBRL_FINALLY,
116
149
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -129,7 +162,7 @@ def rule_gfm_1_1_7(
129
162
  """
130
163
  baseElements = []
131
164
  for rootElt in val.modelXbrl.ixdsHtmlElements:
132
- for uncast_elt, depth in etreeIterWithDepth(rootElt):
165
+ for uncast_elt in rootElt.iter():
133
166
  elt = cast(Any, uncast_elt)
134
167
  if elt.get(xmlBaseIdentifier) is not None:
135
168
  baseElements.append(elt)
@@ -143,6 +176,54 @@ def rule_gfm_1_1_7(
143
176
  )
144
177
 
145
178
 
179
+ @validation(
180
+ hook=ValidationHook.XBRL_FINALLY,
181
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
182
+ )
183
+ def rule_gfm_1_2_1(
184
+ pluginData: PluginValidationDataExtension,
185
+ val: ValidateXbrl,
186
+ *args: Any,
187
+ **kwargs: Any,
188
+ ) -> Iterable[Validation]:
189
+ """
190
+ EDINET.EC5700W: [GFM 1.2.1] The scheme of the entity identifier must be http://disclosure.edinet-fsa.go.jp
191
+ """
192
+ entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
193
+ for entityId in entityIdentifierValues:
194
+ if entityId[0] != 'http://disclosure.edinet-fsa.go.jp':
195
+ yield Validation.warning(
196
+ codes='EDINET.EC5700W.GFM.1.2.1',
197
+ msg=_("The scheme of the entity identifier is: '%(scheme)s' but it must be 'http://disclosure.edinet-fsa.go.jp'."),
198
+ scheme=entityId[0],
199
+ modelObject=entityId,
200
+ )
201
+
202
+
203
+ @validation(
204
+ hook=ValidationHook.XBRL_FINALLY,
205
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
206
+ )
207
+ def rule_gfm_1_2_2(
208
+ pluginData: PluginValidationDataExtension,
209
+ val: ValidateXbrl,
210
+ *args: Any,
211
+ **kwargs: Any,
212
+ ) -> Iterable[Validation]:
213
+ """
214
+ EDINET.EC5700W: [GFM 1.2.2] The entity identifier element must match the following: X00000-000
215
+ """
216
+ entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
217
+ for entityId in entityIdentifierValues:
218
+ if not XBRLI_IDENTIFIER_PATTERN.match(entityId[1]):
219
+ yield Validation.warning(
220
+ codes='EDINET.EC5700W.GFM.1.2.2',
221
+ msg=_("The entity identifier element: '%(element)s' is incorrect. It must take the form of 'X00000-000'."),
222
+ element=entityId[1],
223
+ modelObject=entityId,
224
+ )
225
+
226
+
146
227
  @validation(
147
228
  hook=ValidationHook.XBRL_FINALLY,
148
229
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -676,6 +757,167 @@ def rule_gfm_1_3_8(
676
757
  )
677
758
 
678
759
 
760
+ @validation(
761
+ hook=ValidationHook.XBRL_FINALLY,
762
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
763
+ )
764
+ def rule_gfm_1_3_10(
765
+ pluginData: PluginValidationDataExtension,
766
+ val: ValidateXbrl,
767
+ *args: Any,
768
+ **kwargs: Any,
769
+ ) -> Iterable[Validation]:
770
+ """
771
+ EDINET.EC5700W: [GFM 1.3.10] Remove the duplicate link:roleType element.
772
+ """
773
+ for modelRoleTypes in val.modelXbrl.roleTypes.values():
774
+ if modelRoleTypes and len(modelRoleTypes) > 1:
775
+ yield Validation.warning(
776
+ codes='EDINET.EC5700W.GFM.1.3.10',
777
+ msg=_("Remove the duplicate link:roleType element. Duplicate roleURI: %(roleURI)s"),
778
+ roleURI=modelRoleTypes[0].roleURI,
779
+ modelObject=modelRoleTypes
780
+ )
781
+
782
+
783
+ @validation(
784
+ hook=ValidationHook.XBRL_FINALLY,
785
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
786
+ )
787
+ def rule_gfm_1_3_11(
788
+ pluginData: PluginValidationDataExtension,
789
+ val: ValidateXbrl,
790
+ *args: Any,
791
+ **kwargs: Any,
792
+ ) -> Iterable[Validation]:
793
+ """
794
+ EDINET.EC5700W: [GFM 1.3.11] The usedOn attribute of the extended link role should be set to include all of link:presentationLink, link:calculationLink, and link:definitionLink.
795
+ """
796
+ requiredUsedOns = {XbrlConst.qnLinkPresentationLink,
797
+ XbrlConst.qnLinkCalculationLink,
798
+ XbrlConst.qnLinkDefinitionLink}
799
+ for modelRoleTypes in val.modelXbrl.roleTypes.values():
800
+ if len(modelRoleTypes) > 0:
801
+ modelRoleType = modelRoleTypes[0]
802
+ usedOns = modelRoleType.usedOns
803
+ if not usedOns.isdisjoint(requiredUsedOns) and len(requiredUsedOns - usedOns) > 0:
804
+ yield Validation.warning(
805
+ codes='EDINET.EC5700W.GFM.1.3.11',
806
+ msg=_("The usedOn attribute of the extended link role should be set to include all of link:presentationLink, link:calculationLink, and link:definitionLink. "
807
+ "Extended link role roleURI: %(roleURI)s is missing %(usedOn)s."),
808
+ roleURI=modelRoleType.roleURI,
809
+ modelObject=modelRoleType
810
+ )
811
+
812
+
813
+ @validation(
814
+ hook=ValidationHook.XBRL_FINALLY,
815
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
816
+ )
817
+ def rule_gfm_1_3_13(
818
+ pluginData: PluginValidationDataExtension,
819
+ val: ValidateXbrl,
820
+ *args: Any,
821
+ **kwargs: Any,
822
+ ) -> Iterable[Validation]:
823
+ """
824
+ EDINET.EC5700W: [GFM 1.3.13] Remove any leading or trailing XML whitespace and newline
825
+ characters from the "link:definition" of your extended link role.
826
+ """
827
+ for modelRoleTypes in val.modelXbrl.roleTypes.values():
828
+ if len(modelRoleTypes) > 0:
829
+ modelRoleType = modelRoleTypes[0]
830
+ if (
831
+ modelRoleType.definition and modelRoleType.definitionNotStripped
832
+ and modelRoleType.definition != modelRoleType.definitionNotStripped
833
+ ):
834
+ yield Validation.warning(
835
+ codes='EDINET.EC5700W.GFM.1.3.13',
836
+ msg=_("Remove any leading or trailing XML whitespace and newline characters from "
837
+ "the `link:definition` of your extended link role. Definition: %(definition)s"),
838
+ definition=modelRoleTypes[0].definitionNotStripped,
839
+ modelObject=modelRoleTypes[0]
840
+ )
841
+
842
+
843
+ @validation(
844
+ hook=ValidationHook.XBRL_FINALLY,
845
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
846
+ )
847
+ def rule_gfm_1_3_16(
848
+ pluginData: PluginValidationDataExtension,
849
+ val: ValidateXbrl,
850
+ *args: Any,
851
+ **kwargs: Any,
852
+ ) -> Iterable[Validation]:
853
+ """
854
+ EDINET.EC5700W: [GFM 1.3.16] Remove the duplicate link:arcroleType element.
855
+ """
856
+ for modelArcRoleTypes in val.modelXbrl.arcroleTypes.values():
857
+ if len(modelArcRoleTypes) > 1:
858
+ yield Validation.warning(
859
+ codes='EDINET.EC5700W.GFM.1.3.16',
860
+ msg=_("Remove the duplicate link:arcroleType element. Duplicate arcroleURI: %(arcroleURI)s"),
861
+ arcroleURI=modelArcRoleTypes[0].arcroleURI,
862
+ modelObject=modelArcRoleTypes
863
+ )
864
+
865
+
866
+ @validation(
867
+ hook=ValidationHook.XBRL_FINALLY,
868
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
869
+ )
870
+ def rule_gfm_1_3_17(
871
+ pluginData: PluginValidationDataExtension,
872
+ val: ValidateXbrl,
873
+ *args: Any,
874
+ **kwargs: Any,
875
+ ) -> Iterable[Validation]:
876
+ """
877
+ EDINET.EC5700W: [GFM 1.3.17] Add a link:definition to the link:arcroleType element.
878
+ """
879
+ for modelArcRoleTypes in val.modelXbrl.arcroleTypes.values():
880
+ modelArcRoleType = modelArcRoleTypes[0]
881
+ if not modelArcRoleType.definition:
882
+ yield Validation.warning(
883
+ codes='EDINET.EC5700W.GFM.1.3.17',
884
+ msg=_("Add a link:definition to the link:arcroleType element. ArcroleURI: %(arcroleURI)s"),
885
+ arcroleURI=modelArcRoleType.arcroleURI,
886
+ modelObject=modelArcRoleType
887
+ )
888
+
889
+
890
+ @validation(
891
+ hook=ValidationHook.XBRL_FINALLY,
892
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
893
+ )
894
+ def rule_gfm_1_3_18(
895
+ pluginData: PluginValidationDataExtension,
896
+ val: ValidateXbrl,
897
+ *args: Any,
898
+ **kwargs: Any,
899
+ ) -> Iterable[Validation]:
900
+ """
901
+ EDINET.EC5700W: [GFM 1.3.18] The submitter's taxonomy contains an element whose name matches an element in the EDINET taxonomy.
902
+ Modify the element name so that it does not match the EDINET taxonomy, or use the element in the EDINET taxonomy and delete the
903
+ element added in the submitter's taxonomy.
904
+ """
905
+ for extensionConcept in pluginData.getExtensionConcepts(val.modelXbrl):
906
+ name = extensionConcept.get("name")
907
+ if name is not None:
908
+ concepts = val.modelXbrl.nameConcepts.get(name, [])
909
+ for concept in concepts:
910
+ if not pluginData.isExtensionUri(concept.document.uri, val.modelXbrl):
911
+ yield Validation.warning(
912
+ codes='EDINET.EC5700W.GFM.1.3.18',
913
+ msg=_("Your extension taxonomy contains an element, %(concept)s, which has the same name as an element "
914
+ "in the base taxonomy, %(standardConcept)s. Please ensure that this extension is appropriate and "
915
+ "if so, please change the extension concept."),
916
+ concept=name,
917
+ standardConcept=concept
918
+ )
919
+
920
+
679
921
  @validation(
680
922
  hook=ValidationHook.XBRL_FINALLY,
681
923
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -976,6 +1218,160 @@ def rule_gfm_1_3_31(
976
1218
  )
977
1219
 
978
1220
 
1221
+ @validation(
1222
+ hook=ValidationHook.XBRL_FINALLY,
1223
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1224
+ )
1225
+ def rule_gfm_1_5_1(
1226
+ pluginData: PluginValidationDataExtension,
1227
+ val: ValidateXbrl,
1228
+ *args: Any,
1229
+ **kwargs: Any,
1230
+ ) -> Iterable[Validation]:
1231
+ """
1232
+ EDINET.EC5700W: [GFM 1.5.1] An element used in a fact or xbrldi:explicitMember in an instance must have a Japanese
1233
+ language standard label in the DTS of that instance.
1234
+ """
1235
+ usedConcepts = pluginData.getUsedConcepts(val.modelXbrl)
1236
+ labelRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
1237
+ if labelRelationshipSet is None:
1238
+ return
1239
+ for concept in usedConcepts:
1240
+ labelRels = labelRelationshipSet.fromModelObject(concept)
1241
+ labelExists = False
1242
+ for rel in labelRels:
1243
+ label = rel.toModelObject
1244
+ if (label is not None and
1245
+ label.role == XbrlConst.standardLabel and
1246
+ label.xmlLang in JAPAN_LANGUAGE_CODES):
1247
+ labelExists = True
1248
+ break
1249
+ if not labelExists:
1250
+ yield Validation.warning(
1251
+ codes='EDINET.EC5700W.GFM.1.5.1',
1252
+ msg=_("The used concept of '%(concept)s' is missing a standard label in Japanese"),
1253
+ concept=concept.qname.localName,
1254
+ modelObject=concept
1255
+ )
1256
+
1257
+
1258
+ @validation(
1259
+ hook=ValidationHook.XBRL_FINALLY,
1260
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1261
+ )
1262
+ def rule_gfm_1_5_2(
1263
+ pluginData: PluginValidationDataExtension,
1264
+ val: ValidateXbrl,
1265
+ *args: Any,
1266
+ **kwargs: Any,
1267
+ ) -> Iterable[Validation]:
1268
+ """
1269
+ EDINET.EC5700W: [GFM 1.5.2] An element used in a fact or xbrldi:explicitMember in an instance must have at most one
1270
+ label for any combination of the xlink:role attribute and the xml:lang attribute in the
1271
+ DTS of that instance.
1272
+ """
1273
+ usedConcepts = pluginData.getUsedConcepts(val.modelXbrl)
1274
+ labelRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
1275
+ if labelRelationshipSet is None:
1276
+ return
1277
+ for concept in usedConcepts:
1278
+ labelRels = labelRelationshipSet.fromModelObject(concept)
1279
+ labelsByRoleAndLang = defaultdict(list)
1280
+ for rel in labelRels:
1281
+ label = rel.toModelObject
1282
+ if label is None:
1283
+ continue
1284
+ labelsByRoleAndLang[(label.role, label.xmlLang)].append(label)
1285
+ warningLabels = []
1286
+ for key, labels in labelsByRoleAndLang.items():
1287
+ if len(labels) > 1:
1288
+ warningLabels.append(key)
1289
+ if len(warningLabels) > 0:
1290
+ yield Validation.warning(
1291
+ codes='EDINET.EC5700W.GFM.1.5.2',
1292
+ msg=_("The used concept of '%(concept)s' has more than one label for the given role/lang pairs: %(pairs)s."),
1293
+ concept=concept.qname.localName,
1294
+ pairs=warningLabels,
1295
+ modelObject=concept
1296
+ )
1297
+
1298
+
1299
+ @validation(
1300
+ hook=ValidationHook.XBRL_FINALLY,
1301
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1302
+ )
1303
+ def rule_gfm_1_5_3(
1304
+ pluginData: PluginValidationDataExtension,
1305
+ val: ValidateXbrl,
1306
+ *args: Any,
1307
+ **kwargs: Any,
1308
+ ) -> Iterable[Validation]:
1309
+ """
1310
+ EDINET.EC5700W: [GFM 1.5.3] If an element used in an instance is assigned a label in the DTS whose xml:lang
1311
+ attribute does not reflect the default language, then the DTS must also contain a
1312
+ link:label for the same element and all other attributes with an xml:lang attribute
1313
+ reflecting the default language.
1314
+ """
1315
+ usedConcepts = pluginData.getUsedConcepts(val.modelXbrl)
1316
+ labelRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
1317
+ if labelRelationshipSet is None:
1318
+ return
1319
+ for concept in usedConcepts:
1320
+ labelRels = labelRelationshipSet.fromModelObject(concept)
1321
+ labelsByRole = defaultdict(list)
1322
+ for rel in labelRels:
1323
+ label = rel.toModelObject
1324
+ if label is None:
1325
+ continue
1326
+ labelsByRole[label.role].append(label)
1327
+ warningRoles = []
1328
+ for role, labels in labelsByRole.items():
1329
+ if len([label for label in labels if label.xmlLang in JAPAN_LANGUAGE_CODES]) == 0:
1330
+ warningRoles.append(role)
1331
+ if len(warningRoles) > 0:
1332
+ yield Validation.warning(
1333
+ codes='EDINET.EC5700W.GFM.1.5.3',
1334
+ msg=_("The used concept of '%(concept)s' is missing a label in Japanese in the following roles: %(roles)s."),
1335
+ concept=concept.qname.localName,
1336
+ roles=warningRoles,
1337
+ modelObject=concept
1338
+ )
1339
+
1340
+
1341
+ @validation(
1342
+ hook=ValidationHook.XBRL_FINALLY,
1343
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1344
+ )
1345
+ def rule_gfm_1_5_5(
1346
+ pluginData: PluginValidationDataExtension,
1347
+ val: ValidateXbrl,
1348
+ *args: Any,
1349
+ **kwargs: Any,
1350
+ ) -> Iterable[Validation]:
1351
+ """
1352
+ EDINET.EC5700W: [GFM 1.5.5] A label linkbase must not have a documentation label for an element defined in a
1353
+ standard taxonomy.
1354
+ """
1355
+ labelRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
1356
+ if labelRelationshipSet is None:
1357
+ return
1358
+ for concept in val.modelXbrl.qnameConcepts.values():
1359
+ if concept.namespaceURI is not None and not pluginData.isStandardTaxonomyUrl(concept.namespaceURI, val.modelXbrl):
1360
+ continue
1361
+ labelRels = labelRelationshipSet.fromModelObject(concept)
1362
+ for rel in labelRels:
1363
+ label = rel.toModelObject
1364
+ if (label is not None and
1365
+ not pluginData.isStandardTaxonomyUrl(label.modelDocument.uri, val.modelXbrl) and
1366
+ label.role == XbrlConst.documentationLabel):
1367
+ yield Validation.warning(
1368
+ codes='EDINET.EC5700W.GFM.1.5.5',
1369
+ msg=_("The standard concept of '%(concept)s' must not have a documentation label defined."),
1370
+ concept=concept.qname.localName,
1371
+ modelObject=label
1372
+ )
1373
+
1374
+
979
1375
  @validation(
980
1376
  hook=ValidationHook.XBRL_FINALLY,
981
1377
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -1293,6 +1689,53 @@ def rule_gfm_1_7_3(
1293
1689
  )
1294
1690
 
1295
1691
 
1692
+ @validation(
1693
+ hook=ValidationHook.XBRL_FINALLY,
1694
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1695
+ )
1696
+ def rule_gfm_1_7_5(
1697
+ pluginData: PluginValidationDataExtension,
1698
+ val: ValidateXbrl,
1699
+ *args: Any,
1700
+ **kwargs: Any,
1701
+ ) -> Iterable[Validation]:
1702
+ """
1703
+ EDINET.EC5700W: [GFM 1.7.5] The source and target of a calculation relationship must appear in either:
1704
+ 1) a presentation relationship within each other
1705
+ 2) two presentation relationships with any other elements that also share the same ELR.
1706
+ """
1707
+ calculationRelationshipSet = val.modelXbrl.relationshipSet(tuple(LinkbaseType.CALCULATION.getArcroles()))
1708
+ if calculationRelationshipSet is None:
1709
+ return
1710
+ for rel in calculationRelationshipSet.modelRelationships:
1711
+ conceptsMissingRels = []
1712
+ concepts = []
1713
+ for concept in [rel.fromModelObject, rel.toModelObject]:
1714
+ if concept is not None:
1715
+ conceptFacts = val.modelXbrl.factsByQname.get(concept.qname, set())
1716
+ if len([fact for fact in conceptFacts if fact.xValid >= VALID and not fact.isNil]) > 0:
1717
+ concepts.append(concept)
1718
+ if len(concepts) > 0:
1719
+ presentationRelationshipSet = val.modelXbrl.relationshipSet(tuple(LinkbaseType.PRESENTATION.getArcroles()), rel.linkrole)
1720
+ if presentationRelationshipSet is None:
1721
+ conceptsMissingRels.extend(concepts)
1722
+ else:
1723
+ for concept in concepts:
1724
+ if (len(presentationRelationshipSet.fromModelObject(concept)) == 0 and
1725
+ len(presentationRelationshipSet.toModelObject(concept)) == 0):
1726
+ conceptsMissingRels.append(concept)
1727
+ if len(conceptsMissingRels) > 0:
1728
+ yield Validation.warning(
1729
+ codes='EDINET.EC5700W.GFM.1.7.5',
1730
+ msg=_("The concepts participating in a calculation relationship must also participate in a presentation "
1731
+ "relationship within the same extended link role. The concept(s) of '%(concepts)s' "
1732
+ "do not appear in a presentation relationship within the extended link role of '%(elr)s'."),
1733
+ concepts=' and '.join([concept.qname.localName for concept in conceptsMissingRels]),
1734
+ elr=rel.linkrole,
1735
+ modelObject=rel
1736
+ )
1737
+
1738
+
1296
1739
  @validation(
1297
1740
  hook=ValidationHook.XBRL_FINALLY,
1298
1741
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -1383,6 +1826,35 @@ def rule_gfm_1_8_3(
1383
1826
  )
1384
1827
 
1385
1828
 
1829
+ @validation(
1830
+ hook=ValidationHook.XBRL_FINALLY,
1831
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1832
+ )
1833
+ def rule_gfm_1_8_5(
1834
+ pluginData: PluginValidationDataExtension,
1835
+ val: ValidateXbrl,
1836
+ *args: Any,
1837
+ **kwargs: Any,
1838
+ ) -> Iterable[Validation]:
1839
+ """
1840
+ EDINET.EC5700W: [GFM 1.8.5] Each ELR can have at most one effective arc with the role of http://xbrl.org/int/dim/arcrole/all.
1841
+ """
1842
+ dimensionAllRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.all)
1843
+ if dimensionAllRelationshipSet is None:
1844
+ return
1845
+ relsByLinkrole = defaultdict(list)
1846
+ for rel in dimensionAllRelationshipSet.modelRelationships:
1847
+ relsByLinkrole[rel.linkrole].append(rel)
1848
+ for linkrole, rels in relsByLinkrole.items():
1849
+ if len(rels) > 1:
1850
+ yield Validation.warning(
1851
+ codes='EDINET.EC5700W.GFM.1.8.5',
1852
+ msg=_("The extended link role of '%(elr)s' has more than one effective arc with the role of 'http://xbrl.org/int/dim/arcrole/all'"),
1853
+ elr=linkrole,
1854
+ modelObject=rels
1855
+ )
1856
+
1857
+
1386
1858
  @validation(
1387
1859
  hook=ValidationHook.XBRL_FINALLY,
1388
1860
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -1463,7 +1935,7 @@ def rule_gfm_1_9_1(
1463
1935
  continue
1464
1936
  if modelConcept.qname is None or modelConcept.qname.namespaceURI is None:
1465
1937
  continue
1466
- if pluginData.isExtensionUri(modelConcept.qname.namespaceURI, val.modelXbrl):
1938
+ if pluginData.isExtensionUri(modelConcept.document.uri, val.modelXbrl):
1467
1939
  yield Validation.warning(
1468
1940
  codes='EDINET.EC5700W.GFM.1.9.1',
1469
1941
  msg=_("References should not be defined for extension concepts: %(conceptName)s"),
@@ -1472,6 +1944,144 @@ def rule_gfm_1_9_1(
1472
1944
  )
1473
1945
 
1474
1946
 
1947
+ @validation(
1948
+ hook=ValidationHook.XBRL_FINALLY,
1949
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1950
+ )
1951
+ def rule_gfm_1_10_3(
1952
+ pluginData: PluginValidationDataExtension,
1953
+ val: ValidateXbrl,
1954
+ *args: Any,
1955
+ **kwargs: Any,
1956
+ ) -> Iterable[Validation]:
1957
+ """
1958
+ EDINET.EC5700W: [GFM 1.10.3] The Inline XBRL document must contain all necessary namespace declarations including
1959
+ those for QName values of attributes. These namespace declarations must be on the root html element.
1960
+ """
1961
+ for ixdsHtmlRootElt in val.modelXbrl.ixdsHtmlElements:
1962
+ for elt in ixdsHtmlRootElt.iterdescendants():
1963
+ if not isinstance(elt, ModelObject):
1964
+ continue
1965
+ parent = elt.getparent()
1966
+ if parent is None or elt.nsmap == parent.nsmap:
1967
+ continue
1968
+ yield Validation.warning(
1969
+ codes='EDINET.EC5700W.GFM.1.10.3',
1970
+ msg=_('The Inline XBRL document must contain all necessary namespace declarations on the root html '
1971
+ 'element. Found namespace declaration on descendant element %(elementName)s.'),
1972
+ elementName=elt.tag,
1973
+ modelObject=elt
1974
+ )
1975
+
1976
+
1977
+ @validation(
1978
+ hook=ValidationHook.XBRL_FINALLY,
1979
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1980
+ )
1981
+ def rule_charsets(
1982
+ pluginData: PluginValidationDataExtension,
1983
+ val: ValidateXbrl,
1984
+ *args: Any,
1985
+ **kwargs: Any,
1986
+ ) -> Iterable[Validation]:
1987
+ """
1988
+ EDINET.EC1010E: The charset specification in the content attribute of the HTML <meta> tag must be UTF-8.
1989
+ EDINET.EC5700W: [GFM 1.10.4] The document encoding must be set in both the XML document declaration and the HTML
1990
+ meta element for content type.
1991
+ """
1992
+ for modelDocument in val.modelXbrl.urlDocs.values():
1993
+ if modelDocument.type != ModelDocument.Type.INLINEXBRL:
1994
+ continue
1995
+
1996
+ if pluginData.isStandardTaxonomyUrl(modelDocument.uri, val.modelXbrl):
1997
+ continue
1998
+
1999
+ xmlDeclaredEncoding = None
2000
+ try:
2001
+ with val.modelXbrl.fileSource.file(modelDocument.filepath)[0] as f:
2002
+ fileContent = cast(str, f.read(512))
2003
+ match = XmlUtil.xmlEncodingPattern.match(fileContent)
2004
+ if match:
2005
+ xmlDeclaredEncoding = match.group(1)
2006
+ except Exception:
2007
+ pass
2008
+
2009
+ if xmlDeclaredEncoding is None:
2010
+ yield Validation.warning(
2011
+ codes='EDINET.EC5700W.GFM.1.10.4',
2012
+ msg=_("The document encoding must be declared in an XML document declaration"),
2013
+ modelObject=modelDocument
2014
+ )
2015
+
2016
+ metaCharsetDeclared = False
2017
+ for metaElt in modelDocument.xmlRootElement.iterdescendants(tag=XbrlConst.qnXhtmlMeta.clarkNotation):
2018
+ metaCharset = None
2019
+ httpEquiv = metaElt.get("http-equiv", "").lower()
2020
+ if httpEquiv == "content-type":
2021
+ content = metaElt.get("content")
2022
+ if content:
2023
+ metaCharset = attrValue(content)
2024
+ if metaCharset is not None:
2025
+ metaCharsetDeclared = True
2026
+ if xmlDeclaredEncoding is not None and metaCharset.lower() != xmlDeclaredEncoding.lower():
2027
+ yield Validation.warning(
2028
+ codes='EDINET.EC5700W.GFM.1.10.4',
2029
+ msg=_("The XML declaration encoding '%(xmlEncoding)s' does not match the HTML meta charset '%(metaCharset)s'"),
2030
+ xmlEncoding=xmlDeclaredEncoding,
2031
+ metaCharset=metaCharset,
2032
+ modelObject=metaElt
2033
+ )
2034
+ if metaCharset.lower() != 'utf-8':
2035
+ yield Validation.error(
2036
+ codes='EDINET.EC1010E',
2037
+ msg=_("The charset specification in the content attribute of the HTML <meta> tag is not UTF-8. "
2038
+ "File name: '%(path)s'. "
2039
+ "Please set the character code of the file to UTF-8."),
2040
+ path=modelDocument.uri,
2041
+ modelObject=metaElt,
2042
+ )
2043
+
2044
+ if not metaCharsetDeclared:
2045
+ yield Validation.warning(
2046
+ codes='EDINET.EC5700W.GFM.1.10.4',
2047
+ msg=_("The document encoding must be declared in an HTML meta element charset"),
2048
+ modelObject=modelDocument
2049
+ )
2050
+
2051
+
2052
+ @validation(
2053
+ hook=ValidationHook.XBRL_FINALLY,
2054
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
2055
+ )
2056
+ def rule_gfm_1_10_12(
2057
+ pluginData: PluginValidationDataExtension,
2058
+ val: ValidateXbrl,
2059
+ *args: Any,
2060
+ **kwargs: Any,
2061
+ ) -> Iterable[Validation]:
2062
+ """
2063
+ EDINET.EC5700W: [GFM 1.10.12] In all inline XBRL files, multiple target attribute values ​​are not allowed.
2064
+ Correct the target attribute value. (A warning will be issued if the target attribute is not specified and is
2065
+ specified at the same time.)
2066
+ """
2067
+ targets: set[str | None] = set()
2068
+ for ixdsHtmlRootElt in val.modelXbrl.ixdsHtmlElements:
2069
+ targetEltTags = [qname.clarkNotation for qname in XbrlConst.ixbrlAllTargetElements]
2070
+ for elt in ixdsHtmlRootElt.iter(targetEltTags):
2071
+ targets.add(elt.get("target"))
2072
+ if len(targets) > 1:
2073
+ if None in targets:
2074
+ msg = _("Inline document set may not use multiple target documents. Found targets: default, %(targets)s")
2075
+ else:
2076
+ msg = _("Inline document set may not use multiple target documents. Found targets: %(targets)s")
2077
+ yield Validation.warning(
2078
+ codes='EDINET.EC5700W.GFM.1.10.12',
2079
+ msg=msg,
2080
+ targets=",".join(target for target in targets if target is not None),
2081
+ modelObject=val.modelXbrl,
2082
+ )
2083
+
2084
+
1475
2085
  @validation(
1476
2086
  hook=ValidationHook.XBRL_FINALLY,
1477
2087
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -1501,3 +2111,69 @@ def rule_gfm_1_10_14(
1501
2111
  msg=_("A non-empty footnote is not referenced by an element"),
1502
2112
  modelObject=footnote
1503
2113
  )
2114
+
2115
+
2116
+ @validation(
2117
+ hook=ValidationHook.XBRL_FINALLY,
2118
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
2119
+ )
2120
+ def rule_gfm_2_5_1(
2121
+ pluginData: PluginValidationDataExtension,
2122
+ val: ValidateXbrl,
2123
+ *args: Any,
2124
+ **kwargs: Any,
2125
+ ) -> Iterable[Validation]:
2126
+ """
2127
+ EDINET.EC5700W: [GFM 2.5.1] A presentation linkbase of a standard taxonomy should not be included in the DTS of an instance.
2128
+ """
2129
+ for elt in pluginData.getStandardTaxonomyExtensionLinks(LinkbaseType.PRESENTATION, val.modelXbrl):
2130
+ yield Validation.warning(
2131
+ codes='EDINET.EC5700W.GFM.2.5.1',
2132
+ msg=_("A presentation linkbase from the standard taxonomy file of '%(uri)s' is not allowed."),
2133
+ uri=elt.attr(XbrlConst.qnXlinkHref.clarkNotation),
2134
+ modelObject=elt
2135
+ )
2136
+
2137
+
2138
+ @validation(
2139
+ hook=ValidationHook.XBRL_FINALLY,
2140
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
2141
+ )
2142
+ def rule_gfm_2_6_1(
2143
+ pluginData: PluginValidationDataExtension,
2144
+ val: ValidateXbrl,
2145
+ *args: Any,
2146
+ **kwargs: Any,
2147
+ ) -> Iterable[Validation]:
2148
+ """
2149
+ EDINET.EC5700W: [GFM 2.6.1] A calculation linkbase of a standard taxonomy should not be included in the DTS of an instance.
2150
+ """
2151
+ for elt in pluginData.getStandardTaxonomyExtensionLinks(LinkbaseType.CALCULATION, val.modelXbrl):
2152
+ yield Validation.warning(
2153
+ codes='EDINET.EC5700W.GFM.2.6.1',
2154
+ msg=_("A calculation linkbase from the standard taxonomy file of '%(uri)s' is not allowed."),
2155
+ uri=elt.attr(XbrlConst.qnXlinkHref.clarkNotation),
2156
+ modelObject=elt
2157
+ )
2158
+
2159
+
2160
+ @validation(
2161
+ hook=ValidationHook.XBRL_FINALLY,
2162
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
2163
+ )
2164
+ def rule_gfm_2_8_1(
2165
+ pluginData: PluginValidationDataExtension,
2166
+ val: ValidateXbrl,
2167
+ *args: Any,
2168
+ **kwargs: Any,
2169
+ ) -> Iterable[Validation]:
2170
+ """
2171
+ EDINET.EC5700W: [GFM 2.8.1] A reference linkbase of a standard taxonomy should not be included in the DTS of an instance.
2172
+ """
2173
+ for elt in pluginData.getStandardTaxonomyExtensionLinks(LinkbaseType.REFERENCE, val.modelXbrl):
2174
+ yield Validation.warning(
2175
+ codes='EDINET.EC5700W.GFM.2.8.1',
2176
+ msg=_("A reference linkbase from the standard taxonomy file of '%(uri)s' is not allowed."),
2177
+ uri=elt.attr(XbrlConst.qnXlinkHref.clarkNotation),
2178
+ modelObject=elt
2179
+ )