civics-cdf-validator 1.49.dev11__py3-none-any.whl → 1.49.dev13__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.
@@ -96,8 +96,14 @@ _VALID_OFFICE_ROLE_COMBINATIONS = frozenset([
96
96
  ])
97
97
 
98
98
 
99
- def _is_executive_office(element):
100
- office_roles = get_entity_info_for_value_type(element, "office-role")
99
+ def _get_office_roles(element, is_post_office_split_feed=False):
100
+ if is_post_office_split_feed:
101
+ return [element.text for element in element.findall("OfficeRole")]
102
+ return get_entity_info_for_value_type(element, "office-role")
103
+
104
+
105
+ def _is_executive_office(element, is_post_office_split_feed=False):
106
+ office_roles = _get_office_roles(element, is_post_office_split_feed)
101
107
  return not _EXECUTIVE_OFFICE_ROLES.isdisjoint(office_roles)
102
108
 
103
109
 
@@ -3454,11 +3460,21 @@ class PartySpanMultipleCountries(base.BaseRule):
3454
3460
  class NonExecutiveOfficeShouldHaveGovernmentBody(base.BaseRule):
3455
3461
  """Ensure non-executive Office elements have a government body defined."""
3456
3462
 
3463
+ def __init__(self, election_tree, schema_tree, **kwargs):
3464
+ self.is_post_office_split_feed = False
3465
+ officeholder_tenure_collection_element = self.get_elements_by_class(
3466
+ election_tree, "OfficeHolderTenureCollection"
3467
+ )
3468
+ if officeholder_tenure_collection_element:
3469
+ self.is_post_office_split_feed = True
3470
+
3457
3471
  def elements(self):
3458
3472
  return ["Office"]
3459
3473
 
3460
3474
  def check(self, element):
3461
- if not _is_executive_office(element) and not _has_government_body(element):
3475
+ if not _is_executive_office(
3476
+ element, self.is_post_office_split_feed
3477
+ ) and not _has_government_body(element):
3462
3478
  raise loggers.ElectionInfo.from_message(
3463
3479
  "Non-executive Office element is missing a government body.",
3464
3480
  [element],
@@ -3468,12 +3484,22 @@ class NonExecutiveOfficeShouldHaveGovernmentBody(base.BaseRule):
3468
3484
  class ExecutiveOfficeShouldNotHaveGovernmentBody(base.BaseRule):
3469
3485
  """Ensure executive Office elements do not have a government body defined."""
3470
3486
 
3487
+ def __init__(self, election_tree, schema_tree, **kwargs):
3488
+ self.is_post_office_split_feed = False
3489
+ officeholder_tenure_collection_element = self.get_elements_by_class(
3490
+ election_tree, "OfficeHolderTenureCollection"
3491
+ )
3492
+ if officeholder_tenure_collection_element:
3493
+ self.is_post_office_split_feed = True
3494
+
3471
3495
  def elements(self):
3472
3496
  return ["Office"]
3473
3497
 
3474
3498
  def check(self, element):
3475
- if _is_executive_office(element) and _has_government_body(element):
3476
- office_roles = get_entity_info_for_value_type(element, "office-role")
3499
+ if _is_executive_office(
3500
+ element, self.is_post_office_split_feed
3501
+ ) and _has_government_body(element):
3502
+ office_roles = _get_office_roles(element, self.is_post_office_split_feed)
3477
3503
  raise loggers.ElectionError.from_message(
3478
3504
  f"Executive Office element (roles: {','.join(office_roles)}) has a "
3479
3505
  "government body. Executive offices should not have government "
@@ -4156,34 +4182,32 @@ class ElectionEventDatesAreSequential(base.DateRule):
4156
4182
  raise loggers.ElectionError(self.error_log)
4157
4183
 
4158
4184
 
4159
- class NoSourceDirPathBeforeInitialDeliveryDate(base.BaseRule):
4160
- """SourceDirPath should only be defined if one of the initial delivery dates is in the past."""
4185
+ class SourceDirPathMustBeSetAfterInitialDeliveryDate(base.BaseRule):
4186
+ """SourceDirPath must be set if any InitialDeliveryDate is in the past."""
4161
4187
 
4162
4188
  def elements(self):
4163
4189
  return ["Feed"]
4164
4190
 
4165
4191
  def check(self, element):
4166
- if not element_has_text(element.find("SourceDirPath")):
4192
+ if element_has_text(element.find("SourceDirPath")):
4167
4193
  return
4168
4194
  today = datetime.date.today()
4169
4195
  today_partial_date = base.PartialDate(
4170
4196
  year=today.year, month=today.month, day=today.day
4171
4197
  )
4172
- initial_deliveries = element.findall(".//InitialDeliveryDate")
4173
- if initial_deliveries:
4174
- for initial_delivery in initial_deliveries:
4175
- initial_delivery_date = (
4176
- base.PartialDate.init_partial_date(initial_delivery.text)
4177
- if element_has_text(initial_delivery)
4178
- else None
4179
- )
4180
- if initial_delivery_date and initial_delivery_date < today_partial_date:
4181
- return
4182
- raise loggers.ElectionWarning.from_message(
4183
- "SourceDirPath is defined but all initialDeliveryDate are in the"
4184
- " future.",
4185
- [element],
4198
+ initial_deliveries = element.findall(".//InitialDeliveryDate") or []
4199
+ for initial_delivery in initial_deliveries:
4200
+ initial_delivery_date = (
4201
+ base.PartialDate.init_partial_date(initial_delivery.text)
4202
+ if element_has_text(initial_delivery)
4203
+ else None
4186
4204
  )
4205
+ if initial_delivery_date and initial_delivery_date < today_partial_date:
4206
+ raise loggers.ElectionError.from_message(
4207
+ "SourceDirPath is not set but an InitialDeliveryDate is in the "
4208
+ f"past for feed {element.find('FeedId').text}.",
4209
+ [element],
4210
+ )
4187
4211
 
4188
4212
 
4189
4213
  class OfficeHolderSubFeedDatesAreSequential(base.DateRule):
@@ -4764,10 +4788,10 @@ METADATA_RULES = (
4764
4788
  FeedInactiveDateIsLatestDate,
4765
4789
  FeedInactiveDateSetForNonEvergreenFeed,
4766
4790
  FeedTypeHasValidFeedLongevity,
4767
- NoSourceDirPathBeforeInitialDeliveryDate,
4768
4791
  OfficeHolderSubFeedDatesAreSequential,
4769
4792
  OptionalAndEmpty,
4770
4793
  Schema,
4794
+ SourceDirPathMustBeSetAfterInitialDeliveryDate,
4771
4795
  SourceDirPathsAreUnique,
4772
4796
  UniqueLabel,
4773
4797
  # go/keep-sorted end
@@ -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.49.dev11'
8
+ __version__ = '1.49.dev13'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.49.dev11
3
+ Version: 1.49.dev13
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=LS6U9YWzu72V2Q0PwyE9xE03Ul392UAPRnrp2uRBMLA,6923
5
5
  civics_cdf_validator/office_utils.py,sha256=aFxcFQZF2oBn0gPXt_kv1LxHGvwzABScT8X5yaYtVLw,2705
6
- civics_cdf_validator/rules.py,sha256=Hn7qk3qLhidhQrb15iq1ZwN4XLJ4HVhY4VHBbNGY9u4,158898
6
+ civics_cdf_validator/rules.py,sha256=Ucw1vURByvUoyMVdBUDnzggO15kExbnpsBZU0Wlg-EE,159895
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=5WTRUaJiARj_r2UPhcMKa9SSvt8tRFJt6pCR0zFyGpc,189
10
- civics_cdf_validator-1.49.dev11.dist-info/licenses/LICENSE-2.0.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
11
- civics_cdf_validator-1.49.dev11.dist-info/METADATA,sha256=9odJ6J0QGbWLOgkjRweufw1myU5Tg_CX3ts5z_zLbCI,1009
12
- civics_cdf_validator-1.49.dev11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- civics_cdf_validator-1.49.dev11.dist-info/entry_points.txt,sha256=QibgvtMOocwDi7fQ1emgMJ2lIlI41sW0__KIQdnVn90,77
14
- civics_cdf_validator-1.49.dev11.dist-info/top_level.txt,sha256=PYT5Eclxbop5o6DJIcgs4IeU6Ds5jqyftjoFbgkkJYo,21
15
- civics_cdf_validator-1.49.dev11.dist-info/RECORD,,
9
+ civics_cdf_validator/version.py,sha256=VFMdAjvjwr34E1vqDkhcL8mmJWGxF_XUDagoSEfJ11Y,189
10
+ civics_cdf_validator-1.49.dev13.dist-info/licenses/LICENSE-2.0.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
11
+ civics_cdf_validator-1.49.dev13.dist-info/METADATA,sha256=MBpl8nej6fgkR0c0jy0owtovKInrOYSLDPpp1k8viaw,1009
12
+ civics_cdf_validator-1.49.dev13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ civics_cdf_validator-1.49.dev13.dist-info/entry_points.txt,sha256=QibgvtMOocwDi7fQ1emgMJ2lIlI41sW0__KIQdnVn90,77
14
+ civics_cdf_validator-1.49.dev13.dist-info/top_level.txt,sha256=PYT5Eclxbop5o6DJIcgs4IeU6Ds5jqyftjoFbgkkJYo,21
15
+ civics_cdf_validator-1.49.dev13.dist-info/RECORD,,