Skip to content

Commit

Permalink
Remove/avoid redundant function calls (#5280)
Browse files Browse the repository at this point in the history
* Remove/avoid redundant function calls

Signed-off-by: Marcel Bargull <[email protected]>

* Refactor get_vars
* Deprecate get_vars(loop_only)

---------

Signed-off-by: Marcel Bargull <[email protected]>
Co-authored-by: Marcel Bargull <[email protected]>
  • Loading branch information
kenodegard and mbargull authored Apr 17, 2024
1 parent f6d7798 commit 2d3270d
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 50 deletions.
64 changes: 27 additions & 37 deletions conda_build/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from conda.gateways.disk.read import compute_sum
from frozendict import deepfreeze

from . import exceptions, utils, variants
from . import exceptions, utils
from .conda_interface import MatchSpec
from .config import Config, get_or_merge_config
from .features import feature_list
Expand All @@ -34,6 +34,15 @@
insert_variant_versions,
on_win,
)
from .variants import (
dict_of_lists_to_list_of_dicts,
find_used_variables_in_batch_script,
find_used_variables_in_shell_script,
find_used_variables_in_text,
get_default_variant,
get_vars,
list_of_dicts_to_dict_of_lists,
)

if TYPE_CHECKING:
from typing import Literal
Expand Down Expand Up @@ -156,7 +165,7 @@ def get_selectors(config: Config) -> dict[str, bool]:
if arch == "32":
d["x86"] = plat.endswith(("-32", "-64"))

defaults = variants.get_default_variant(config)
defaults = get_default_variant(config)
py = config.variant.get("python", defaults["python"])
# there are times when python comes in as a tuple
if not hasattr(py, "split"):
Expand Down Expand Up @@ -2435,9 +2444,7 @@ def append_parent_metadata(self, out_metadata):

def get_reduced_variant_set(self, used_variables):
# reduce variable space to limit work we need to do
full_collapsed_variants = variants.list_of_dicts_to_dict_of_lists(
self.config.variants
)
full_collapsed_variants = list_of_dicts_to_dict_of_lists(self.config.variants)
reduced_collapsed_variants = full_collapsed_variants.copy()
reduce_keys = set(self.config.variants[0].keys()) - set(used_variables)

Expand Down Expand Up @@ -2469,7 +2476,7 @@ def get_reduced_variant_set(self, used_variables):
# save only one element from this key
reduced_collapsed_variants[key] = utils.ensure_list(next(iter(values)))

out = variants.dict_of_lists_to_list_of_dicts(reduced_collapsed_variants)
out = dict_of_lists_to_list_of_dicts(reduced_collapsed_variants)
return out

def get_output_metadata_set(
Expand Down Expand Up @@ -2613,21 +2620,14 @@ def get_output_metadata_set(
return output_tuples

def get_loop_vars(self):
_variants = (
self.config.input_variants
if hasattr(self.config, "input_variants")
else self.config.variants
)
return variants.get_vars(_variants, loop_only=True)
return get_vars(getattr(self.config, "input_variants", self.config.variants))

def get_used_loop_vars(self, force_top_level=False, force_global=False):
return {
var
for var in self.get_used_vars(
force_top_level=force_top_level, force_global=force_global
)
if var in self.get_loop_vars()
}
loop_vars = self.get_loop_vars()
used_vars = self.get_used_vars(
force_top_level=force_top_level, force_global=force_global
)
return set(loop_vars).intersection(used_vars)

def get_rendered_recipe_text(
self, permit_undefined_jinja=False, extract_pattern=None
Expand Down Expand Up @@ -2803,7 +2803,7 @@ def _get_used_vars_meta_yaml(self, force_top_level=False, force_global=False):
apply_selectors=False,
)

all_used_selectors = variants.find_used_variables_in_text(
all_used_selectors = find_used_variables_in_text(
variant_keys, recipe_text, selectors_only=True
)

Expand All @@ -2812,7 +2812,7 @@ def _get_used_vars_meta_yaml(self, force_top_level=False, force_global=False):
force_global=force_global,
apply_selectors=True,
)
all_used_reqs = variants.find_used_variables_in_text(
all_used_reqs = find_used_variables_in_text(
variant_keys, recipe_text, selectors_only=False
)

Expand All @@ -2823,9 +2823,7 @@ def _get_used_vars_meta_yaml(self, force_top_level=False, force_global=False):
if force_global:
used = all_used
else:
requirements_used = variants.find_used_variables_in_text(
variant_keys, reqs_text
)
requirements_used = find_used_variables_in_text(variant_keys, reqs_text)
outside_reqs_used = all_used - requirements_used

requirements_used = trim_build_only_deps(self, requirements_used)
Expand All @@ -2838,16 +2836,12 @@ def _get_used_vars_build_scripts(self):
buildsh = os.path.join(self.path, "build.sh")
if os.path.isfile(buildsh):
used_vars.update(
variants.find_used_variables_in_shell_script(
self.config.variant, buildsh
)
find_used_variables_in_shell_script(self.config.variant, buildsh)
)
bldbat = os.path.join(self.path, "bld.bat")
if self.config.platform == "win" and os.path.isfile(bldbat):
used_vars.update(
variants.find_used_variables_in_batch_script(
self.config.variant, bldbat
)
find_used_variables_in_batch_script(self.config.variant, bldbat)
)
return used_vars

Expand All @@ -2860,15 +2854,11 @@ def _get_used_vars_output_script(self):
script = os.path.join(self.path, this_output["script"])
if os.path.splitext(script)[1] == ".sh":
used_vars.update(
variants.find_used_variables_in_shell_script(
self.config.variant, script
)
find_used_variables_in_shell_script(self.config.variant, script)
)
elif os.path.splitext(script)[1] == ".bat":
used_vars.update(
variants.find_used_variables_in_batch_script(
self.config.variant, script
)
find_used_variables_in_batch_script(self.config.variant, script)
)
else:
log = utils.get_logger(__name__)
Expand All @@ -2879,7 +2869,7 @@ def _get_used_vars_output_script(self):
return used_vars

def get_variants_as_dict_of_lists(self):
return variants.list_of_dicts_to_dict_of_lists(self.config.variants)
return list_of_dicts_to_dict_of_lists(self.config.variants)

def clean(self):
"""This ensures that clean is called with the correct build id"""
Expand Down
34 changes: 21 additions & 13 deletions conda_build/variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
"""This file handles the parsing of feature specifications from files,
ending up with a configuration matrix"""

from __future__ import annotations

import os.path
import re
import sys
from collections import OrderedDict
from copy import copy
from functools import lru_cache
from itertools import product
from typing import TYPE_CHECKING

import yaml
from conda.base.context import context

from .conda_interface import cc_conda_build
from .deprecations import deprecated
from .utils import ensure_list, get_logger, islist, on_win, trim_empty_keys
from .version import _parse as parse_version

if TYPE_CHECKING:
from typing import Any, Iterable

DEFAULT_VARIANTS = {
"python": f"{sys.version_info.major}.{sys.version_info.minor}",
"numpy": {
Expand Down Expand Up @@ -694,21 +701,22 @@ def get_package_variants(recipedir_or_metadata, config=None, variants=None):
return filter_combined_spec_to_used_keys(combined_spec, specs=specs)


def get_vars(variants, loop_only=False):
@deprecated.argument("24.5", "24.7", "loop_only")
def get_vars(variants: Iterable[dict[str, Any]]) -> set[str]:
"""For purposes of naming/identifying, provide a way of identifying which variables contribute
to the matrix dimensionality"""
special_keys = {"pin_run_as_build", "zip_keys", "ignore_version"}
special_keys.update(set(ensure_list(variants[0].get("extend_keys"))))
loop_vars = [
k
for k in variants[0]
if k not in special_keys
and (
not loop_only
or any(variant[k] != variants[0][k] for variant in variants[1:])
)
]
return loop_vars
first, *others = variants
special_keys = {
"pin_run_as_build",
"zip_keys",
"ignore_version",
*ensure_list(first.get("extend_keys")),
}
return {
var
for var in set(first) - special_keys
if any(first[var] != other[var] for other in others)
}


@lru_cache(maxsize=None)
Expand Down
19 changes: 19 additions & 0 deletions news/5280-deprecate-get_vars-loop_only
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* <news item>

### Bug fixes

* <news item>

### Deprecations

* Deprecate `conda_build.variants.get_vars(loop_only)`. Unused. (#5280)

### Docs

* <news item>

### Other

* <news item>
15 changes: 15 additions & 0 deletions tests/test_variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
dict_of_lists_to_list_of_dicts,
filter_combined_spec_to_used_keys,
get_package_variants,
get_vars,
validate_spec,
)

Expand Down Expand Up @@ -700,3 +701,17 @@ def test_zip_key_filtering(
}

assert filter_combined_spec_to_used_keys(combined_spec, specs=specs) == expected


def test_get_vars():
variants = [
{
"python": "3.12",
"nodejs": "20",
"zip_keys": [], # ignored
},
{"python": "3.12", "nodejs": "18"},
{"python": "3.12", "nodejs": "20"},
]

assert get_vars(variants) == {"nodejs"}

0 comments on commit 2d3270d

Please sign in to comment.