|
25 | 25 | # Strictness is correct there: a bad value is the caller's typo and should raise |
26 | 26 | # rather than be silently coerced. Add an entry only with a comment justifying |
27 | 27 | # that the enum never sees API-supplied values. |
28 | | -REQUEST_ONLY_ENUMS = frozenset() |
| 28 | +REQUEST_ONLY_ENUMS = frozenset( |
| 29 | + { |
| 30 | + # Only ever travels outbound: FullScanParams.to_dict() is urlencoded |
| 31 | + # onto the create-scan query string. It never parses an API response, so |
| 32 | + # an unrecognized value is a caller typo that should surface at |
| 33 | + # construction rather than reach the API as scan_type=unknown. |
| 34 | + "ScanType", |
| 35 | + } |
| 36 | +) |
29 | 37 |
|
30 | 38 | # A value the API will never legitimately send. |
31 | 39 | SENTINEL = "__value_the_api_would_never_send__" |
@@ -98,6 +106,24 @@ def test_unknown_value_warns(self): |
98 | 106 | f"got: {captured.output}", |
99 | 107 | ) |
100 | 108 |
|
| 109 | + def test_request_only_enums_stay_strict(self): |
| 110 | + # The opt-out is not a "skip this one" marker: these enums must actively |
| 111 | + # keep raising. Coercing a caller's typo to a fallback would send the |
| 112 | + # fallback to the API instead of failing at construction, which is how |
| 113 | + # the forward-compat change first got ScanType wrong. |
| 114 | + by_name = {cls.__name__: cls for cls in _all_enums().values()} |
| 115 | + for name in sorted(REQUEST_ONLY_ENUMS): |
| 116 | + with self.subTest(enum=name): |
| 117 | + enum_cls = by_name.get(name) |
| 118 | + self.assertIsNotNone( |
| 119 | + enum_cls, f"{name} is exempted but no longer exists" |
| 120 | + ) |
| 121 | + with self.assertRaises( |
| 122 | + ValueError, |
| 123 | + msg=f"{name} is request-only and must reject unknown values", |
| 124 | + ): |
| 125 | + enum_cls(SENTINEL) |
| 126 | + |
101 | 127 | def test_known_values_still_round_trip(self): |
102 | 128 | # Forward-compat must not swallow legitimate values. |
103 | 129 | for qualname, enum_cls in sorted(_all_enums().items()): |
|
0 commit comments