Skip to content
Open
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
5 changes: 4 additions & 1 deletion src/specify_cli/catalogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ def _load_catalog_config(self, config_path: Path) -> list[CatalogEntry] | None:
)
try:
priority = int(raw_priority)
except (TypeError, ValueError):
except (TypeError, ValueError, OverflowError):
Comment thread
jawwad-ali marked this conversation as resolved.
# OverflowError: int(float("inf")) — a YAML ``priority: .inf``
# would otherwise escape as an uncaught traceback instead of the
# clean validation error.
raise self._validation_error(
f"Invalid catalog config {config_path}: "
f"Invalid priority for catalog '{item.get('name', idx + 1)}': "
Expand Down
5 changes: 4 additions & 1 deletion src/specify_cli/presets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2231,7 +2231,10 @@ def _load_catalog_config(self, config_path: Path) -> Optional[List[PresetCatalog
)
try:
priority = int(raw_priority)
except (TypeError, ValueError):
except (TypeError, ValueError, OverflowError):
# OverflowError: int(float("inf")) — a YAML ``priority: .inf``
# would otherwise escape as an uncaught traceback instead of the
# clean validation error (mirrors catalogs.py).
raise PresetValidationError(
f"Invalid priority for catalog '{item.get('name', idx + 1)}': "
f"expected integer, got {raw_priority!r}"
Expand Down
30 changes: 30 additions & 0 deletions tests/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4542,6 +4542,36 @@ def test_load_catalog_config_rejects_boolean_priority(self, temp_dir):
catalog.get_active_catalogs()
assert str(config_path) in str(exc_info.value)

def test_load_catalog_config_rejects_infinite_priority(self, temp_dir):
"""A ``priority: .inf`` yields a clean validation error, not an uncaught
OverflowError from int(float('inf'))."""
import yaml as yaml_module

project_dir = self._make_project(temp_dir)
config_path = project_dir / ".specify" / "extension-catalogs.yml"
config_path.write_text(
yaml_module.dump(
{
"catalogs": [
{
"name": "inf-priority",
"url": "https://example.com/catalog.json",
"priority": float("inf"),
}
]
}
),
encoding="utf-8",
)

catalog = ExtensionCatalog(project_dir)

with pytest.raises(
ValidationError, match="Invalid priority|expected integer"
) as exc_info:
catalog.get_active_catalogs()
assert str(config_path) in str(exc_info.value)

def test_load_catalog_config_defaults_blank_names(self, temp_dir):
"""Blank and null names normalize by valid catalog order."""
import yaml as yaml_module
Expand Down
18 changes: 18 additions & 0 deletions tests/test_presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2659,6 +2659,24 @@ def test_load_catalog_config_rejects_boolean_priority(self, project_dir):
with pytest.raises(PresetValidationError, match="Invalid priority|expected integer"):
catalog._load_catalog_config(config_path)

def test_load_catalog_config_rejects_infinite_priority(self, project_dir):
"""A ``priority: .inf`` yields a clean validation error, not an uncaught
OverflowError from int(float('inf'))."""
config_path = project_dir / ".specify" / "preset-catalogs.yml"
config_path.write_text(yaml.dump({
"catalogs": [
{
"name": "inf-priority",
"url": "https://example.com/catalog.json",
"priority": float("inf"),
}
]
}))

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"
Expand Down