Skip to content

Commit

Permalink
Properly initialize context with parsed arguments (#5271)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenodegard authored Apr 18, 2024
1 parent e4434d9 commit a6d53af
Show file tree
Hide file tree
Showing 18 changed files with 100 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/post_create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ echo "Installing dev dependencies"
--file "$SRC_CONDA_BUILD/tests/requirements.txt" \
--file "$SRC_CONDA_BUILD/tests/requirements-Linux.txt" \
--file "$SRC_CONDA_BUILD/tests/requirements-ci.txt" \
"conda>=23.5.0"
"conda>=23.7.0"
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ jobs:
include:
# minimum Python/conda combo
- python-version: '3.8'
conda-version: 23.5.0
conda-version: 23.7.0
test-type: serial
- python-version: '3.8'
conda-version: 23.5.0
conda-version: 23.7.0
test-type: parallel
# maximum Python/conda combo
- python-version: '3.12'
Expand Down
3 changes: 2 additions & 1 deletion conda_build/cli/main_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,14 @@ def check_action(recipe, config):

def execute(args: Sequence[str] | None = None) -> int:
_, parsed = parse_args(args)
context.__init__(argparse_args=parsed)

config = get_or_merge_config(None, **parsed.__dict__)
build.check_external()

# change globals in build module, see comment there as well
config.channel_urls = get_channel_urls(parsed.__dict__)

config.override_channels = parsed.override_channels
config.verbose = not parsed.quiet or parsed.debug

if "purge" in parsed.recipe:
Expand Down
4 changes: 4 additions & 0 deletions conda_build/cli/main_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from os.path import abspath, expanduser
from typing import TYPE_CHECKING

from conda.base.context import context

from .. import api

if TYPE_CHECKING:
Expand Down Expand Up @@ -126,6 +128,8 @@ def parse_args(args: Sequence[str] | None) -> tuple[ArgumentParser, Namespace]:

def execute(args: Sequence[str] | None = None) -> int:
_, parsed = parse_args(args)
context.__init__(argparse_args=parsed)

files = parsed.files
del parsed.__dict__["files"]

Expand Down
3 changes: 3 additions & 0 deletions conda_build/cli/main_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import sys
from typing import TYPE_CHECKING

from conda.base.context import context

from .. import api
from ..utils import on_win
from . import validators as valid
Expand Down Expand Up @@ -94,6 +96,7 @@ def get_parser() -> ArgumentParser:
def execute(args: Sequence[str] | None = None) -> int:
parser = get_parser()
parsed = parser.parse_args(args)
context.__init__(argparse_args=parsed)

try:
activation_string = api.debug(
Expand Down
7 changes: 4 additions & 3 deletions conda_build/cli/main_develop.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import logging
from typing import TYPE_CHECKING

from conda.base.context import context, determine_target_prefix
from conda.base.context import context

from .. import api

Expand Down Expand Up @@ -88,10 +88,11 @@ def parse_args(args: Sequence[str] | None) -> tuple[ArgumentParser, Namespace]:

def execute(args: Sequence[str] | None = None) -> int:
_, parsed = parse_args(args)
prefix = determine_target_prefix(context, parsed)
context.__init__(argparse_args=parsed)

api.develop(
parsed.source,
prefix=prefix,
prefix=context.target_prefix,
no_pth_file=parsed.no_pth_file,
build_ext=parsed.build_ext,
clean=parsed.clean,
Expand Down
7 changes: 4 additions & 3 deletions conda_build/cli/main_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pprint import pprint
from typing import TYPE_CHECKING

from conda.base.context import context, determine_target_prefix
from conda.base.context import context

from .. import api

Expand Down Expand Up @@ -196,6 +196,7 @@ def parse_args(args: Sequence[str] | None) -> tuple[ArgumentParser, Namespace]:

def execute(args: Sequence[str] | None = None) -> int:
parser, parsed = parse_args(args)
context.__init__(argparse_args=parsed)

if not parsed.subcommand:
parser.print_help()
Expand All @@ -206,7 +207,7 @@ def execute(args: Sequence[str] | None = None) -> int:
print(
api.inspect_linkages(
parsed.packages,
prefix=determine_target_prefix(context, parsed),
prefix=context.target_prefix,
untracked=parsed.untracked,
all_packages=parsed.all,
show_files=parsed.show_files,
Expand All @@ -218,7 +219,7 @@ def execute(args: Sequence[str] | None = None) -> int:
print(
api.inspect_objects(
parsed.packages,
prefix=determine_target_prefix(context, parsed),
prefix=context.target_prefix,
groupby=parsed.groupby,
)
)
Expand Down
10 changes: 7 additions & 3 deletions conda_build/cli/main_metapackage.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,12 @@ def parse_args(args: Sequence[str] | None) -> tuple[ArgumentParser, Namespace]:


def execute(args: Sequence[str] | None = None) -> int:
_, args = parse_args(args)
channel_urls = args.__dict__.get("channel") or args.__dict__.get("channels") or ()
api.create_metapackage(channel_urls=channel_urls, **args.__dict__)
_, parsed = parse_args(args)
context.__init__(argparse_args=parsed)

api.create_metapackage(
channel_urls=context.channels,
**parsed.__dict__,
)

return 0
3 changes: 1 addition & 2 deletions conda_build/cli/main_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ def parse_args(args: Sequence[str] | None) -> tuple[ArgumentParser, Namespace]:

def execute(args: Sequence[str] | None = None) -> int:
_, parsed = parse_args(args)
context.__init__(argparse_args=parsed)

config = get_or_merge_config(None, **parsed.__dict__)

Expand All @@ -213,8 +214,6 @@ def execute(args: Sequence[str] | None = None) -> int:

config.channel_urls = get_channel_urls(parsed.__dict__)

config.override_channels = parsed.override_channels

if parsed.output:
config.verbose = False
config.debug = False
Expand Down
4 changes: 4 additions & 0 deletions conda_build/cli/main_skeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from importlib import import_module
from typing import TYPE_CHECKING

from conda.base.context import context

from .. import api
from ..config import Config

Expand Down Expand Up @@ -52,6 +54,8 @@ def parse_args(args: Sequence[str] | None) -> tuple[ArgumentParser, Namespace]:

def execute(args: Sequence[str] | None = None) -> int:
parser, parsed = parse_args(args)
context.__init__(argparse_args=parsed)

config = Config(**parsed.__dict__)

if not parsed.repo:
Expand Down
15 changes: 14 additions & 1 deletion conda_build/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from conda.base.context import context
from conda.utils import url_path

from .deprecations import deprecated
from .utils import (
get_build_folders,
get_conda_operation_locks,
Expand Down Expand Up @@ -89,7 +90,6 @@ def _get_default_settings():
Setting("dirty", False),
Setting("include_recipe", True),
Setting("no_download_source", False),
Setting("override_channels", False),
Setting("skip_existing", False),
Setting("token", None),
Setting("user", None),
Expand Down Expand Up @@ -297,6 +297,10 @@ def set_lang(variant, lang):
for lang in ("perl", "lua", "python", "numpy", "r_base"):
set_lang(self.variant, lang)

# --override-channels is a valid CLI argument but we no longer wish to set it here
# use conda.base.context.context.override_channels instead
kwargs.pop("override_channels", None)

self._build_id = kwargs.pop("build_id", getattr(self, "_build_id", ""))
source_cache = kwargs.pop("cache_dir", None)
croot = kwargs.pop("croot", None)
Expand Down Expand Up @@ -779,6 +783,15 @@ def test_dir(self):
def subdirs_same(self):
return self.host_subdir == self.build_subdir

@property
@deprecated(
"24.5",
"24.7",
addendum="Use `conda.base.context.context.override_channels` instead.",
)
def override_channels(self):
return context.override_channels

def clean(self, remove_folders=True):
# build folder is the whole burrito containing envs and source folders
# It will only exist if we download source, or create a build or test environment
Expand Down
19 changes: 19 additions & 0 deletions news/5271-context
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* Require `conda >=23.7.0`. (#5271)

### Bug fixes

* Fix all CLI arguments to properly initialize `conda.base.context.context` with parsed arguments. Fixes issue with arguments not being processed (e.g., `--override-channels` was previously ignored). (#3693 via #5271)

### Deprecations

* Deprecate `conda_build.config.Config.override_channels`. Use `conda.base.context.context.override_channels` instead. (#5271)

### Docs

* <news item>

### Other

* <news item>
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ classifiers = [
dependencies = [
"beautifulsoup4",
"chardet",
"conda >=23.5.0",
"conda >=23.7.0",
"conda-index >=0.4.0",
"conda-package-handling >=1.3",
"filelock",
Expand Down
2 changes: 1 addition & 1 deletion recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ requirements:
run:
- beautifulsoup4
- chardet
- conda >=23.5.0
- conda >=23.7.0
- conda-index >=0.4.0
- conda-package-handling >=1.3
- filelock
Expand Down
12 changes: 12 additions & 0 deletions tests/cli/test_main_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import TYPE_CHECKING

import pytest
from conda.exceptions import PackagesNotFoundError

from conda_build import api
from conda_build.cli import main_build, main_render
Expand Down Expand Up @@ -549,3 +550,14 @@ def test_user_warning(tmpdir, recwarn):

main_build.parse_args([str(dir_recipe_path)])
assert not recwarn.list


def test_build_with_empty_channel_fails(empty_channel: Path) -> None:
with pytest.raises(PackagesNotFoundError):
main_build.execute(
[
"--override-channels",
f"--channel={empty_channel}",
os.path.join(metadata_dir, "_recipe_requiring_external_channel"),
]
)
31 changes: 11 additions & 20 deletions tests/cli/test_main_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import pytest
import yaml
from conda.exceptions import PackagesNotFoundError

from conda_build import api
from conda_build.cli import main_render
Expand Down Expand Up @@ -48,26 +49,16 @@ def test_render_add_channel(tmp_path: Path) -> None:
), f"Expected version number 1.0 on successful rendering, but got {required_package_details[1]}"


def test_render_without_channel_fails(tmp_path):
# do make extra channel available, so the required package should not be found
rendered_filename = tmp_path / "out.yaml"
args = [
"--override-channels",
os.path.join(metadata_dir, "_recipe_requiring_external_channel"),
"--file",
str(rendered_filename),
]
main_render.execute(args)
with open(rendered_filename) as rendered_file:
rendered_meta = yaml.safe_load(rendered_file)
required_package_string = [
pkg
for pkg in rendered_meta.get("requirements", {}).get("build", [])
if "conda_build_test_requirement" in pkg
][0]
assert (
required_package_string == "conda_build_test_requirement"
), f"Expected to get only base package name because it should not be found, but got :{required_package_string}"
def test_render_with_empty_channel_fails(tmp_path: Path, empty_channel: Path) -> None:
with pytest.raises(PackagesNotFoundError):
main_render.execute(
[
"--override-channels",
f"--channel={empty_channel}",
os.path.join(metadata_dir, "_recipe_requiring_external_channel"),
f"--file={tmp_path / 'out.yaml'}",
]
)


def test_render_output_build_path(
Expand Down
9 changes: 9 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import pytest
from conda.common.compat import on_mac, on_win
from conda_index.api import update_index
from pytest import MonkeyPatch

import conda_build
Expand Down Expand Up @@ -251,3 +252,11 @@ def conda_build_test_recipe_envvar(
name = "CONDA_BUILD_TEST_RECIPE_PATH"
monkeypatch.setenv(name, str(conda_build_test_recipe_path))
return name


@pytest.fixture(scope="session")
def empty_channel(tmp_path_factory: pytest.TempPathFactory) -> Path:
"""Create a temporary, empty conda channel."""
channel = tmp_path_factory.mktemp("empty_channel", numbered=False)
update_index(channel)
return channel
2 changes: 1 addition & 1 deletion tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
beautifulsoup4
chardet
conda >=23.5.0
conda >=23.7.0
conda-index >=0.4.0
conda-libmamba-solver # ensure we use libmamba
conda-package-handling >=1.3
Expand Down

0 comments on commit a6d53af

Please sign in to comment.