Skip to content

fix(catalogs): reject boolean priority in extension and preset catalo…#2589

Open
Quratulain-bilal wants to merge 2 commits into
github:mainfrom
Quratulain-bilal:fix/catalog-priority-bool-guard
Open

fix(catalogs): reject boolean priority in extension and preset catalo…#2589
Quratulain-bilal wants to merge 2 commits into
github:mainfrom
Quratulain-bilal:fix/catalog-priority-bool-guard

Conversation

@Quratulain-bilal
Copy link
Copy Markdown
Contributor

What

The extension- and preset-catalog config readers silently accept a boolean priority value. Because bool is a
subclass of int in Python, a config like:

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

is coerced via int(True) == 1 and quietly treated as a valid priority of 1 — silently reordering the catalog stack
instead of raising the same Invalid priority error that a typo like priority: "fast" already raises.

The sibling integration-catalog reader in src/specify_cli/catalogs.py already guards this case (see catalogs.py:137,
plus the existing test_load_catalog_config_rejects_boolean_priority in
tests/integrations/test_integration_catalog.py). The extension and preset readers had drifted from that precedent.

Why this matters

  • priority: yes / priority: no / priority: true are easy YAML typos — silently accepting them changes catalog
    resolution order without any warning, which is a frustrating bug to diagnose because the config "looks valid" and no
    error fires.
  • The three catalog readers (catalogs.py, extensions.py, presets.py) validate the same shape and should fail in
    the same way. Today, the same malformed input raises in one and is silently accepted in two.

The change

  • src/specify_cli/extensions.py add isinstance(raw_priority, bool) guard before int(...) in
    ExtensionCatalog._load_catalog_config, raising ValidationError with the same message shape used for other invalid
    priorities.
  • src/specify_cli/presets.py same guard in PresetCatalog._load_catalog_config, raising PresetValidationError.
  • Both call sites mirror the existing catalogs.py:137 pattern exactly, with a short comment explaining the
    bool-is-int subtlety so the rationale is visible to the next reader.

Tests

  • tests/test_extensions.pytest_load_catalog_config_rejects_boolean_priority
  • tests/test_presets.pytest_load_catalog_config_rejects_boolean_priority

Both follow the template of the existing integration-catalog regression test, so the three catalog validators now have
parallel coverage.

$ python -m pytest tests/test_extensions.py::TestCatalogStack tests/test_presets.py::TestPresetCatalog -q
38 passed in 2.44s
$ python -m ruff check src/
All checks passed!

Scope

Intentionally small: no behaviour change for any priority that was previously accepted (real integers, numeric strings,
missing values all behave exactly as before). Only priority: true / priority: false which were almost certainly
never intended as priority 1 / priority 0 now raise a clear error.

…g readers

`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`.
@Quratulain-bilal Quratulain-bilal requested a review from mnriem as a code owner May 15, 2026 22:37
@mnriem mnriem requested a review from Copilot May 18, 2026 15:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens catalog config validation so extension and preset catalog readers reject boolean priority values consistently with the integration catalog reader.

Changes:

  • Adds explicit bool checks before integer coercion in extension and preset catalog config loading.
  • Updates invalid-priority error reporting to use the captured raw priority value.
  • Adds regression tests for boolean priority rejection in extension and preset catalogs.
Show a summary per file
File Description
src/specify_cli/extensions.py Rejects boolean catalog priorities before int(...) coercion.
src/specify_cli/presets.py Applies the same boolean priority validation for preset catalogs.
tests/test_extensions.py Adds coverage for extension catalog boolean priority rejection.
tests/test_presets.py Adds coverage for preset catalog boolean priority rejection.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/4 changed files
  • Comments generated: 0

…bool-guard

# Conflicts:
#	src/specify_cli/extensions.py
#	tests/test_extensions.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants