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.
Files changed (22) hide show
  1. {civics_cdf_validator-1.57.dev8/civics_cdf_validator.egg-info → civics_cdf_validator-1.57.dev9}/PKG-INFO +1 -1
  2. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/base.py +16 -0
  3. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9/civics_cdf_validator.egg-info}/PKG-INFO +1 -1
  4. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/rules.py +8 -53
  5. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/version.py +1 -1
  6. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/CONTRIBUTING.md +0 -0
  7. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/LICENSE-2.0.txt +0 -0
  8. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/MANIFEST.in +0 -0
  9. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/README.md +0 -0
  10. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/__init__.py +0 -0
  11. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/SOURCES.txt +0 -0
  12. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/dependency_links.txt +0 -0
  13. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/entry_points.txt +0 -0
  14. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/requires.txt +0 -0
  15. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/civics_cdf_validator.egg-info/top_level.txt +0 -0
  16. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/gpunit_rules.py +0 -0
  17. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/loggers.py +0 -0
  18. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/office_utils.py +0 -0
  19. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/setup.cfg +0 -0
  20. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/setup.py +0 -0
  21. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/stats.py +0 -0
  22. {civics_cdf_validator-1.57.dev8 → civics_cdf_validator-1.57.dev9}/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.57.dev8
3
+ Version: 1.57.dev9
4
4
  Summary: Checks if an election feed follows best practices
5
5
  Home-page: https://github.com/google/civics_cdf_validator
6
6
  Author: Google Civics
@@ -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."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.57.dev8
3
+ Version: 1.57.dev9
4
4
  Summary: Checks if an election feed follows best practices
5
5
  Home-page: https://github.com/google/civics_cdf_validator
6
6
  Author: Google Civics
@@ -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
- _INTERNATIONALIZED_TEXT_ELEMENTS = [
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
- """Returns all elements of type xs:string from the schema."""
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
- eligible_elements = []
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 _INTERNATIONALIZED_TEXT_ELEMENTS
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 Internationalized Text Elements missing the english version."""
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:
@@ -5,4 +5,4 @@ No dependencies should be added to this module.
5
5
  See https://packaging.python.org/guides/single-sourcing-package-version/
6
6
  """
7
7
 
8
- __version__ = '1.57.dev8'
8
+ __version__ = '1.57.dev9'