fix(catalogs): reject boolean priority in extension and preset catalog readers (#2589)

`bool` is a subclass of `int` in Python, so `int(True)` silently returns
`1`. The extension- and preset-catalog config readers coerced priority
with a bare `int(item.get("priority", idx + 1))`, which meant a YAML
config like:

    catalogs:
      - name: mine
        url: https://example.com/catalog.json
        priority: yes     # parses to True

was silently accepted as a valid priority of 1, quietly reordering the
catalog stack instead of raising the same `Invalid priority` error a
typo of `priority: not-a-number` already raises.

The sibling integration-catalog reader in `src/specify_cli/catalogs.py`
already guards this case (see `catalogs.py:137`). This change mirrors
that pattern in `extensions.py` and `presets.py` so the three catalog
validators stay consistent, and adds regression tests for both readers
matching the existing `test_load_catalog_config_rejects_boolean_priority`
template in `tests/integrations/test_integration_catalog.py`.
This commit is contained in:
Quratulain-bilal
2026-05-21 18:21:13 +05:00
committed by GitHub
parent 7fda89decb
commit 0dee2faf11
2 changed files with 39 additions and 2 deletions

View File

@@ -1830,6 +1830,31 @@ class TestPresetCatalogMultiCatalog:
with pytest.raises(PresetValidationError, match="Invalid priority"):
catalog._load_catalog_config(config_path)
def test_load_catalog_config_rejects_boolean_priority(self, project_dir):
"""A YAML ``priority: true`` is a typo, not a request for priority 1.
``bool`` is a subclass of ``int`` in Python, so ``int(True)`` silently
returns ``1``. Without an explicit guard a malformed config like
``priority: yes`` would be accepted as a valid priority of 1 and
silently change catalog ordering. The sibling integration-catalog
reader rejects this case (see ``catalogs.py``); the preset catalog
reader must stay consistent.
"""
config_path = project_dir / ".specify" / "preset-catalogs.yml"
config_path.write_text(yaml.dump({
"catalogs": [
{
"name": "bool-priority",
"url": "https://example.com/catalog.json",
"priority": True,
}
]
}))
catalog = PresetCatalog(project_dir)
with pytest.raises(PresetValidationError, match="Invalid priority|expected integer"):
catalog._load_catalog_config(config_path)
def test_load_catalog_config_install_allowed_string(self, project_dir):
"""Test that install_allowed accepts string values."""
config_path = project_dir / ".specify" / "preset-catalogs.yml"