From 6231afc824612f1e3cfa4ee0650a880bf3f71e8d Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Thu, 30 Jun 2022 22:14:17 +0300 Subject: [PATCH 01/12] Disable `colorama` on Linux (fixes #493) [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/build/__main__.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index 6e2ebf0b..ad1f03e2 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -4,6 +4,7 @@ import argparse import contextlib import os +import platform import shutil import subprocess import sys @@ -60,12 +61,14 @@ def _showwarning( def _setup_cli() -> None: warnings.showwarning = _showwarning - try: - import colorama - except ModuleNotFoundError: - pass - else: - colorama.init() # fix colors on windows + if platform.system() == 'Windows': + # try to enable colors + try: + import colorama + + colorama.init() + except ModuleNotFoundError: + pass def _error(msg: str, code: int = 1) -> NoReturn: # pragma: no cover From 3c2e668c13069caab776665096a74c8d43fe188a Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 10:14:00 +0300 Subject: [PATCH 02/12] `colorama` is a required dependency on Windows --- src/build/__main__.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index ad1f03e2..c98d29d8 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -63,12 +63,9 @@ def _setup_cli() -> None: if platform.system() == 'Windows': # try to enable colors - try: - import colorama + import colorama - colorama.init() - except ModuleNotFoundError: - pass + colorama.init() def _error(msg: str, code: int = 1) -> NoReturn: # pragma: no cover From f75a29cdab102373018b752c5e9543a49022d19c Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 10:24:39 +0300 Subject: [PATCH 03/12] Prevent output buffering --- src/build/__main__.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index c98d29d8..5c1b75bb 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -47,6 +47,10 @@ def _init_colors() -> Dict[str, str]: _STYLES = _init_colors() +def cprint(msg): + print('{red}ERROR{reset} {}'.format(msg, **_STYLES), flush=True) + + def _showwarning( message: Union[Warning, str], category: Type[Warning], @@ -55,7 +59,7 @@ def _showwarning( file: Optional[TextIO] = None, line: Optional[str] = None, ) -> None: # pragma: no cover - print('{yellow}WARNING{reset} {}'.format(message, **_STYLES)) + cprint('{yellow}WARNING{reset} ' + message) def _setup_cli() -> None: @@ -75,20 +79,20 @@ def _error(msg: str, code: int = 1) -> NoReturn: # pragma: no cover :param msg: Error message :param code: Error code """ - print('{red}ERROR{reset} {}'.format(msg, **_STYLES)) + cprint('{red}ERROR{reset} ' + msg) raise SystemExit(code) class _ProjectBuilder(ProjectBuilder): @staticmethod def log(message: str) -> None: - print('{bold}* {}{reset}'.format(message, **_STYLES)) + cprint('{bold}* ' + message + '{reset}') class _IsolatedEnvBuilder(IsolatedEnvBuilder): @staticmethod def log(message: str) -> None: - print('{bold}* {}{reset}'.format(message, **_STYLES)) + cprint('{bold}* ' + message + '{reset}') def _format_dep_chain(dep_chain: Sequence[str]) -> str: @@ -119,7 +123,7 @@ def _build_in_current_env( missing = builder.check_dependencies(distribution) if missing: dependencies = ''.join('\n\t' + dep for deps in missing for dep in (deps[0], _format_dep_chain(deps[1:])) if dep) - print() + cprint('') _error(f'Missing dependencies:{dependencies}') return builder.build(distribution, outdir, config_settings or {}) @@ -147,7 +151,7 @@ def _handle_build_error() -> Iterator[None]: _error(str(e)) except BuildBackendException as e: if isinstance(e.exception, subprocess.CalledProcessError): - print() + cprint('') _error(str(e)) if e.exc_info: @@ -160,7 +164,7 @@ def _handle_build_error() -> Iterator[None]: tb = ''.join(tb_lines) else: tb = traceback.format_exc(-1) - print('\n{dim}{}{reset}\n'.format(tb.strip('\n'), **_STYLES)) + cprint('\n{dim}' + tb.strip('\n') + '{reset}\n') _error(str(e)) @@ -370,10 +374,10 @@ def main(cli_args: Sequence[str], prog: Optional[str] = None) -> None: # noqa: artifact_list = _natural_language_list( ['{underline}{}{reset}{bold}{green}'.format(artifact, **_STYLES) for artifact in built] ) - print('{bold}{green}Successfully built {}{reset}'.format(artifact_list, **_STYLES)) + cprint('{bold}{green}Successfully built ' + artifact_list + '{reset}') except Exception as e: # pragma: no cover tb = traceback.format_exc().strip('\n') - print('\n{dim}{}{reset}\n'.format(tb, **_STYLES)) + cprint('\n{dim}' + tb + '{reset}\n') _error(str(e)) From 753e8ffbac7800703acd5b3589237865df9e7d57 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 20:44:18 +0300 Subject: [PATCH 04/12] Fix `cprint()` --- src/build/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index 5c1b75bb..c5f0b52b 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -48,7 +48,7 @@ def _init_colors() -> Dict[str, str]: def cprint(msg): - print('{red}ERROR{reset} {}'.format(msg, **_STYLES), flush=True) + print(msg.format(**_STYLES), flush=True) def _showwarning( From c2ad8c11aeb01d714420fc000e49ad6d98bff19d Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 20:46:36 +0300 Subject: [PATCH 05/12] Make `cprint()` private --- src/build/__main__.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index c5f0b52b..f9bf0bf3 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -47,7 +47,7 @@ def _init_colors() -> Dict[str, str]: _STYLES = _init_colors() -def cprint(msg): +def _cprint(msg): print(msg.format(**_STYLES), flush=True) @@ -59,7 +59,7 @@ def _showwarning( file: Optional[TextIO] = None, line: Optional[str] = None, ) -> None: # pragma: no cover - cprint('{yellow}WARNING{reset} ' + message) + _cprint('{yellow}WARNING{reset} ' + message) def _setup_cli() -> None: @@ -79,20 +79,20 @@ def _error(msg: str, code: int = 1) -> NoReturn: # pragma: no cover :param msg: Error message :param code: Error code """ - cprint('{red}ERROR{reset} ' + msg) + _cprint('{red}ERROR{reset} ' + msg) raise SystemExit(code) class _ProjectBuilder(ProjectBuilder): @staticmethod def log(message: str) -> None: - cprint('{bold}* ' + message + '{reset}') + _cprint('{bold}* ' + message + '{reset}') class _IsolatedEnvBuilder(IsolatedEnvBuilder): @staticmethod def log(message: str) -> None: - cprint('{bold}* ' + message + '{reset}') + _cprint('{bold}* ' + message + '{reset}') def _format_dep_chain(dep_chain: Sequence[str]) -> str: @@ -123,7 +123,7 @@ def _build_in_current_env( missing = builder.check_dependencies(distribution) if missing: dependencies = ''.join('\n\t' + dep for deps in missing for dep in (deps[0], _format_dep_chain(deps[1:])) if dep) - cprint('') + _cprint('') _error(f'Missing dependencies:{dependencies}') return builder.build(distribution, outdir, config_settings or {}) @@ -151,7 +151,7 @@ def _handle_build_error() -> Iterator[None]: _error(str(e)) except BuildBackendException as e: if isinstance(e.exception, subprocess.CalledProcessError): - cprint('') + _cprint('') _error(str(e)) if e.exc_info: @@ -164,7 +164,7 @@ def _handle_build_error() -> Iterator[None]: tb = ''.join(tb_lines) else: tb = traceback.format_exc(-1) - cprint('\n{dim}' + tb.strip('\n') + '{reset}\n') + _cprint('\n{dim}' + tb.strip('\n') + '{reset}\n') _error(str(e)) @@ -374,10 +374,10 @@ def main(cli_args: Sequence[str], prog: Optional[str] = None) -> None: # noqa: artifact_list = _natural_language_list( ['{underline}{}{reset}{bold}{green}'.format(artifact, **_STYLES) for artifact in built] ) - cprint('{bold}{green}Successfully built ' + artifact_list + '{reset}') + _cprint('{bold}{green}Successfully built ' + artifact_list + '{reset}') except Exception as e: # pragma: no cover tb = traceback.format_exc().strip('\n') - cprint('\n{dim}' + tb + '{reset}\n') + _cprint('\n{dim}' + tb + '{reset}\n') _error(str(e)) From 97dd2aa40c3bfa2aea187966a041e24f4d7f4dc2 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 21:10:42 +0300 Subject: [PATCH 06/12] Get back `ModuleNotFoundError` --- src/build/__main__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index f9bf0bf3..27aea51c 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -66,10 +66,12 @@ def _setup_cli() -> None: warnings.showwarning = _showwarning if platform.system() == 'Windows': - # try to enable colors - import colorama + try: + import colorama - colorama.init() + colorama.init() + except ModuleNotFoundError: + pass def _error(msg: str, code: int = 1) -> NoReturn: # pragma: no cover From 31bc4f1263985658bd33b63dff242ab0fbd57a94 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 21:16:01 +0300 Subject: [PATCH 07/12] `cprint`: don't try to format message `{` are present in tracebacks leading to errors --- src/build/__main__.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index 27aea51c..8fe3c15d 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -47,8 +47,8 @@ def _init_colors() -> Dict[str, str]: _STYLES = _init_colors() -def _cprint(msg): - print(msg.format(**_STYLES), flush=True) +def _cprint(fmt='', msg=''): + print(fmt.format(msg, **_STYLES), flush=True) def _showwarning( @@ -59,7 +59,7 @@ def _showwarning( file: Optional[TextIO] = None, line: Optional[str] = None, ) -> None: # pragma: no cover - _cprint('{yellow}WARNING{reset} ' + message) + _cprint('{yellow}WARNING{reset} {}', message) def _setup_cli() -> None: @@ -81,20 +81,20 @@ def _error(msg: str, code: int = 1) -> NoReturn: # pragma: no cover :param msg: Error message :param code: Error code """ - _cprint('{red}ERROR{reset} ' + msg) + _cprint('{red}ERROR{reset} {}', msg) raise SystemExit(code) class _ProjectBuilder(ProjectBuilder): @staticmethod def log(message: str) -> None: - _cprint('{bold}* ' + message + '{reset}') + _cprint('{bold}* {}{reset}', message) class _IsolatedEnvBuilder(IsolatedEnvBuilder): @staticmethod def log(message: str) -> None: - _cprint('{bold}* ' + message + '{reset}') + _cprint('{bold}* {}{reset}', message) def _format_dep_chain(dep_chain: Sequence[str]) -> str: @@ -125,7 +125,7 @@ def _build_in_current_env( missing = builder.check_dependencies(distribution) if missing: dependencies = ''.join('\n\t' + dep for deps in missing for dep in (deps[0], _format_dep_chain(deps[1:])) if dep) - _cprint('') + _cprint() _error(f'Missing dependencies:{dependencies}') return builder.build(distribution, outdir, config_settings or {}) @@ -153,7 +153,7 @@ def _handle_build_error() -> Iterator[None]: _error(str(e)) except BuildBackendException as e: if isinstance(e.exception, subprocess.CalledProcessError): - _cprint('') + _cprint() _error(str(e)) if e.exc_info: @@ -166,7 +166,7 @@ def _handle_build_error() -> Iterator[None]: tb = ''.join(tb_lines) else: tb = traceback.format_exc(-1) - _cprint('\n{dim}' + tb.strip('\n') + '{reset}\n') + _cprint('\n{dim}{}{reset}\n', tb.strip('\n')) _error(str(e)) @@ -376,10 +376,10 @@ def main(cli_args: Sequence[str], prog: Optional[str] = None) -> None: # noqa: artifact_list = _natural_language_list( ['{underline}{}{reset}{bold}{green}'.format(artifact, **_STYLES) for artifact in built] ) - _cprint('{bold}{green}Successfully built ' + artifact_list + '{reset}') + _cprint('{bold}{green}Successfully built {}{reset}', artifact_list) except Exception as e: # pragma: no cover tb = traceback.format_exc().strip('\n') - _cprint('\n{dim}' + tb + '{reset}\n') + _cprint('\n{dim}{}{reset}\n', tb) _error(str(e)) From b589716c5c4d22388c624fca165d55e740fae721 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Fri, 1 Jul 2022 21:45:52 +0300 Subject: [PATCH 08/12] Add type annotation Fix type annotaion errors --- src/build/__main__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/build/__main__.py b/src/build/__main__.py index 8fe3c15d..67b21d12 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -47,7 +47,7 @@ def _init_colors() -> Dict[str, str]: _STYLES = _init_colors() -def _cprint(fmt='', msg=''): +def _cprint(fmt: str = '', msg: str = '') -> None: print(fmt.format(msg, **_STYLES), flush=True) @@ -59,7 +59,7 @@ def _showwarning( file: Optional[TextIO] = None, line: Optional[str] = None, ) -> None: # pragma: no cover - _cprint('{yellow}WARNING{reset} {}', message) + _cprint('{yellow}WARNING{reset} {}', str(message)) def _setup_cli() -> None: From ec960b29b7a4fe1447fc68b537c250b630e8121b Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 2 Jul 2022 09:45:34 -0400 Subject: [PATCH 09/12] tests: remove colorama on path test --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 5965ede9..a4a49714 100644 --- a/tox.ini +++ b/tox.ini @@ -48,7 +48,7 @@ description = verify build can run from source (bootstrap) setenv = PYTHONPATH = {toxinidir}/src commands = - python -E -m pip uninstall -y build + python -E -m pip uninstall -y build colorama pytest -ra {posargs:-n auto} [testenv:type] From c6dc62f3fdee01792e6531d614d079b7f38e7526 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 2 Jul 2022 10:34:19 -0400 Subject: [PATCH 10/12] tests: move path test up to normal tests Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 91cdd82a..69b6b565 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -91,6 +91,10 @@ jobs: if: matrix.tox-target == 'min' run: tox -e ${{env.BASE}}-${{ matrix.tox-target }} + - name: Run path test + if: matrix.tox-target == 'tox' && matrix.py == '3.10' + run: tox -e path + - name: Rename coverage report file if: matrix.tox-target == 'tox' run: mv ".tox/coverage.${BASE}.xml" .tox/coverage.xml @@ -106,10 +110,6 @@ jobs: env_vars: PYTHON name: ${{ matrix.py }} - ${{ matrix.os }} - - name: Run path test - if: matrix.tox-target == 'tox' && matrix.py == '3.10' - run: tox -e path - type: runs-on: ubuntu-latest env: From 4fa308645da47c105d934a3551fc30492b549674 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sun, 3 Jul 2022 13:48:05 -0400 Subject: [PATCH 11/12] tox: include coverage on path job Signed-off-by: Henry Schreiner --- tox.ini | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index a4a49714..612806b6 100644 --- a/tox.ini +++ b/tox.ini @@ -47,9 +47,8 @@ commands = description = verify build can run from source (bootstrap) setenv = PYTHONPATH = {toxinidir}/src -commands = +commands_pre = python -E -m pip uninstall -y build colorama - pytest -ra {posargs:-n auto} [testenv:type] description = run type check on code base @@ -102,7 +101,7 @@ commands = coverage xml -o {toxworkdir}/coverage.xml -i coverage html -d {toxworkdir}/htmlcov -i python -m diff_cover.diff_cover_tool --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml -depends = {py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39} +depends = {py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39, path} [flake8] max-line-length = 127 From a1ccc2724054376171c5074d5019bd18892c589e Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 17 Oct 2022 21:54:53 -0400 Subject: [PATCH 12/12] ci: combine coverage from the run Signed-off-by: Henry Schreiner --- .github/workflows/test.yml | 9 +++++---- tox.ini | 11 +++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 69b6b565..1dec8867 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,6 +51,8 @@ jobs: steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Setup python for test ${{ matrix.py }} uses: actions/setup-python@v4 @@ -95,10 +97,9 @@ jobs: if: matrix.tox-target == 'tox' && matrix.py == '3.10' run: tox -e path - - name: Rename coverage report file - if: matrix.tox-target == 'tox' - run: mv ".tox/coverage.${BASE}.xml" .tox/coverage.xml - shell: bash + - name: Combine coverage files + if: always() + run: tox -e coverage - uses: codecov/codecov-action@v3 if: always() diff --git a/tox.ini b/tox.ini index 612806b6..19cce036 100644 --- a/tox.ini +++ b/tox.ini @@ -47,6 +47,7 @@ commands = description = verify build can run from source (bootstrap) setenv = PYTHONPATH = {toxinidir}/src + COVERAGE_FILE = {toxworkdir}/.coverage.{envname} commands_pre = python -E -m pip uninstall -y build colorama @@ -59,9 +60,8 @@ commands = [testenv:{py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39}-min] description = check minimum versions required of all dependencies skip_install = true -commands = +commands_pre = pip install .[test] -c tests/constraints.txt - pytest -ra {posargs:-n auto} [testenv:docs] description = build documentations @@ -89,19 +89,18 @@ description = combine coverage from test environments passenv = DIFF_AGAINST setenv = - COVERAGE_FILE = {toxworkdir}/.coverage skip_install = true deps = - coverage>=5.1 + coverage[toml]>=5.1 diff_cover>=3 parallel_show_output = true commands = - coverage combine + coverage combine {toxworkdir} coverage report --skip-covered --show-missing -i coverage xml -o {toxworkdir}/coverage.xml -i coverage html -d {toxworkdir}/htmlcov -i python -m diff_cover.diff_cover_tool --compare-branch {env:DIFF_AGAINST:origin/main} {toxworkdir}/coverage.xml -depends = {py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39, path} +depends = {py311, py310, py39, py38, py37, py36, pypy37, pypy38, pypy39}{,-min}, path [flake8] max-line-length = 127