Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/populace_dynamics/data/sipp_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,24 @@ def read_sipp_job_months(
active & ~no_establishment,
_EMPSIZE_CODES,
)
bad_size = raw[f"EJB{n}_EMPSIZE"][
# A garbage *string* on a no-establishment slot would coerce
# to NaN and masquerade as the structural blank, so the raw
# cell is checked too: non-blank raw + NaN coercion refuses,
# keeping the loud-refusal posture symmetric with employer
# slots (review note on #206).
raw_size = raw[f"EJB{n}_EMPSIZE"]
raw_blank = raw_size.isna() | (raw_size.astype(str).str.strip() == "")
bad_size = raw_size[
active
& no_establishment
& empsize.notna()
& ~empsize.isin((_MISSING, _MISSING_ID))
& ~empsize.isin(sorted(_EMPSIZE_CODES))
& (
(
empsize.notna()
& ~empsize.isin((_MISSING, _MISSING_ID))
& ~empsize.isin(sorted(_EMPSIZE_CODES))
)
| (empsize.isna() & ~raw_blank)
)
]
if len(bad_size):
raise _domain_error(year, f"EJB{n}_EMPSIZE", bad_size)
Expand Down
20 changes: 20 additions & 0 deletions tests/data/test_sipp_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,26 @@ def test_corrupt_empsize_on_self_employment_refuses(self, tmp_path):
with pytest.raises(ValueError, match="EJB1_EMPSIZE"):
sipp_jobs.read_sipp_job_months(2023, path=path)

def test_garbage_string_empsize_on_se_slot_refuses(self, tmp_path):
# A non-numeric string coerces to NaN like a structural
# blank; the raw-cell guard keeps it a loud refusal on
# no-establishment slots too (post-merge review note).
# JBORSE 2 and 3 take the same no-establishment code path.
for jborse in (2, 3):
months = [
{
"month": 1,
"job1": {
"JBORSE": jborse,
"CLWRK": 8,
"EMPSIZE": "GARBAGE",
},
}
]
path = _write_pu_file(tmp_path / f"j{jborse}", 2023, months)
with pytest.raises(ValueError, match="EJB1_EMPSIZE"):
sipp_jobs.read_sipp_job_months(2023, path=path)

def test_corrupt_code_on_active_slot_refuses(self, tmp_path):
# Only the -9/-999 sentinels excuse a non-domain value on an
# active slot; an unparseable string or a blank must refuse
Expand Down
2 changes: 1 addition & 1 deletion tests/tier_counts.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schema_version": 1,
"counts": {
"unit": 650,
"unit": 651,
"artifact": 1020,
"integration_psid": 802,
"reproduction_legacy": 520,
Expand Down