civics-cdf-validator 1.55.dev0__py3-none-any.whl → 1.55.dev2__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.
@@ -71,6 +71,15 @@ _INTERNATIONALIZED_TEXT_ELEMENTS = [
71
71
  "Title",
72
72
  # go/keep-sorted end
73
73
  ]
74
+ _GPUNIT_TYPES_WITHOUT_OCD_IDS = frozenset([
75
+ "ballot-batch",
76
+ "ballot-style-area",
77
+ "combined-precinct",
78
+ "drop-box",
79
+ "polling-place",
80
+ "split-precinct",
81
+ "vote-center",
82
+ ])
74
83
 
75
84
  _EXECUTIVE_OFFICE_ROLES = frozenset([
76
85
  "head of state",
@@ -558,95 +567,53 @@ class ValidStableID(base.BaseRule):
558
567
  raise loggers.ElectionError(error_log)
559
568
 
560
569
 
561
- class ElectoralDistrictOcdId(base.BaseRule):
562
- """GpUnit referred to by ElectoralDistrictId MUST have a valid OCD-ID."""
563
-
564
- def __init__(self, election_tree, schema_tree, **kwargs):
565
- super(ElectoralDistrictOcdId, self).__init__(
566
- election_tree, schema_tree, **kwargs
567
- )
568
- self._all_gpunits = {}
569
-
570
- def setup(self):
571
- gp_units = self.election_tree.findall(".//GpUnit")
572
- for gp_unit in gp_units:
573
- if "objectId" not in gp_unit.attrib:
574
- continue
575
- self._all_gpunits[gp_unit.attrib["objectId"]] = gp_unit
570
+ class GpUnitOcdId(base.BaseRule):
571
+ """All GpUnits MUST have a valid OCD ID."""
576
572
 
577
573
  def elements(self):
578
- return ["ElectoralDistrictId"]
574
+ return ["GpUnit"]
579
575
 
580
576
  def check(self, element):
581
- error_log = []
582
- referenced_gpunit = self._all_gpunits.get(element.text)
583
- if referenced_gpunit is None:
584
- msg = (
585
- "The ElectoralDistrictId element not refer to a GpUnit. Every "
586
- "ElectoralDistrictId MUST reference a GpUnit"
577
+ # ReportingDevices are not expected to have OCD IDs.
578
+ if self.get_element_class(element) == "ReportingDevice":
579
+ return
580
+ type_element = element.find("Type")
581
+ if (
582
+ element_has_text(type_element)
583
+ and type_element.text in _GPUNIT_TYPES_WITHOUT_OCD_IDS
584
+ ):
585
+ return
586
+ ocd_ids = get_external_id_values(element, "ocd-id")
587
+ if not ocd_ids:
588
+ raise loggers.ElectionError.from_message(
589
+ f"The GpUnit {element.get('objectId')} does not have an ocd-id.",
590
+ [element],
591
+ [element.sourceline],
587
592
  )
588
- error_log.append(loggers.LogEntry(msg, [element]))
589
- else:
590
- ocd_ids = get_external_id_values(referenced_gpunit, "ocd-id")
591
- if not ocd_ids:
592
- error_log.append(
593
- loggers.LogEntry(
594
- "The referenced GpUnit %s does not have an ocd-id"
595
- % element.text,
596
- [element],
597
- [referenced_gpunit.sourceline],
598
- )
593
+ for ocd_id in ocd_ids:
594
+ if not self.ocd_id_validator.is_valid_ocd_id(ocd_id):
595
+ raise loggers.ElectionError.from_message(
596
+ f"The GpUnit {element.get('objectId')} does not have a valid "
597
+ f"ocd-id: '{ocd_id}'.",
598
+ [element],
599
+ [element.sourceline],
599
600
  )
600
- else:
601
- for ocd_id in ocd_ids:
602
- if not self.ocd_id_validator.is_valid_ocd_id(ocd_id):
603
- error_log.append(
604
- loggers.LogEntry(
605
- "The ElectoralDistrictId refers to GpUnit %s "
606
- "that does not have a valid OCD ID (%s)"
607
- % (element.text, ocd_id),
608
- [element],
609
- [referenced_gpunit.sourceline],
610
- )
611
- )
612
- if error_log:
613
- raise loggers.ElectionError(error_log)
614
601
 
615
602
 
616
- class GpUnitOcdId(base.BaseRule):
617
- """Any GpUnit that is a geographic district SHOULD have a valid OCD-ID."""
618
-
619
- districts = [
620
- "borough",
621
- "city",
622
- "county",
623
- "municipality",
624
- "state",
625
- "town",
626
- "township",
627
- "village",
628
- ]
629
- validate_ocd_file = True
603
+ # TODO(b/337001513): Remove this once the new rule is rolled out everywhere and
604
+ # no feeds have this in their disabled rules anymore.
605
+ class ElectoralDistrictOcdId(base.BaseRule):
606
+ """All GpUnits MUST have a valid OCD ID."""
630
607
 
631
608
  def elements(self):
632
609
  return ["ReportingUnit"]
633
610
 
634
611
  def check(self, element):
635
- gpunit_type = element.find("Type")
636
- if gpunit_type is not None and gpunit_type.text in self.districts:
637
- external_id_elements = get_external_id_values(
638
- element, "ocd-id", return_elements=True
639
- )
640
- for extern_id in external_id_elements:
641
- if not self.ocd_id_validator.is_valid_ocd_id(extern_id.text):
642
- msg = "The OCD ID %s is not valid" % extern_id.text
643
- raise loggers.ElectionWarning.from_message(
644
- msg, [element], [extern_id.sourceline]
645
- )
612
+ pass
646
613
 
647
614
 
648
615
  class DuplicatedGpUnitOcdId(base.BaseRule):
649
- """2 GPUnits should not have same OCD-ID."""
616
+ """2 GpUnits should not have same OCD ID."""
650
617
 
651
618
  def elements(self):
652
619
  return ["GpUnitCollection"]
@@ -1389,6 +1356,14 @@ class ValidateDuplicateColors(base.TreeRule):
1389
1356
  element=party_contest, element_name="PartyIds"
1390
1357
  ):
1391
1358
  for party_id in party_ids_element.text.split():
1359
+ if party_id not in party_color_mapping:
1360
+ warning_log.append(
1361
+ loggers.LogEntry(
1362
+ "Party (%s) in PartyContest should have an assigned color."
1363
+ % party_id
1364
+ )
1365
+ )
1366
+ continue
1392
1367
  party_color = party_color_mapping[party_id][0]
1393
1368
  if party_color in contest_colors:
1394
1369
  contest_colors[party_color].append(party_color_mapping[party_id][1])
@@ -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.55.dev0'
8
+ __version__ = '1.55.dev2'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.55.dev0
3
+ Version: 1.55.dev2
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
@@ -3,13 +3,13 @@ civics_cdf_validator/base.py,sha256=5zntjAdAA-bdwYOOStFgUle9LGX_ccelS--thMhUG9A,
3
3
  civics_cdf_validator/gpunit_rules.py,sha256=Cg-qlOeVKTCQ5qUKYSxbVrrh3tdLt1X5Eg-7uyyR_SY,9487
4
4
  civics_cdf_validator/loggers.py,sha256=ZfWFd9yskcd2-qb83EPz7eqa1iGO8BRFMtDZeE1hofA,6921
5
5
  civics_cdf_validator/office_utils.py,sha256=aFxcFQZF2oBn0gPXt_kv1LxHGvwzABScT8X5yaYtVLw,2705
6
- civics_cdf_validator/rules.py,sha256=slArBGSKIborc-4ypcXciDoTP7J6EUnR-lUDe51KzBo,165531
6
+ civics_cdf_validator/rules.py,sha256=mhFmup6AmLTQIxtVmzerBRehdSuACe5iWhIg4nnyaSw,164641
7
7
  civics_cdf_validator/stats.py,sha256=YNqv3Khkt_hJxCIunFBRSl23oXqu5gNjCmWMHFbAcSU,3819
8
8
  civics_cdf_validator/validator.py,sha256=2nwlFfQ9AmpTaO5n5ekaO845Rm0JPjNF-Il6FJW_50k,12678
9
- civics_cdf_validator/version.py,sha256=-IgVt3DdiIPmJwMEDsgoVLIV2l-oasljSz1qkfy7zX8,188
10
- civics_cdf_validator-1.55.dev0.dist-info/licenses/LICENSE-2.0.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
11
- civics_cdf_validator-1.55.dev0.dist-info/METADATA,sha256=_EDKP4G-0A_zbayQm2sQDHthUAVUWyff7NRs_L5He2Q,1218
12
- civics_cdf_validator-1.55.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- civics_cdf_validator-1.55.dev0.dist-info/entry_points.txt,sha256=QibgvtMOocwDi7fQ1emgMJ2lIlI41sW0__KIQdnVn90,77
14
- civics_cdf_validator-1.55.dev0.dist-info/top_level.txt,sha256=PYT5Eclxbop5o6DJIcgs4IeU6Ds5jqyftjoFbgkkJYo,21
15
- civics_cdf_validator-1.55.dev0.dist-info/RECORD,,
9
+ civics_cdf_validator/version.py,sha256=2-E4n1DJTc6Z60MLFZw6USuaV3LOvCCi9bO-jkdvJjE,188
10
+ civics_cdf_validator-1.55.dev2.dist-info/licenses/LICENSE-2.0.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
11
+ civics_cdf_validator-1.55.dev2.dist-info/METADATA,sha256=5bVzvldK7o-0z6UGGmO08_bwHj_ijs9C0TMw-Pq52Fg,1218
12
+ civics_cdf_validator-1.55.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ civics_cdf_validator-1.55.dev2.dist-info/entry_points.txt,sha256=QibgvtMOocwDi7fQ1emgMJ2lIlI41sW0__KIQdnVn90,77
14
+ civics_cdf_validator-1.55.dev2.dist-info/top_level.txt,sha256=PYT5Eclxbop5o6DJIcgs4IeU6Ds5jqyftjoFbgkkJYo,21
15
+ civics_cdf_validator-1.55.dev2.dist-info/RECORD,,