Skip to content

Commit

Permalink
fix: allow incomplete specs during intermediate parsing stages (#5555)
Browse files Browse the repository at this point in the history
* fix: allow incomplete specs if undefined jinja2

* refactor: skip it instead

* refactor: simpler

* style: pre the commit

* style: no extra whitespace

* test: add test

* test: fix tests
  • Loading branch information
beckermr authored Nov 26, 2024
1 parent aa7a2b6 commit 8d0ca34
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 6 deletions.
23 changes: 18 additions & 5 deletions conda_build/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -1597,21 +1597,34 @@ def ms_depends(self, typ="run"):
try:
ms = MatchSpec(spec)
except AssertionError:
raise RuntimeError(f"Invalid package specification: {spec!r}")
if len(self.undefined_jinja_vars) == 0:
raise RuntimeError(f"Invalid package specification: {spec!r}")
else:
continue
except (AttributeError, ValueError) as e:
raise RuntimeError(
"Received dictionary as spec. Note that pip requirements are "
"not supported in conda-build meta.yaml. Error message: " + str(e)
)
if len(self.undefined_jinja_vars) == 0:
raise RuntimeError(
"Received dictionary as spec. Note that pip requirements are "
"not supported in conda-build meta.yaml. Error message: "
+ str(e)
)
else:
continue

if ms.name == self.name() and not (
typ == "build" and self.config.host_subdir != self.config.build_subdir
):
raise RuntimeError(f"{self.name()} cannot depend on itself")

# TODO: IDK what this does since AFAIK the inner continue applies only
# to the inner loop
for name, ver in name_ver_list:
if ms.name == name:
if self.noarch:
continue

# TODO: the validation here appears to be a waste of time since MatchSpec
# appears to validate?
for c in "=!@#$%^&*:;\"'\\|<>?/":
if c in ms.name:
sys.exit(
Expand Down
19 changes: 19 additions & 0 deletions news/5555-skip-bad-specs-while-still-parsing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* <news item>

### Bug fixes

* Fixed a bug where bad match specs from intermediate parsing results would cause parsing to fail. (#5555)

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>
2 changes: 1 addition & 1 deletion tests/test_api_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2082,7 +2082,7 @@ def test_conda_build_script_errors_without_conda_info_handlers(tmp_path, recipe,

def test_api_build_inject_jinja2_vars_on_first_pass(testing_config):
recipe_dir = os.path.join(metadata_dir, "_inject_jinja2_vars_on_first_pass")
with pytest.raises(RuntimeError):
with pytest.raises((RuntimeError, CondaBuildUserError)):
api.build(recipe_dir, config=testing_config)

testing_config.variant = {"python_min": "3.12"}
Expand Down
53 changes: 53 additions & 0 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,3 +655,56 @@ def test_parse_until_resolved_skip_avoids_undefined_jinja(
pytest.fail(
"Undefined variable caused error, even though this build is skipped"
)


@pytest.mark.parametrize("have_variant", [True, False])
def test_parse_until_resolved_missing_jinja_in_spec(
testing_metadata: MetaData,
tmp_path: Path,
have_variant: bool,
) -> None:
(recipe := tmp_path / (name := "meta.yaml")).write_text(
"""
package:
name: dummy
version: 1.0.0
build:
noarch: python
number: 0
requirements:
host:
- python ={{ python_min }}
run:
- python >={{ python_min }}
"""
)
(tmp_path / "conda_build_config.yaml").write_text(
"""
python_min:
- 3.6
"""
)
testing_metadata._meta_path = recipe
testing_metadata._meta_name = name
if have_variant:
testing_metadata.config.variant = {"python_min": "3.6"}
else:
delattr(testing_metadata.config, "variant")
delattr(testing_metadata.config, "variant_config_files")
delattr(testing_metadata.config, "variants")

try:
testing_metadata.parse_until_resolved()
if not have_variant:
pytest.fail("Undefined variable did NOT cause spec parsing error!")
else:
print("parsed OK!")
except (Exception, SystemExit):
if have_variant:
pytest.fail(
"Undefined variable caused spec parsing error even if we have the variant!"
)
else:
print("did not parse OK!")

0 comments on commit 8d0ca34

Please sign in to comment.