diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6058efe79..9fcb6042c 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -115,8 +115,8 @@ jobs: run: >- python -Im pip install -e . ${{ - matrix.no-extensions == '' - && '--config-settings=--build-c-extensions=' + matrix.no-extensions != '' + && '--config-settings=--pure-python=' || '' }} - name: Run unittests diff --git a/CHANGES/893.misc.rst b/CHANGES/893.misc.rst index 1bd014e5c..f6beb2cdc 100644 --- a/CHANGES/893.misc.rst +++ b/CHANGES/893.misc.rst @@ -2,15 +2,15 @@ Replaced the packaging is replaced from an old-fashioned :file:`setup.py` to an in-tree :pep:`517` build backend -- by :user:`webknjaz`. Whenever the end-users or downstream packagers need to build ``yarl`` from -source (a Git checkout or an sdist), they have to pass a ``config_settings`` -flag ``--build-c-extensions``. If this flag is not set, a pure-python -distribution will be built. +source (a Git checkout or an sdist), they may pass a ``config_settings`` +flag ``--pure-python``. If this flag is not set, a C-extension will be built +and included into the distribution. Here is how this can be done with ``pip``: .. code-block:: console - $ python -m pip install . --config-settings=--build-c-extensions= + $ python -m pip install . --config-settings=--pure-python= This will also work with ``-e | --editable``. @@ -18,7 +18,7 @@ The same can be achieved via ``pypa/build``: .. code-block:: console - $ python -m pip build --config-settings=--build-c-extensions= + $ python -m pip build --config-settings=--pure-python= Adding ``-w | --wheel`` can force ``pypa/build`` produce a wheel from source directly, as opposed to building an ``sdist`` and then building from it. diff --git a/packaging/pep517_backend/_backend.py b/packaging/pep517_backend/_backend.py index a62940c0e..3b95377ce 100644 --- a/packaging/pep517_backend/_backend.py +++ b/packaging/pep517_backend/_backend.py @@ -69,8 +69,8 @@ ) -BUILD_C_EXT_CONFIG_SETTING = '--build-c-extensions' -"""Config setting name toggle that is used to request C-ext in wheels.""" +PURE_PYTHON_CONFIG_SETTING = '--pure-python' +"""Config setting name toggle that is used to opt out of making C-exts.""" IS_PY3_12_PLUS = _python_version_tuple[:2] >= (3, 12) """A flag meaning that the current runtime is Python 3.12 or higher.""" @@ -78,6 +78,21 @@ IS_CPYTHON = _system_implementation.name == "cpython" """A flag meaning that the current interpreter implementation is CPython.""" +PURE_PYTHON_MODE_CLI_FALLBACK = bool(IS_CPYTHON) +"""A fallback for `--pure-python` is not set.""" + + +def _make_pure_python(config_settings: dict[str, str] | None = None) -> bool: + if ( + config_settings is None or + PURE_PYTHON_CONFIG_SETTING not in config_settings + ): + return PURE_PYTHON_MODE_CLI_FALLBACK + + truthy_values = {'', None, 'true', '1', 'on'} + + return config_settings[PURE_PYTHON_CONFIG_SETTING].lower() in truthy_values + def _get_local_cython_config(): """Grab optional build dependencies from pyproject.toml config. @@ -113,7 +128,7 @@ def _get_local_cython_config(): keep-going = false [tool.local.cythonize.kwargs] - # This section can contain args tha have values: + # This section can contain args that have values: # * exclude=PATTERN exclude certain file patterns from the compilation # * parallel=N run builds in N parallel jobs (default: calculated per system) exclude = "**.py" @@ -230,7 +245,7 @@ def _run_in_temporary_directory() -> t.Iterator[Path]: def maybe_prebuild_c_extensions( # noqa: WPS210 build_inplace: bool = False, config_settings: dict[str, str] | None = None, -) -> str: +) -> t.Generator[None, t.Any, t.Any]: """Pre-build C-extensions in a temporary directory, when needed. This context manager also patches metadata, setuptools and distutils. @@ -239,10 +254,9 @@ def maybe_prebuild_c_extensions( # noqa: WPS210 :param config_settings: :pep:`517` config settings mapping. """ - build_c_ext_requested = BUILD_C_EXT_CONFIG_SETTING in ( - config_settings or {} - ) - if not build_c_ext_requested: + is_pure_python_build = _make_pure_python(config_settings) + + if is_pure_python_build: print("*********************", file=_standard_error_stream) print("* Pure Python build *", file=_standard_error_stream) print("*********************", file=_standard_error_stream) @@ -255,8 +269,8 @@ def maybe_prebuild_c_extensions( # noqa: WPS210 if not IS_CPYTHON: _warn_that( 'Building C-extensions under the runtimes other than CPython is ' - 'unsupported and will likely fail. Consider not passing the ' - f'`{BUILD_C_EXT_CONFIG_SETTING !s}` PEP 517 config setting.', + 'unsupported and will likely fail. Consider passing the ' + f'`{PURE_PYTHON_CONFIG_SETTING !s}` PEP 517 config setting.', RuntimeWarning, stacklevel=999, ) @@ -288,9 +302,9 @@ def maybe_prebuild_c_extensions( # noqa: WPS210 def build_wheel( - wheel_directory: str, - config_settings: dict[str, str] | None = None, - metadata_directory: str | None = None, + wheel_directory: str, + config_settings: dict[str, str] | None = None, + metadata_directory: str | None = None, ) -> str: """Produce a built wheel. @@ -313,9 +327,9 @@ def build_wheel( def build_editable( - wheel_directory: str, - config_settings: dict[str, str] | None = None, - metadata_directory: str | None = None, + wheel_directory: str, + config_settings: dict[str, str] | None = None, + metadata_directory: str | None = None, ) -> str: """Produce a built wheel for editable installs. @@ -345,23 +359,21 @@ def get_requires_for_build_wheel( :param config_settings: :pep:`517` config settings mapping. """ - build_c_ext_requested = BUILD_C_EXT_CONFIG_SETTING in ( - config_settings or {} - ) + is_pure_python_build = _make_pure_python(config_settings) - if build_c_ext_requested and not IS_CPYTHON: + if not is_pure_python_build and not IS_CPYTHON: _warn_that( 'Building C-extensions under the runtimes other than CPython is ' - 'unsupported and will likely fail. Consider not passing the ' - f'`{BUILD_C_EXT_CONFIG_SETTING !s}` PEP 517 config setting.', + 'unsupported and will likely fail. Consider passing the ' + f'`{PURE_PYTHON_CONFIG_SETTING !s}` PEP 517 config setting.', RuntimeWarning, stacklevel=999, ) - c_ext_build_deps = [ + c_ext_build_deps = [] if is_pure_python_build else [ 'Cython >= 3.0.0b3' if IS_PY3_12_PLUS # Only Cython 3+ is compatible else 'Cython', - ] if build_c_ext_requested else [] + ] return _setuptools_get_requires_for_build_wheel( config_settings=config_settings,