civics-cdf-validator 1.45.dev1__tar.gz → 1.46.dev0__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.45.dev1/civics_cdf_validator.egg-info → civics_cdf_validator-1.46.dev0}/PKG-INFO +1 -1
  2. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0/civics_cdf_validator.egg-info}/PKG-INFO +1 -1
  3. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/rules.py +17 -2
  4. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/version.py +1 -1
  5. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/CONTRIBUTING.md +0 -0
  6. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/LICENSE-2.0.txt +0 -0
  7. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/MANIFEST.in +0 -0
  8. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/README.md +0 -0
  9. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/__init__.py +0 -0
  10. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/base.py +0 -0
  11. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/civics_cdf_validator.egg-info/SOURCES.txt +0 -0
  12. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/civics_cdf_validator.egg-info/dependency_links.txt +0 -0
  13. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/civics_cdf_validator.egg-info/entry_points.txt +0 -0
  14. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/civics_cdf_validator.egg-info/requires.txt +0 -0
  15. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/civics_cdf_validator.egg-info/top_level.txt +0 -0
  16. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/gpunit_rules.py +0 -0
  17. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/loggers.py +0 -0
  18. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/office_utils.py +0 -0
  19. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/setup.cfg +0 -0
  20. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/setup.py +0 -0
  21. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/stats.py +0 -0
  22. {civics_cdf_validator-1.45.dev1 → civics_cdf_validator-1.46.dev0}/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: civics_cdf_validator
3
- Version: 1.45.dev1
3
+ Version: 1.46.dev0
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: civics_cdf_validator
3
- Version: 1.45.dev1
3
+ Version: 1.46.dev0
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
@@ -917,18 +917,33 @@ class CandidatesReferencedInRelatedContests(base.BaseRule):
917
917
  self.contest_graph.add_node(contest.get("objectId"))
918
918
 
919
919
  for contest in contests:
920
+ subsequent_contest_id = None
920
921
  subsequent_contest = contest.find("SubsequentContestId")
921
922
  if element_has_text(subsequent_contest):
923
+ subsequent_contest_id = subsequent_contest.text
922
924
  # subsequent contest id is not valid if it isn't in the graph
923
- if not self.contest_graph.has_node(subsequent_contest.text):
925
+ if not self.contest_graph.has_node(subsequent_contest_id):
924
926
  raise loggers.ElectionError.from_message(
925
927
  ("Contest {} contains a subsequent Contest Id ({}) that does "
926
928
  "not exist.").format(
927
- contest.get("objectId"), subsequent_contest.text),
929
+ contest.get("objectId"), subsequent_contest_id),
928
930
  [subsequent_contest])
929
931
  self.contest_graph.add_edge(
930
932
  contest.get("objectId"), subsequent_contest.text
931
933
  )
934
+ # Add the composing contest if it exists
935
+ composing_contests = contest.find("ComposingContestIds")
936
+ if element_has_text(composing_contests):
937
+ children = composing_contests.text.split()
938
+ for child in children:
939
+ # composing contest id is not valid if it isn't in the graph
940
+ if not self.contest_graph.has_node(child):
941
+ raise loggers.ElectionError.from_message(
942
+ ("Contest {} contains a composing Contest Id ({}) that does "
943
+ "not exist.").format(contest.get("objectId"), child),
944
+ [composing_contests])
945
+ if subsequent_contest_id:
946
+ self.contest_graph.add_edge(child, subsequent_contest_id)
932
947
 
933
948
  def _check_candidate_contests_are_related(self, contest_id_list):
934
949
  for i in range(len(contest_id_list) - 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.45.dev1'
8
+ __version__ = '1.46.dev0'