civics-cdf-validator 1.57.dev8__tar.gz → 1.57.dev9__tar.gz
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.
- {civics_cdf_validator-1.57.dev8/civics_cdf_validator.egg-info → civics_cdf_validator-1.57.dev9}/PKG-INFO +1 -1
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/base.py +16 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9/civics_cdf_validator.egg-info}/PKG-INFO +1 -1
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/rules.py +8 -53
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/version.py +1 -1
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/CONTRIBUTING.md +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/LICENSE-2.0.txt +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/MANIFEST.in +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/README.md +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/__init__.py +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/SOURCES.txt +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/dependency_links.txt +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/entry_points.txt +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/requires.txt +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/top_level.txt +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/gpunit_rules.py +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/loggers.py +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/office_utils.py +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/setup.cfg +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/setup.py +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/stats.py +0 -0
- {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/validator.py +0 -0
|
@@ -16,6 +16,7 @@ limitations under the License.
|
|
|
16
16
|
|
|
17
17
|
from __future__ import print_function
|
|
18
18
|
|
|
19
|
+
from collections.abc import Set
|
|
19
20
|
import datetime
|
|
20
21
|
import functools
|
|
21
22
|
import re
|
|
@@ -93,6 +94,21 @@ class BaseRule(SchemaHandler):
|
|
|
93
94
|
def setup(self):
|
|
94
95
|
"""Perform any rule specific setup before checking."""
|
|
95
96
|
|
|
97
|
+
def get_element_names_for_types(self, element_types: Set[str]) -> set[str]:
|
|
98
|
+
element_names = set()
|
|
99
|
+
for _, element in etree.iterwalk(self.schema_tree):
|
|
100
|
+
tag = self.strip_schema_ns(element)
|
|
101
|
+
if (
|
|
102
|
+
tag == "element"
|
|
103
|
+
and element.get("type") in element_types
|
|
104
|
+
and element.get("name") is not None
|
|
105
|
+
):
|
|
106
|
+
element_names.add(element.get("name"))
|
|
107
|
+
return element_names
|
|
108
|
+
|
|
109
|
+
def get_element_names_for_type(self, element_type: str) -> set[str]:
|
|
110
|
+
return self.get_element_names_for_types({element_type})
|
|
111
|
+
|
|
96
112
|
|
|
97
113
|
class TreeRule(BaseRule):
|
|
98
114
|
"""Rule that checks entire tree."""
|
|
@@ -34,6 +34,7 @@ from six.moves.urllib.parse import urlparse
|
|
|
34
34
|
|
|
35
35
|
_PARTY_LEADERSHIP_TYPES = ["party-leader-id", "party-chair-id"]
|
|
36
36
|
_INDEPENDENT_PARTY_NAMES = frozenset(["independent", "nonpartisan"])
|
|
37
|
+
_IDREF_TYPES = frozenset(["xs:IDREF", "xs:IDREFS"])
|
|
37
38
|
# The set of external identifiers that contain references to other entities.
|
|
38
39
|
_IDREF_EXTERNAL_IDENTIFIERS = frozenset(
|
|
39
40
|
["jurisdiction-id"] + _PARTY_LEADERSHIP_TYPES
|
|
@@ -49,7 +50,7 @@ _CONTEST_STAGE_TYPES = frozenset([
|
|
|
49
50
|
"official",
|
|
50
51
|
"unnamed",
|
|
51
52
|
])
|
|
52
|
-
|
|
53
|
+
_INTERNATIONALIZED_TEXT_ELEMENTS_WITH_ONLY_ONE_TEXT_PER_LANGUAGE = [
|
|
53
54
|
# go/keep-sorted start
|
|
54
55
|
"BallotName",
|
|
55
56
|
"BallotSubTitle",
|
|
@@ -451,18 +452,7 @@ class EmptyString(base.BaseRule):
|
|
|
451
452
|
"""Check that string fields are not empty or strictly whitespace."""
|
|
452
453
|
|
|
453
454
|
def elements(self):
|
|
454
|
-
"
|
|
455
|
-
string_elements = []
|
|
456
|
-
for _, element in etree.iterwalk(self.schema_tree):
|
|
457
|
-
tag = self.strip_schema_ns(element)
|
|
458
|
-
if (
|
|
459
|
-
tag
|
|
460
|
-
and tag == "element"
|
|
461
|
-
and element.get("type") == "xs:string"
|
|
462
|
-
and element.get("name") is not None
|
|
463
|
-
):
|
|
464
|
-
string_elements.append(element.get("name"))
|
|
465
|
-
return string_elements
|
|
455
|
+
return list(self.get_element_names_for_type("xs:string"))
|
|
466
456
|
|
|
467
457
|
# pylint: disable=g-explicit-length-test
|
|
468
458
|
def check(self, element):
|
|
@@ -961,15 +951,7 @@ class UniqueLabel(base.BaseRule):
|
|
|
961
951
|
self.labels = set()
|
|
962
952
|
|
|
963
953
|
def elements(self):
|
|
964
|
-
|
|
965
|
-
for _, element in etree.iterwalk(self.schema_tree):
|
|
966
|
-
tag = self.strip_schema_ns(element)
|
|
967
|
-
if tag == "element":
|
|
968
|
-
elem_type = element.get("type")
|
|
969
|
-
if elem_type == "InternationalizedText":
|
|
970
|
-
if element.get("name") not in eligible_elements:
|
|
971
|
-
eligible_elements.append(element.get("name"))
|
|
972
|
-
return eligible_elements
|
|
954
|
+
return list(self.get_element_names_for_type("InternationalizedText"))
|
|
973
955
|
|
|
974
956
|
def check(self, element):
|
|
975
957
|
element_label = element.get("label")
|
|
@@ -3939,7 +3921,7 @@ class MultipleInternationalizedTextWithSameLanguageCode(base.BaseRule):
|
|
|
3939
3921
|
"""Checks for multiple InternationalizedText with the same language code."""
|
|
3940
3922
|
|
|
3941
3923
|
def elements(self):
|
|
3942
|
-
return
|
|
3924
|
+
return _INTERNATIONALIZED_TEXT_ELEMENTS_WITH_ONLY_ONE_TEXT_PER_LANGUAGE
|
|
3943
3925
|
|
|
3944
3926
|
def check(self, element):
|
|
3945
3927
|
language_map = get_language_to_text_map(element)
|
|
@@ -3952,22 +3934,10 @@ class MultipleInternationalizedTextWithSameLanguageCode(base.BaseRule):
|
|
|
3952
3934
|
|
|
3953
3935
|
|
|
3954
3936
|
class AllInternationalizedTextHaveEnVersion(base.BaseRule):
|
|
3955
|
-
"""Checks for
|
|
3937
|
+
"""Checks for InternationalizedText elements missing an English version."""
|
|
3956
3938
|
|
|
3957
3939
|
def elements(self):
|
|
3958
|
-
return
|
|
3959
|
-
"BallotName",
|
|
3960
|
-
"Directions",
|
|
3961
|
-
"BallotSubTitle",
|
|
3962
|
-
"BallotTitle",
|
|
3963
|
-
"Name",
|
|
3964
|
-
"InternationalizedName",
|
|
3965
|
-
"InternationalizedAbbreviation",
|
|
3966
|
-
"Alias",
|
|
3967
|
-
"FullName",
|
|
3968
|
-
"Profession",
|
|
3969
|
-
"Title",
|
|
3970
|
-
]
|
|
3940
|
+
return list(self.get_element_names_for_type("InternationalizedText"))
|
|
3971
3941
|
|
|
3972
3942
|
def check(self, element):
|
|
3973
3943
|
language_map = get_language_to_text_map(element)
|
|
@@ -4518,29 +4488,14 @@ class UnreferencedEntitiesBase(base.TreeRule):
|
|
|
4518
4488
|
self.top_level_entity_types = top_level_entity_types
|
|
4519
4489
|
self.warned_entity_types = warned_entity_types
|
|
4520
4490
|
|
|
4521
|
-
def _get_idref_elements(self):
|
|
4522
|
-
"""Returns the names of all XML elements in the schema of type IDREF or IDREFS."""
|
|
4523
|
-
|
|
4524
|
-
idref_elements = set()
|
|
4525
|
-
for _, element in etree.iterwalk(self.schema_tree):
|
|
4526
|
-
tag = self.strip_schema_ns(element)
|
|
4527
|
-
if (
|
|
4528
|
-
tag
|
|
4529
|
-
and tag == "element"
|
|
4530
|
-
and element.get("type") in ("xs:IDREF", "xs:IDREFS")
|
|
4531
|
-
):
|
|
4532
|
-
idref_elements.add(element.get("name"))
|
|
4533
|
-
return idref_elements
|
|
4534
|
-
|
|
4535
4491
|
def _gather_referenced_entities(self):
|
|
4536
4492
|
"""Create a set of all entities referenced by either IDREF(S) elements or external identifiers."""
|
|
4537
|
-
|
|
4538
|
-
idref_elements = self._get_idref_elements()
|
|
4539
4493
|
referenced_entities = set()
|
|
4540
4494
|
for external_id_type in _IDREF_EXTERNAL_IDENTIFIERS:
|
|
4541
4495
|
referenced_entities.update(
|
|
4542
4496
|
get_external_id_values(self.election_tree, external_id_type)
|
|
4543
4497
|
)
|
|
4498
|
+
idref_elements = self.get_element_names_for_types(_IDREF_TYPES)
|
|
4544
4499
|
for _, element in etree.iterwalk(self.election_tree):
|
|
4545
4500
|
tag = self.strip_schema_ns(element)
|
|
4546
4501
|
if tag and tag in idref_elements:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|