diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index a802bd251..c20f44975 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -115,8 +115,8 @@ jobs: github.event_name == 'push' && contains(github.ref, 'refs/tags/') ) - && '0' - || '1' + && 'false' + || 'true' }} test: diff --git a/.github/workflows/reusable-build-wheel.yml b/.github/workflows/reusable-build-wheel.yml index caf38dde0..76bc22d0c 100644 --- a/.github/workflows/reusable-build-wheel.yml +++ b/.github/workflows/reusable-build-wheel.yml @@ -69,14 +69,9 @@ jobs: uses: pypa/cibuildwheel@v2.16.2 env: CIBW_ARCHS_MACOS: x86_64 arm64 universal2 - CIBW_ENVIRONMENT: >- # Cython line tracing for coverage collection - COLOR="yes" - FORCE_COLOR="1" - MYPY_FORCE_COLOR="1" - PIP_CONSTRAINT="requirements/cython.txt" - PRE_COMMIT_COLOR="always" - PY_COLORS="1" - YARL_CYTHON_TRACING="${{ inputs.cython-tracing }}" + CIBW_CONFIG_SETTINGS: >- # Cython line tracing for coverage collection + --pure-python=false + --with-cython-tracing=${{ inputs.cython-tracing }} - name: Upload built artifacts for testing and publishing uses: actions/upload-artifact@v3 diff --git a/CHANGES/962.contrib.rst b/CHANGES/962.contrib.rst new file mode 100644 index 000000000..9137904bd --- /dev/null +++ b/CHANGES/962.contrib.rst @@ -0,0 +1,16 @@ +It is now possible to request line tracing in Cython builds using the +``--with-cython-tracing`` :pep:`517` config setting +-- :user:`webknjaz`. + +This can be used in CI and development environment to measure coverage +on Cython modules, but is not normally useful to the end-users or +downstream packagers. + +Here's a usage example: + +.. code-block:: console + + $ python -Im pip install . --with-cython-tracing=true + +For editable installs, this setting is on by default. Otherwise, it's +off unless requested explicitly. diff --git a/packaging/pep517_backend/_backend.py b/packaging/pep517_backend/_backend.py index 405d3b8cd..322da6415 100644 --- a/packaging/pep517_backend/_backend.py +++ b/packaging/pep517_backend/_backend.py @@ -70,6 +70,12 @@ ) +CYTHON_TRACING_CONFIG_SETTING = '--with-cython-tracing' +"""Config setting name toggle to include line tracing to C-exts.""" + +CYTHON_TRACING_ENV_VAR = 'YARL_CYTHON_TRACING' +"""Environment variable name toggle used to opt out of making C-exts.""" + PURE_PYTHON_CONFIG_SETTING = '--pure-python' """Config setting name toggle that is used to opt out of making C-exts.""" @@ -86,19 +92,52 @@ """A fallback for `--pure-python` is not set.""" -def _make_pure_python(config_settings: dict[str, str] | None = None) -> bool: +def _is_truthy_setting_value(setting_value) -> bool: truthy_values = {'', None, 'true', '1', 'on'} + return setting_value.lower() in truthy_values + +def _get_setting_value( + config_settings: dict[str, str] | None = None, + config_setting_name: str | None = None, + env_var_name: str | None = None, + *, + default: bool = False, +) -> bool: user_provided_setting_sources = ( - (config_settings, PURE_PYTHON_CONFIG_SETTING, (KeyError, TypeError)), - (os.environ, PURE_PYTHON_ENV_VAR, KeyError), + (config_settings, config_setting_name, (KeyError, TypeError)), + (os.environ, env_var_name, KeyError), ) for src_mapping, src_key, lookup_errors in user_provided_setting_sources: + if src_key is None: + continue + with suppress(lookup_errors): # type: ignore[arg-type] - candidate_val = src_mapping[src_key].lower() # type: ignore[index] - return candidate_val in truthy_values + return _is_truthy_setting_value(src_mapping[src_key]) # type: ignore[index] + + return default + - return PURE_PYTHON_MODE_CLI_FALLBACK +def _make_pure_python(config_settings: dict[str, str] | None = None) -> bool: + return _get_setting_value( + config_settings, + PURE_PYTHON_CONFIG_SETTING, + PURE_PYTHON_ENV_VAR, + default=PURE_PYTHON_MODE_CLI_FALLBACK, + ) + + +def _include_cython_line_tracing( + config_settings: dict[str, str] | None = None, + *, + default=False, +) -> bool: + return _get_setting_value( + config_settings, + CYTHON_TRACING_CONFIG_SETTING, + CYTHON_TRACING_ENV_VAR, + default=default, + ) def _get_local_cython_config(): @@ -216,7 +255,7 @@ def _get_sanitized_long_description(self): @contextmanager -def patched_env(env): +def patched_env(env: dict[str, str], cython_line_tracing_requested: bool): """Temporary set given env vars. :param env: tmp env vars to set @@ -227,7 +266,8 @@ def patched_env(env): orig_env = os.environ.copy() expanded_env = {name: expandvars(var_val) for name, var_val in env.items()} os.environ.update(expanded_env) - if os.getenv('YARL_CYTHON_TRACING') == '1': + + if cython_line_tracing_requested: os.environ['CFLAGS'] = ' '.join(( os.getenv('CFLAGS', ''), '-DCYTHON_TRACE_NOGIL=1', # Implies CYTHON_TRACE=1 @@ -248,6 +288,7 @@ def _run_in_temporary_directory() -> t.Iterator[Path]: @contextmanager def maybe_prebuild_c_extensions( # noqa: WPS210 + line_trace_cython_when_unset: bool = False, build_inplace: bool = False, config_settings: dict[str, str] | None = None, ) -> t.Generator[None, t.Any, t.Any]: @@ -259,12 +300,27 @@ def maybe_prebuild_c_extensions( # noqa: WPS210 :param config_settings: :pep:`517` config settings mapping. """ + cython_line_tracing_requested = _include_cython_line_tracing( + config_settings, + default=line_trace_cython_when_unset, + ) 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) + + if cython_line_tracing_requested: + _warn_that( + f'The `{CYTHON_TRACING_CONFIG_SETTING !s}` setting requesting ' + 'Cython line tracing is set, but building C-extensions is not. ' + 'This option will not have any effect for in the pure-python ' + 'build mode.', + RuntimeWarning, + stacklevel=999, + ) + yield return @@ -299,7 +355,7 @@ def maybe_prebuild_c_extensions( # noqa: WPS210 cli_kwargs = get_cli_kwargs_from_config(config['kwargs']) cythonize_args = cli_flags + [py_ver_arg] + cli_kwargs + config['src'] - with patched_env(config['env']): + with patched_env(config['env'], cython_line_tracing_requested): _cythonize_cli_cmd(cythonize_args) with patched_distutils_cmd_install(): with patched_dist_has_ext_modules(): @@ -322,6 +378,7 @@ def build_wheel( """ with maybe_prebuild_c_extensions( + line_trace_cython_when_unset=False, build_inplace=False, config_settings=config_settings, ): @@ -348,8 +405,9 @@ def build_editable( """ with maybe_prebuild_c_extensions( - build_inplace=True, - config_settings=config_settings, + line_trace_cython_when_unset=True, + build_inplace=True, + config_settings=config_settings, ): return _setuptools_build_editable( wheel_directory=wheel_directory,