Commit cd996f7
authored
fix(manifests): reject non-string requires.speckit_version (#3980)
`requires.speckit_version` was presence-checked but never type-checked in
both the extension and preset manifest validators, so an unquoted YAML
`speckit_version: 1.0` (a float) passed validation and reached
`SpecifierSet(required)` in `check_compatibility()`.
That call is guarded by `except InvalidSpecifier` alone, which a
non-string escapes two different ways:
- a float/int/bool/None raises `TypeError: 'float' object is not
iterable` from the `SpecifierSet` constructor;
- a list or dict is an *iterable*, so `SpecifierSet` accepts it and the
failure surfaces much later as `AttributeError: 'str' object has no
attribute 'filter'` from inside `.contains()`.
Neither is a `CompatibilityError`/`PresetCompatibilityError`, so both
bypass the CLI's "Compatibility Error" handler in `_commands.py` and exit
1 with a raw traceback that names no field, leaving the author with no
hint which manifest key is wrong.
Type-check the field in both validators, requiring a non-empty string,
and additionally guard `check_compatibility()` in both managers since
each is public and reachable with a hand-built or mutated manifest. This
mirrors the sibling `IntegrationDescriptor`, which already requires a
non-empty string for the same key, and completes the type-checking pass
started in #3943 for the neighbouring `extension`/`preset` fields.
Adds 33 regression tests across both modules covering every escape path;
26 of them fail without this change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Code (model: Claude Opus 5, supervised)1 parent 0fa86e8 commit cd996f7
4 files changed
Lines changed: 183 additions & 0 deletions
File tree
- src/specify_cli
- extensions
- presets
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
341 | 341 | | |
342 | 342 | | |
343 | 343 | | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
344 | 363 | | |
345 | 364 | | |
346 | 365 | | |
| |||
1851 | 1870 | | |
1852 | 1871 | | |
1853 | 1872 | | |
| 1873 | + | |
| 1874 | + | |
| 1875 | + | |
| 1876 | + | |
| 1877 | + | |
| 1878 | + | |
| 1879 | + | |
| 1880 | + | |
| 1881 | + | |
| 1882 | + | |
| 1883 | + | |
1854 | 1884 | | |
1855 | 1885 | | |
1856 | 1886 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
344 | 344 | | |
345 | 345 | | |
346 | 346 | | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
347 | 366 | | |
348 | 367 | | |
349 | 368 | | |
| |||
756 | 775 | | |
757 | 776 | | |
758 | 777 | | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
759 | 790 | | |
760 | 791 | | |
761 | 792 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
410 | 410 | | |
411 | 411 | | |
412 | 412 | | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
413 | 462 | | |
414 | 463 | | |
415 | 464 | | |
| |||
1265 | 1314 | | |
1266 | 1315 | | |
1267 | 1316 | | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
1268 | 1339 | | |
1269 | 1340 | | |
1270 | 1341 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
406 | 406 | | |
407 | 407 | | |
408 | 408 | | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
409 | 440 | | |
410 | 441 | | |
411 | 442 | | |
| |||
964 | 995 | | |
965 | 996 | | |
966 | 997 | | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
967 | 1018 | | |
968 | 1019 | | |
969 | 1020 | | |
| |||
0 commit comments