From 7f8a9ed663454525ce78792b6c5c8f9ed08408b9 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 3 Jan 2025 13:31:03 +0530 Subject: [PATCH] Add docs --- conda_build/metadata.py | 4 +- docs/source/resources/define-metadata.rst | 55 +++++++++++++++++++ .../meta.yaml | 0 tests/test_api_build.py | 14 +++++ 4 files changed, 71 insertions(+), 2 deletions(-) rename tests/test-recipes/metadata/{python_version_independent => _python_version_independent}/meta.yaml (100%) diff --git a/conda_build/metadata.py b/conda_build/metadata.py index 9f3cd702f8..dfe87240bc 100644 --- a/conda_build/metadata.py +++ b/conda_build/metadata.py @@ -2327,7 +2327,7 @@ def copy(self: Self) -> MetaData: return new @property - def python_version_independent(self): + def python_version_independent(self) -> bool: return ( self.get_value("build/python_version_independent") or self.get_value("build/noarch") == "python" @@ -2336,7 +2336,7 @@ def python_version_independent(self): @python_version_independent.setter def python_version_independent(self, value: bool) -> None: - self.meta.setdefault("build", {})["python_version_independent"] = value + self.meta.setdefault("build", {})["python_version_independent"] = bool(value) @property def noarch(self): diff --git a/docs/source/resources/define-metadata.rst b/docs/source/resources/define-metadata.rst index 1b2ab6167f..7ca2138731 100644 --- a/docs/source/resources/define-metadata.rst +++ b/docs/source/resources/define-metadata.rst @@ -687,6 +687,61 @@ conda >=4.3 to install. it was built, which probably will result in incorrect/incomplete installation in other platforms. +Python version independent packages +----------------------------------- + +Allows you to specify "no python version" when building a Python +package thus making it compatible with a user specified range of Python +versions. Main use-case for this is to create ABI3 packages as specified +in [CEP20](https://github.com/conda/ceps/blob/main/cep-0020.md). + +ABI3 packages support building a native Python extension using a +specific Python version and running it against any later Python version. +ABI3 or stable ABI is supported by only CPython - the reference Python +implementation with the Global Interpreter Lock (GIL) enabled. Therefore +package builders who wishes to support the free-threaded python build +or another implementation like PyPy still has to build a conda package +specific to that ABI as they don't support ABI3. There are other +proposed standards like HPy and ABI4 (work-in-progress) that tries +to address all python implementations. + +conda-build can indicate that a conda package works for any python version +by adding + +.. code-block:: yaml + + build: + python_version_independent: true + +A package builder also has to indicate which standard is supported by +the package, i.e., for ABI3, + +.. code-block:: yaml + + requirements: + host: + - python-abi3 + - python + run: + - python + + +In order to support ABI3 with python 3.9 and onwards and +free-threaded builds you can do + +.. code-block:: yaml + build: + python_version_independent: true # [py == 39] + skip: true # [py > 39 and python.endswith("t")] + + requirements: + host: + - python-abi3 # [py == 39] + - python + run: + - python + + Include build recipe -------------------- diff --git a/tests/test-recipes/metadata/python_version_independent/meta.yaml b/tests/test-recipes/metadata/_python_version_independent/meta.yaml similarity index 100% rename from tests/test-recipes/metadata/python_version_independent/meta.yaml rename to tests/test-recipes/metadata/_python_version_independent/meta.yaml diff --git a/tests/test_api_build.py b/tests/test_api_build.py index dd647ac8d4..86897958e3 100644 --- a/tests/test_api_build.py +++ b/tests/test_api_build.py @@ -145,6 +145,20 @@ def test_recipe_builds( api.build(str(recipe), config=testing_config) +@pytest.mark.slow +@pytest.mark.serial +def test_python_version_independent( + testing_config, + monkeypatch: pytest.MonkeyPatch, +): + recipe = os.path.join(metadata_dir, "_python_version_independent") + testing_config.activate = True + monkeypatch.setenv("CONDA_TEST_VAR", "conda_test") + monkeypatch.setenv("CONDA_TEST_VAR_2", "conda_test_2") + output = api.build(str(recipe), config=testing_config)[0] + print(output) + + @pytest.mark.serial @pytest.mark.skipif( "CI" in os.environ and "GITHUB_WORKFLOW" in os.environ,