Skip to content

Conversation

@Sachaa-Thanasius
Copy link
Contributor

@Sachaa-Thanasius Sachaa-Thanasius commented Mar 11, 2025

Existing subclasses of CCompiler override this method to return a string or a list of strings. For example, those for cygwin and unix (see below).

def runtime_library_dir_option(self, dir):
# cygwin doesn't support rpath. While in theory we could error
# out like MSVC does, code might expect it to work like on Unix, so
# just warn and hope for the best.
self.warn(_runtime_library_dirs_msg)
return []

def runtime_library_dir_option(self, dir: str) -> str | list[str]:

Altering the return annotation of the base class's method should make it more compatible and accurate with respect to those subclasses (and possibly other, third-party ones).

Subclasses of `CCompiler`, specifically those in `unix` and `cygwin`, can return lists of strings in addition to strings. Whether this should be loosened further, e.g. `str | Sequence[str]`, is up for debate, but at least adding `list[str]` makes this more accurate.
@Sachaa-Thanasius Sachaa-Thanasius changed the title Expand return type of CCompiler.runtime_library_dir_option(). Widen return type of CCompiler.runtime_library_dir_option(). Mar 11, 2025
@Avasam
Copy link
Contributor

Avasam commented Mar 11, 2025

This change is correct, and mypy currently even catches it in my editor, wonder why not on CI...
image

Union return types have a bit of a gotcha, but I think in this case it'll be fine (both str and list[str] are Sequence[str], so they're pretty close)
https://typing.python.org/en/latest/guides/writing_stubs.html#functions-and-methods

Avoid union return types. See python/mypy#1693

@Sachaa-Thanasius
Copy link
Contributor Author

Fair, Union return types aren't the greatest, though I think it's unavoidable in this case since it's the reality of the return type in practice. Maybe that can be changed in the future, but that's probably out of the scope of this PR.

@Sachaa-Thanasius
Copy link
Contributor Author

Sachaa-Thanasius commented Mar 12, 2025

As for why this isn't caught in CI, well, it looks like mypy isn't run in CI. tox is installed and run, and tox in turn installs pytest-mypy, but pytest-mypy doesn't do anything because --mypy isn't provided as a positional argument for tox to pass along to pytest.

If I test this locally with tox run -- --mypy, I get the expected many mypy errors:

Output
PS C:\Users\thanos\Projects\personal\distutils> tox run -- --mypy
.pkg: _optional_hooks> python c:\Users\thanos\Projects\personal\distutils\.venv\Lib\site-packages\pyproject_api\_backend.py True setuptools.build_meta
.pkg: get_requires_for_build_editable> python c:\Users\thanos\Projects\personal\distutils\.venv\Lib\site-packages\pyproject_api\_backend.py True setuptools.build_meta
.pkg: build_editable> python c:\Users\thanos\Projects\personal\distutils\.venv\Lib\site-packages\pyproject_api\_backend.py True setuptools.build_meta
py: install_package_deps> python -I -m pip install jaraco.collections jaraco.functools>=4
py: install_package> python -I -m pip install --force-reinstall --no-deps C:\Users\thanos\Projects\personal\distutils\.tox\.tmp\package\16\distutils-0.1.dev4426+ga3d37a2-0.editable-py3-none-any.whl
py: commands[0]> pytest --mypy
=============================================================================== test session starts ===============================================================================
platform win32 -- Python 3.11.9, pytest-8.0.2, pluggy-1.5.0
cachedir: .tox\py\.pytest_cache
rootdir: C:\Users\thanos\Projects\personal\distutils
configfile: pytest.ini
plugins: pyfakefs-5.7.4, checkdocs-2.13.0, cov-6.0.0, enabler-3.3.0, mypy-0.10.3, ruff-0.4.1
collected 560 items

conftest.py ...F                                                                                                                                                             [  0%]
distutils\__init__.py ...                                                                                                                                                    [  1%]
distutils\_log.py ...                                                                                                                                                        [  1%]
distutils\_macos_compat.py ...                                                                                                                                               [  2%]
distutils\_modified.py ..F                                                                                                                                                   [  2%]
distutils\_msvccompiler.py ...                                                                                                                                               [  3%]
distutils\archive_util.py ..F                                                                                                                                                [  3%]
distutils\ccompiler.py ...                                                                                                                                                   [  4%]
distutils\cmd.py ..F                                                                                                                                                         [  5%]
distutils\command\__init__.py ...                                                                                                                                            [  5%]
distutils\command\_framework_compat.py ...                                                                                                                                   [  6%]
distutils\command\bdist.py ..F                                                                                                                                               [  6%]
distutils\command\bdist_dumb.py ...                                                                                                                                          [  7%]
distutils\command\bdist_rpm.py ..F                                                                                                                                           [  7%]
distutils\command\build.py ...                                                                                                                                               [  8%]
distutils\command\build_clib.py ..F                                                                                                                                          [  8%]
distutils\command\build_ext.py ..F                                                                                                                                           [  9%]
distutils\command\build_py.py ..F                                                                                                                                            [  9%]
distutils\command\build_scripts.py ...                                                                                                                                       [ 10%]
distutils\command\check.py ..F                                                                                                                                               [ 10%]
distutils\command\clean.py ...                                                                                                                                               [ 11%]
distutils\command\config.py ...                                                                                                                                              [ 11%]
distutils\command\install.py ..F                                                                                                                                             [ 12%]
distutils\command\install_data.py ...                                                                                                                                        [ 13%]
distutils\command\install_egg_info.py ...                                                                                                                                    [ 13%]
distutils\command\install_headers.py ...                                                                                                                                     [ 14%]
distutils\command\install_lib.py ..F                                                                                                                                         [ 14%]
distutils\command\install_scripts.py ...                                                                                                                                     [ 15%]
distutils\command\sdist.py ..F.                                                                                                                                              [ 15%]
distutils\compat\__init__.py ...                                                                                                                                             [ 16%]
distutils\compat\py39.py ...                                                                                                                                                 [ 16%]
distutils\compilers\C\base.py ..F.                                                                                                                                           [ 17%]
distutils\compilers\C\cygwin.py ...                                                                                                                                          [ 18%]
distutils\compilers\C\errors.py ...                                                                                                                                          [ 18%]
distutils\compilers\C\msvc.py ....                                                                                                                                           [ 19%]
distutils\compilers\C\tests\test_base.py ......                                                                                                                              [ 20%]
distutils\compilers\C\tests\test_cygwin.py ...ss..s                                                                                                                          [ 21%]
distutils\compilers\C\tests\test_mingw.py ...ssssF                                                                                                                           [ 23%]
distutils\compilers\C\tests\test_msvc.py ............                                                                                                                        [ 25%]
distutils\compilers\C\tests\test_unix.py .........                                                                                                                           [ 27%]
distutils\compilers\C\unix.py ..F...                                                                                                                                         [ 28%]
distutils\compilers\C\zos.py ...                                                                                                                                             [ 28%]
distutils\core.py ...                                                                                                                                                        [ 29%]
distutils\cygwinccompiler.py ...                                                                                                                                             [ 29%]
distutils\debug.py ...                                                                                                                                                       [ 30%]
distutils\dep_util.py ...                                                                                                                                                    [ 30%]
distutils\dir_util.py ..F                                                                                                                                                    [ 31%]
distutils\dist.py ..F.                                                                                                                                                       [ 32%]
distutils\errors.py ...                                                                                                                                                      [ 32%]
distutils\extension.py ..F                                                                                                                                                   [ 33%]
distutils\fancy_getopt.py ..F                                                                                                                                                [ 33%]
distutils\file_util.py ...                                                                                                                                                   [ 34%]
distutils\filelist.py ..F                                                                                                                                                    [ 34%]
distutils\log.py ...                                                                                                                                                         [ 35%]
distutils\spawn.py ..F                                                                                                                                                       [ 35%]
distutils\sysconfig.py ..F.                                                                                                                                                  [ 36%]
distutils\tests\__init__.py ..F                                                                                                                                              [ 37%]
distutils\tests\compat\__init__.py ...                                                                                                                                       [ 37%]
distutils\tests\compat\py39.py ..F                                                                                                                                           [ 38%]
distutils\tests\support.py ...                                                                                                                                               [ 38%]
distutils\tests\test_archive_util.py ..F                                                                                                                                     [ 39%]
distutils\tests\test_bdist.py .....                                                                                                                                          [ 40%]
distutils\tests\test_bdist_dumb.py ....                                                                                                                                      [ 40%]
distutils\tests\test_bdist_rpm.py ..Fss                                                                                                                                      [ 41%]
distutils\tests\test_build.py ....                                                                                                                                           [ 42%]
distutils\tests\test_build_clib.py .......s                                                                                                                                  [ 43%]
distutils\tests\test_build_ext.py ..F............sss............sss                                                                                                          [ 49%]
distutils\tests\test_build_py.py ..F.......                                                                                                                                  [ 51%]
distutils\tests\test_build_scripts.py ..F...                                                                                                                                 [ 52%]
distutils\tests\test_check.py ..F......                                                                                                                                      [ 54%]
distutils\tests\test_clean.py ....                                                                                                                                           [ 55%]
distutils\tests\test_cmd.py ..........                                                                                                                                       [ 56%]
distutils\tests\test_config_cmd.py ....s..                                                                                                                                   [ 58%]
distutils\tests\test_core.py ..........                                                                                                                                      [ 59%]
distutils\tests\test_dir_util.py ..F.s......                                                                                                                                 [ 61%] 
distutils\tests\test_dist.py ..F..s.......s.......................                                                                                                           [ 68%] 
distutils\tests\test_extension.py ..F..                                                                                                                                      [ 69%] 
distutils\tests\test_file_util.py ..F.....                                                                                                                                   [ 70%] 
distutils\tests\test_filelist.py ..F.........s..s                                                                                                                            [ 73%] 
distutils\tests\test_install.py ...x......                                                                                                                                   [ 75%] 
distutils\tests\test_install_data.py ....                                                                                                                                    [ 76%] 
distutils\tests\test_install_headers.py ....                                                                                                                                 [ 76%] 
distutils\tests\test_install_lib.py ........                                                                                                                                 [ 78%] 
distutils\tests\test_install_scripts.py .....                                                                                                                                [ 79%] 
distutils\tests\test_log.py ....                                                                                                                                             [ 79%] 
distutils\tests\test_modified.py ...........                                                                                                                                 [ 81%] 
distutils\tests\test_sdist.py ..F.s...........s                                                                                                                              [ 84%] 
distutils\tests\test_spawn.py ..F...                                                                                                                                         [ 85%] 
distutils\tests\test_sysconfig.py ..F.s..xs.s........s.                                                                                                                      [ 89%]
distutils\tests\test_text_file.py ..F.                                                                                                                                       [ 90%]
distutils\tests\test_util.py ........s........                                                                                                                               [ 93%]
distutils\tests\test_version.py ......                                                                                                                                       [ 94%]
distutils\tests\test_versionpredicate.py ...                                                                                                                                 [ 95%]
distutils\tests\unix_compat.py ..F                                                                                                                                           [ 95%]
distutils\text_file.py ...                                                                                                                                                   [ 96%]
distutils\unixccompiler.py ...                                                                                                                                               [ 96%]
distutils\util.py ..F.                                                                                                                                                       [ 97%]
distutils\version.py ...                                                                                                                                                     [ 97%]
distutils\versionpredicate.py .....                                                                                                                                          [ 98%]
distutils\zosccompiler.py ...                                                                                                                                                [ 99%]
docs\conf.py ...                                                                                                                                                             [ 99%]
. .                                                                                                                                                                          [100%]

==================================================================================== FAILURES ===================================================================================== 
__________________________________________________________________________________ test session ___________________________________________________________________________________ 
mypy exited with status 1.
_____________________________________________________________________________ distutils\_modified.py ______________________________________________________________________________ 
10: error: Module "jaraco.functools" has no attribute "splat"  [attr-defined]
61: error: Incompatible return value type (got "tuple[list[Any], ...]", expected "tuple[list[_SourcesT], list[_TargetsT]]")  [return-value]
95: error: Value of type variable "_SourcesT" of "newer_pairwise" cannot be "Iterable[str | bytes | PathLike[str] | PathLike[bytes]]"  [type-var]
____________________________________________________________________________ distutils\archive_util.py ____________________________________________________________________________ 
14: error: Incompatible types in assignment (expression has type "None", variable has type Module)  [assignment]
23: error: Module "pwd" has no attribute "getpwnam"  [attr-defined]
28: error: Module "grp" has no attribute "getgrnam"  [attr-defined]
97: error: Argument 1 to "get" of "dict" has incompatible type "Literal['gzip', 'bzip2', 'xz'] | None"; expected "str"  [arg-type]
119: error: No overload variant of "open" matches argument types "str", "str"  [call-overload]
119: note: Possible overload variants:
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None = ..., mode: Literal['r', 'r:*', 'r:', 'r:gz', 'r:bz2', 'r:xz'] = ..., fileobj: IO[bytes] | None 
= ..., bufsize: int = ..., *, format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None, mode: Literal['x', 'x:', 'a', 'a:', 'w', 'w:', 'w:tar'], fileobj: _Fileobj | None = ..., bufsize: int = ..., *, format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: 
str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None = ..., *, mode: Literal['x', 'x:', 'a', 'a:', 'w', 'w:', 'w:tar'], fileobj: _Fileobj | None = ..., bufsize: int = ..., format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None, mode: Literal['x:gz', 'x:bz2', 'w:gz', 'w:bz2'], fileobj: _Fileobj | None = ..., bufsize: int = 
..., *, format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., compresslevel: int = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None = ..., *, mode: Literal['x:gz', 'x:bz2', 'w:gz', 'w:bz2'], fileobj: _Fileobj | None = ..., bufsize: int = ..., format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., compresslevel: int = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None, mode: Literal['x:xz', 'w:xz'], fileobj: _Fileobj | None = ..., bufsize: int = ..., *, format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | None = ..., *, mode: Literal['x:xz', 'w:xz'], fileobj: _Fileobj | None = ..., bufsize: int = ..., format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | Buffer | None = ..., *, mode: Literal['r|*', 'r|', 'r|gz', 'r|bz2', 'r|xz'], fileobj: IO[bytes] | None = ..., bufsize: int = ..., format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., preset: int | None = ...) -> TarFile
119: note:     def open(name: str | bytes | PathLike[str] | PathLike[bytes] | Buffer | None = ..., *, mode: Literal['w|', 'w|gz', 'w|bz2', 'w|xz'], fileobj: IO[bytes] | None = ..., bufsize: int = ..., format: int | None = ..., tarinfo: type[TarInfo] | None = ..., dereference: bool | None = ..., ignore_zeros: bool | None = ..., encoding: str | None = ..., errors: str = ..., pax_headers: Mapping[str, str] | None = ..., debug: int | None = ..., errorlevel: int | None = ..., preset: int | None = ...) -> TarFile
281: error: No overload variant of "update" of "MutableMapping" matches argument type "object"  [call-overload]
281: note: Possible overload variants:
281: note:     def update(self, SupportsKeysAndGetItem[str, bool], /, **kwargs: bool) -> None
281: note:     def update(self, Iterable[tuple[str, bool]], /, **kwargs: bool) -> None
281: note:     def update(self, **kwargs: bool) -> None
284: error: Incompatible types in assignment (expression has type "str | None", target has type "bool")  [assignment]
285: error: Incompatible types in assignment (expression has type "str | None", target has type "bool")  [assignment]
288: error: Cannot call function of unknown type  [operator]
________________________________________________________________________________ distutils\cmd.py _________________________________________________________________________________ 
333: error: No overload variant of "get_command_obj" of "Distribution" matches argument types "str", "bool"  [call-overload]
333: note: Possible overload variants:
333: note:     def get_command_obj(self, command: str, create: Literal[True] = ...) -> Command
333: note:     def get_command_obj(self, command: str, create: Literal[False]) -> Command | None
476: error: Argument 1 to "spawn" has incompatible type "MutableSequence[str]"; expected "MutableSequence[bytes | str | PathLike[str]]"  [arg-type]
507: error: Not all union combinations were tried because there are too many unions  [misc]
508: error: Argument 1 to "make_archive" has incompatible type "str | PathLike[str]"; expected "str"  [arg-type]
536: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
545: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
___________________________________________________________________________ distutils\command\bdist.py ____________________________________________________________________________
156: error: "Command" has no attribute "format"  [attr-defined]
160: error: "Command" has no attribute "owner"  [attr-defined]
161: error: "Command" has no attribute "group"  [attr-defined]
166: error: "Command" has no attribute "keep_temp"  [attr-defined]
_________________________________________________________________________ distutils\command\bdist_rpm.py __________________________________________________________________________ 
312: error: "Command" has no attribute "formats"  [attr-defined]
314: error: "Command" has no attribute "formats"  [attr-defined]
388: error: Argument 2 to "join" has incompatible type "str | None"; expected "str"  [arg-type]
391: error: Argument 2 to "join" has incompatible type "str | None"; expected "str"  [arg-type]
_________________________________________________________________________ distutils\command\build_clib.py _________________________________________________________________________ 
92: error: Argument "force" to "new_compiler" has incompatible type "None"; expected "bool"  [arg-type]
_________________________________________________________________________ distutils\command\build_ext.py __________________________________________________________________________ 
286: error: Argument 1 to "join" has incompatible type "str | None"; expected "str"  [arg-type]
287: error: Argument 1 to "join" has incompatible type "str | None"; expected "str"  [arg-type]
330: error: Argument "force" to "new_compiler" has incompatible type "None"; expected "bool"  [arg-type]
337: error: "Compiler" has no attribute "initialize"  [attr-defined]
727: error: Unsupported operand types for + ("str" and "int")  [operator]
727: error: Unsupported operand types for + ("str" and "None")  [operator]
727: note: Right operand is of type "int | str | None"
810: error: Unsupported operand types for + ("str" and "int")  [operator]
810: error: Unsupported operand types for + ("str" and "None")  [operator]
810: note: Right operand is of type "int | str | None"
__________________________________________________________________________ distutils\command\build_py.py __________________________________________________________________________ 
363: error: "None" has no attribute "__iter__" (not iterable)  [attr-defined]
398: error: Argument "force" to "byte_compile" has incompatible type "None"; expected "bool"  [arg-type]
404: error: Argument "force" to "byte_compile" has incompatible type "None"; expected "bool"  [arg-type]
___________________________________________________________________________ distutils\command\check.py ____________________________________________________________________________ 
13: error: Library stubs not installed for "docutils.frontend"  [import-untyped]
13: error: Library stubs not installed for "docutils"  [import-untyped]
14: error: Library stubs not installed for "docutils.nodes"  [import-untyped]
15: error: Library stubs not installed for "docutils.parsers.rst"  [import-untyped]
15: note: Hint: "python3 -m pip install types-docutils"
15: note: (or run "mypy --install-types" to install all missing stub packages)
15: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
15: error: Library stubs not installed for "docutils.parsers"  [import-untyped]
16: error: Library stubs not installed for "docutils.utils"  [import-untyped]
__________________________________________________________________________ distutils\command\install.py ___________________________________________________________________________ 
306: error: Incompatible types in assignment (expression has type "bool", variable has type "None")  [assignment]
404: error: Module has no attribute "abiflags"  [attr-defined]
497: error: Argument 1 to "join" has incompatible type "str | None"; expected "str"  [arg-type]
559: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
562: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
581: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
582: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
590: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
593: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
599: error: Incompatible types in assignment (expression has type "str", variable has type "None")  [assignment]
________________________________________________________________________ distutils\command\install_lib.py _________________________________________________________________________ 
123: error: Return value expected  [return-value]
143: error: Argument "force" to "byte_compile" has incompatible type "None"; expected "bool"  [arg-type]
151: error: Argument "force" to "byte_compile" has incompatible type "None"; expected "bool"  [arg-type]
___________________________________________________________________________ distutils\command\sdist.py ____________________________________________________________________________ 
388: error: No overload variant of "exclude_pattern" of "FileList" matches argument types "None", "Any"  [call-overload]
388: note: Possible overload variants:
388: note:     def exclude_pattern(self, pattern: str, anchor: bool = ..., prefix: str | None = ..., is_regex: Literal[False] = ...) -> bool
388: note:     def exclude_pattern(self, pattern: str | Pattern[str], anchor: bool = ..., prefix: str | None = ..., *, is_regex: Literal[True]) -> bool
388: note:     def exclude_pattern(self, pattern: str | Pattern[str], anchor: bool, prefix: str | None, is_regex: Literal[True]) -> bool
389: error: No overload variant of "exclude_pattern" of "FileList" matches argument types "None", "str"  [call-overload]
389: note: Possible overload variants:
389: note:     def exclude_pattern(self, pattern: str, anchor: bool = ..., prefix: str | None = ..., is_regex: Literal[False] = ...) -> bool
389: note:     def exclude_pattern(self, pattern: str | Pattern[str], anchor: bool = ..., prefix: str | None = ..., *, is_regex: Literal[True]) -> bool
389: note:     def exclude_pattern(self, pattern: str | Pattern[str], anchor: bool, prefix: str | None, is_regex: Literal[True]) -> bool
437: error: Argument 1 to "filterfalse" has incompatible type "Callable[[str], bool]"; expected "Callable[[str | None], object] | None"  [arg-type]
__________________________________________________________________________ distutils\compilers\C\base.py __________________________________________________________________________ 
123: error: Need type annotation for "include_dirs" (hint: "include_dirs: list[<type>] = ...")  [var-annotated]
128: error: Need type annotation for "library_dirs" (hint: "library_dirs: list[<type>] = ...")  [var-annotated]
151: error: Attribute "include_dirs" already defined on line 123  [no-redef]
158: error: Attribute "library_dirs" already defined on line 128  [no-redef]
446: error: Incompatible return value type (got "tuple[str | None, list[tuple[str] | tuple[str, str | None]], list[str]]", expected "tuple[str, list[tuple[str] | tuple[str, str | None]], list[str]]")  [return-value]
481: error: Incompatible return value type (got "tuple[list[str], str | None]", expected "tuple[list[str], str]")  [return-value]
550: error: Argument 1 to "index" of "list" has incompatible type "str | None"; expected "str"  [arg-type]
1081: error: Unsupported operand types for + ("str" and "None")  [operator]
1081: error: Unsupported left operand type for + ("PathLike[str]")  [operator]
1081: note: Both left and right operands are unions
1106: error: Unsupported left operand type for + ("PathLike[str]")  [operator]
1106: note: Left operand is of type "str | PathLike[str]"
__________________________________________________________ TestMinGW32Compiler.test_customize_compiler_with_msvc_python ___________________________________________________________ 

self = <distutils.compilers.C.tests.test_mingw.TestMinGW32Compiler object at 0x000001897C629B90>

    @pytest.mark.skipif('sys.platform == "cygwin"')
    def test_customize_compiler_with_msvc_python(self):
        # In case we have an MSVC Python build, but still want to use
        # MinGW32Compiler, then customize_compiler() shouldn't fail at least.
        # https://github.com/pypa/setuptools/issues/4456
>       compiler = cygwin.MinGW32Compiler()

distutils\compilers\C\tests\test_mingw.py:47:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
distutils\compilers\C\cygwin.py:254: in __init__
    if is_cygwincc(self.cc):
distutils\compilers\C\cygwin.py:332: in is_cygwincc
    out_string = check_output(shlex.split(cc) + ['-dumpmachine'])
..\..\..\AppData\Local\Programs\Python\Python311\Lib\subprocess.py:466: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
..\..\..\AppData\Local\Programs\Python\Python311\Lib\subprocess.py:548: in run
    with Popen(*popenargs, **kwargs) as process:
..\..\..\AppData\Local\Programs\Python\Python311\Lib\subprocess.py:1026: in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Popen: returncode: None args: ['gcc', '-dumpmachine']>, args = 'gcc -dumpmachine', executable = None, preexec_fn = None, close_fds = False, pass_fds = (), cwd = None       
env = None, startupinfo = <subprocess.STARTUPINFO object at 0x000001897F2BCD50>, creationflags = 0, shell = False, p2cread = Handle(792), p2cwrite = -1, c2pread = 12
c2pwrite = Handle(808), errread = -1, errwrite = Handle(804), unused_restore_signals = True, unused_gid = None, unused_gids = None, unused_uid = None, unused_umask = -1
unused_start_new_session = False, unused_process_group = -1

    def _execute_child(self, args, executable, preexec_fn, close_fds,
                       pass_fds, cwd, env,
                       startupinfo, creationflags, shell,
                       p2cread, p2cwrite,
                       c2pread, c2pwrite,
                       errread, errwrite,
                       unused_restore_signals,
                       unused_gid, unused_gids, unused_uid,
                       unused_umask,
                       unused_start_new_session, unused_process_group):
        """Execute program (MS Windows version)"""

        assert not pass_fds, "pass_fds not supported on Windows."

        if isinstance(args, str):
            pass
        elif isinstance(args, bytes):
            if shell:
                raise TypeError('bytes args is not allowed on Windows')
            args = list2cmdline([args])
        elif isinstance(args, os.PathLike):
            if shell:
                raise TypeError('path-like args is not allowed when '
                                'shell is true')
            args = list2cmdline([args])
        else:
            args = list2cmdline(args)

        if executable is not None:
            executable = os.fsdecode(executable)

        # Process startup details
        if startupinfo is None:
            startupinfo = STARTUPINFO()
        else:
            # bpo-34044: Copy STARTUPINFO since it is modified above,
            # so the caller can reuse it multiple times.
            startupinfo = startupinfo.copy()

        use_std_handles = -1 not in (p2cread, c2pwrite, errwrite)
        if use_std_handles:
            startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES
            startupinfo.hStdInput = p2cread
            startupinfo.hStdOutput = c2pwrite
            startupinfo.hStdError = errwrite

        attribute_list = startupinfo.lpAttributeList
        have_handle_list = bool(attribute_list and
                                "handle_list" in attribute_list and
                                attribute_list["handle_list"])

        # If we were given an handle_list or need to create one
        if have_handle_list or (use_std_handles and close_fds):
            if attribute_list is None:
                attribute_list = startupinfo.lpAttributeList = {}
            handle_list = attribute_list["handle_list"] = \
                list(attribute_list.get("handle_list", []))

            if use_std_handles:
                handle_list += [int(p2cread), int(c2pwrite), int(errwrite)]

            handle_list[:] = self._filter_handle_list(handle_list)

            if handle_list:
                if not close_fds:
                    warnings.warn("startupinfo.lpAttributeList['handle_list'] "
                                  "overriding close_fds", RuntimeWarning)

                # When using the handle_list we always request to inherit
                # handles but the only handles that will be inherited are
                # the ones in the handle_list
                close_fds = False

        if shell:
            startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = _winapi.SW_HIDE
            if not executable:
                # gh-101283: without a fully-qualified path, before Windows
                # checks the system directories, it first looks in the
                # application directory, and also the current directory if
                # NeedCurrentDirectoryForExePathW(ExeName) is true, so try
                # to avoid executing unqualified "cmd.exe".
                comspec = os.environ.get('ComSpec')
                if not comspec:
                    system_root = os.environ.get('SystemRoot', '')
                    comspec = os.path.join(system_root, 'System32', 'cmd.exe')
                    if not os.path.isabs(comspec):
                        raise FileNotFoundError('shell not found: neither %ComSpec% nor %SystemRoot% is set')
                if os.path.isabs(comspec):
                    executable = comspec
            else:
                comspec = executable

            args = '{} /c "{}"'.format (comspec, args)

        if cwd is not None:
            cwd = os.fsdecode(cwd)

        sys.audit("subprocess.Popen", executable, args, cwd, env)

        # Start the process
        try:
>           hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                                     # no special security
                                     None, None,
                                     int(not close_fds),
                                     creationflags,
                                     env,
                                     cwd,
                                     startupinfo)
E                                    FileNotFoundError: [WinError 2] The system cannot find the file specified

..\..\..\AppData\Local\Programs\Python\Python311\Lib\subprocess.py:1538: FileNotFoundError
__________________________________________________________________________ distutils\compilers\C\unix.py __________________________________________________________________________ 
173: error: "Compiler" has no attribute "preprocessor"; maybe "preprocess"?  [attr-defined]
276: error: "Compiler" has no attribute "linker_exe"  [attr-defined]
279: error: "Compiler" has no attribute "linker_so_cxx"  [attr-defined]
279: error: "Compiler" has no attribute "linker_so"  [attr-defined]
283: error: "Compiler" has no attribute "compiler_cxx"  [attr-defined]
286: error: "Compiler" has no attribute "compiler_cxx"  [attr-defined]
287: error: "Compiler" has no attribute "linker_exe"  [attr-defined]
______________________________________________________________________________ distutils\dir_util.py ______________________________________________________________________________ 
61: error: "mkdir" of "Path" does not return a value (it only ever returns None)  [func-returns-value]
________________________________________________________________________________ distutils\dist.py ________________________________________________________________________________ 
186: error: Need type annotation for "cmdclass" (hint: "cmdclass: dict[<type>, <type>] = ...")  [var-annotated]
579: error: Assignment to variable "msg" outside except: block  [misc]
751: error: Item "type" of "type[Command] | Any" has no attribute "description"  [union-attr]
1030: error: Incompatible return value type (got "None", expected "bool")  [return-value]
1033: error: Incompatible return value type (got "None", expected "bool")  [return-value]
1039: error: Incompatible return value type (got "None", expected "bool")  [return-value]
1042: error: Incompatible return value type (got "None", expected "bool")  [return-value]
1045: error: Incompatible return value type (got "None", expected "bool")  [return-value]
1167: error: Missing return statement  [return]
1199: error: Item "None" of "str | None" has no attribute "split"  [union-attr]
_____________________________________________________________________________ distutils\extension.py ______________________________________________________________________________ 
123: error: Argument 1 to "map" has incompatible type overloaded function; expected "Callable[[str | PathLike[str]], str]"  [arg-type]
148: error: Incompatible types in assignment (expression has type "str", variable has type "list[str]")  [assignment]
____________________________________________________________________________ distutils\fancy_getopt.py ____________________________________________________________________________ 
247: error: Argument 1 to "getopt" has incompatible type "Sequence[str]"; expected "list[str]"  [arg-type]
267: error: Incompatible types in assignment (expression has type "int", variable has type "str")  [assignment]
269: error: Incompatible types in assignment (expression has type "int", variable has type "str")  [assignment]
275: error: Incompatible types in assignment (expression has type "Any | int", variable has type "str")  [assignment]
______________________________________________________________________________ distutils\filelist.py ______________________________________________________________________________ 
184: error: No overload variant of "include_pattern" of "FileList" matches argument types "None", "Any"  [call-overload]
184: note: Possible overload variants:
184: note:     def include_pattern(self, pattern: str, anchor: bool = ..., prefix: str | None = ..., is_regex: Literal[False] = ...) -> bool
184: note:     def include_pattern(self, pattern: str | Pattern[str], anchor: bool = ..., prefix: str | None = ..., *, is_regex: Literal[True]) -> bool
184: note:     def include_pattern(self, pattern: str | Pattern[str], anchor: bool, prefix: str | None, is_regex: Literal[True]) -> bool
189: error: No overload variant of "exclude_pattern" of "FileList" matches argument types "None", "Any"  [call-overload]
189: note: Possible overload variants:
189: note:     def exclude_pattern(self, pattern: str, anchor: bool = ..., prefix: str | None = ..., is_regex: Literal[False] = ...) -> bool
189: note:     def exclude_pattern(self, pattern: str | Pattern[str], anchor: bool = ..., prefix: str | None = ..., *, is_regex: Literal[True]) -> bool
189: note:     def exclude_pattern(self, pattern: str | Pattern[str], anchor: bool, prefix: str | None, is_regex: Literal[True]) -> bool
265: error: Item "None" of "Iterable[str] | None" has no attribute "__iter__" (not iterable)  [union-attr]
_______________________________________________________________________________ distutils\spawn.py ________________________________________________________________________________ 
87: error: Argument "env" to "check_call" has incompatible type "Mapping[str, str] | dict[str, str | int] | None"; expected "Mapping[str, str] | None"  [arg-type]
119: error: Module has no attribute "confstr"  [attr-defined]
_____________________________________________________________________________ distutils\sysconfig.py ______________________________________________________________________________ 
110: error: Module has no attribute "abiflags"  [attr-defined]
254: error: No overload variant of "join" matches argument types "str", "str", "int"  [call-overload]
254: note: Possible overload variants:
254: note:     def join(str, /, *paths: str) -> str
254: note:     def join(str | PathLike[str], /, *paths: str | PathLike[str]) -> str
254: note:     def join(bytes | PathLike[bytes], /, *paths: bytes | PathLike[bytes]) -> bytes
342: error: Item "int" of "str | int" has no attribute "startswith"  [union-attr]
342: error: Argument 1 to "startswith" of "str" has incompatible type "str | int"; expected "str | tuple[str, ...]"  [arg-type]
345: error: Value of type "str | int" is not indexable  [index]
345: error: Argument 1 to "len" has incompatible type "str | int"; expected "Sized"  [arg-type]
352: error: Unsupported operand types for + ("int" and "str")  [operator]
352: note: Left operand is of type "str | int"
355: error: Argument 1 to "_add_flags" has incompatible type "str | int"; expected "str"  [arg-type]
356: error: Argument 1 to "_add_flags" has incompatible type "str | int"; expected "str"  [arg-type]
361: error: Argument 1 to "_add_flags" has incompatible type "str | int"; expected "str"  [arg-type]
362: error: Argument 1 to "_add_flags" has incompatible type "str | int"; expected "str"  [arg-type]
363: error: Argument 1 to "_add_flags" has incompatible type "str | int"; expected "str"  [arg-type]
369: error: Unsupported operand types for + ("str" and "int")  [operator]
369: error: Unsupported operand types for + ("int" and "str")  [operator]
369: note: Both left and right operands are unions
369: note: Left operand is of type "str | int"
370: error: Unsupported operand types for + ("int" and "str")  [operator]
370: note: Left operand is of type "str | int"
371: error: Unsupported operand types for + ("int" and "str")  [operator]
371: note: Left operand is of type "str | int"
375: error: Argument "compiler" to "set_executables" of "Compiler" has incompatible type "str | int"; expected "str"  [arg-type]
376: error: Unsupported operand types for + ("str" and "int")  [operator]
376: error: Unsupported operand types for + ("int" and "str")  [operator]
376: note: Both left and right operands are unions
376: error: Argument "compiler_so" to "set_executables" of "Compiler" has incompatible type "str | Any | int"; expected "str"  [arg-type]
376: note: Left operand is of type "str | int"
377: error: Argument "compiler_cxx" to "set_executables" of "Compiler" has incompatible type "str | int"; expected "str"  [arg-type]
378: error: Unsupported operand types for + ("str" and "int")  [operator]
378: error: Unsupported operand types for + ("int" and "str")  [operator]
378: note: Both left and right operands are unions
378: error: Argument "compiler_so_cxx" to "set_executables" of "Compiler" has incompatible type "str | Any | int"; expected "str"  [arg-type]
378: note: Left operand is of type "str | int"
381: error: Argument "linker_exe" to "set_executables" of "Compiler" has incompatible type "str | int"; expected "str"  [arg-type]
382: error: Argument "linker_exe_cxx" to "set_executables" of "Compiler" has incompatible type "str | int"; expected "str"  [arg-type]
383: error: Argument "archiver" to "set_executables" of "Compiler" has incompatible type "str | Any | int"; expected "str"  [arg-type]
389: error: Cannot assign to class variable "shared_lib_extension" via instance  [misc]
389: error: Incompatible types in assignment (expression has type "str | int", variable has type "str | None")  [assignment]
578: error: List comprehension has incompatible type List[Any | None]; expected List[str | int]  [misc]
___________________________________________________________________________ distutils\tests\__init__.py ___________________________________________________________________________ 
30: error: "Compiler" has no attribute "initialize"  [attr-defined]
_________________________________________________________________________ distutils\tests\compat\py39.py __________________________________________________________________________ 
4: error: Cannot find implementation or library stub for module named "test.support.import_helper"  [import-not-found]
10: error: Cannot find implementation or library stub for module named "test.support.os_helper"  [import-not-found]
______________________________________________________________________ distutils\tests\test_archive_util.py _______________________________________________________________________ 
23: error: Cannot find implementation or library stub for module named "test.support"  [import-not-found]
________________________________________________________________________ distutils\tests\test_bdist_rpm.py ________________________________________________________________________ 
11: error: Cannot find implementation or library stub for module named "test.support"  [import-not-found]
________________________________________________________________________ distutils\tests\test_build_ext.py ________________________________________________________________________ 
25: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
28: error: Cannot find implementation or library stub for module named "test"  [import-not-found]
116: error: Cannot find implementation or library stub for module named "xx"  [import-not-found]
________________________________________________________________________ distutils\tests\test_build_py.py _________________________________________________________________________ 
10: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
______________________________________________________________________ distutils\tests\test_build_scripts.py ______________________________________________________________________ 
10: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
__________________________________________________________________________ distutils\tests\test_check.py __________________________________________________________________________ 
12: error: Library stubs not installed for "pygments"  [import-untyped]
12: note: Hint: "python3 -m pip install types-Pygments"
________________________________________________________________________ distutils\tests\test_dir_util.py _________________________________________________________________________ 
18: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
__________________________________________________________________________ distutils\tests\test_dist.py ___________________________________________________________________________ 
18: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
________________________________________________________________________ distutils\tests\test_extension.py ________________________________________________________________________ 
9: error: Cannot find implementation or library stub for module named "test.support.warnings_helper"  [import-not-found]
________________________________________________________________________ distutils\tests\test_file_util.py ________________________________________________________________________ 
9: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
________________________________________________________________________ distutils\tests\test_filelist.py _________________________________________________________________________ 
10: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
__________________________________________________________________________ distutils\tests\test_sdist.py __________________________________________________________________________ 
16: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
__________________________________________________________________________ distutils\tests\test_spawn.py __________________________________________________________________________ 
13: error: Cannot find implementation or library stub for module named "test.support"  [import-not-found]
________________________________________________________________________ distutils\tests\test_sysconfig.py ________________________________________________________________________ 
13: error: Skipping analyzing "jaraco.envs": module is installed, but missing library stubs or py.typed marker  [import-untyped]
16: error: Skipping analyzing "jaraco.text": module is installed, but missing library stubs or py.typed marker  [import-untyped]
17: error: Cannot find implementation or library stub for module named "test.support"  [import-not-found]
________________________________________________________________________ distutils\tests\test_text_file.py ________________________________________________________________________ 
6: error: Skipping analyzing "jaraco.path": module is installed, but missing library stubs or py.typed marker  [import-untyped]
_________________________________________________________________________ distutils\tests\unix_compat.py __________________________________________________________________________ 
7: error: Incompatible types in assignment (expression has type "None", variable has type Module)  [assignment]
________________________________________________________________________________ distutils\util.py ________________________________________________________________________________ 
58: error: Argument 1 to "get" of "dict" has incompatible type "str | None"; expected "str"  [arg-type]
154: error: Value of type "str | PathLike[str]" is not indexable  [index]
154: error: Value of type "bytes | PathLike[bytes]" is not indexable  [index]
178: error: Module has no attribute "getpwuid"  [attr-defined]
178: error: Module has no attribute "getuid"; maybe "getpid" or "getppid"?  [attr-defined]
267: error: Item "None" of "Any | None" has no attribute "match"  [union-attr]
288: error: Item "None" of "Any | None" has no attribute "match"  [union-attr]
290: error: Item "None" of "Any | None" has no attribute "match"  [union-attr]
446: error: Module has no attribute "_optim_args_from_interpreter_flags"  [attr-defined]
448: error: Argument 1 to "spawn" has incompatible type "list[str]"; expected "MutableSequence[bytes | str | PathLike[str]]"  [arg-type]
================================================================================ warnings summary ================================================================================= 
.tox\py\Lib\site-packages\_pytest\config\__init__.py:1396
  C:\Users\thanos\Projects\personal\distutils\.tox\py\Lib\site-packages\_pytest\config\__init__.py:1396: PytestConfigWarning: Unknown config option: consider_namespace_packages   

    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

---------- coverage: platform win32, python 3.11.9-final-0 -----------
Name                                                                                                   Stmts   Miss  Cover   Missing
------------------------------------------------------------------------------------------------------------------------------------
C:\Users\thanos\AppData\Local\Temp\pytest-of-unknown\pytest-22\test_customize_compiler_before0\file       3      0   100%
conftest.py                                                                                               87      5    94%   120-121, 144-147
distutils\__init__.py                                                                                      7      0   100%
distutils\_log.py                                                                                          2      0   100%
distutils\_macos_compat.py                                                                                 7      1    86%   10
distutils\_modified.py                                                                                    25      0   100%
distutils\_msvccompiler.py                                                                                 2      0   100%
distutils\archive_util.py                                                                                133     32    76%   13-14, 37-43, 50-56, 92, 111-112, 114-115, 148-158, 172-173, 277-278
distutils\ccompiler.py                                                                                     4      0   100%
distutils\cmd.py                                                                                         167     13    92%   85, 87, 129, 162, 178, 192, 207, 212, 298, 468, 474-476, 554
distutils\command\__init__.py                                                                              1      0   100%
distutils\command\_framework_compat.py                                                                    24      3    88%   44-45, 54
distutils\command\bdist.py                                                                                70     24    66%   27-34, 41, 133-134, 144-167
distutils\command\bdist_dumb.py                                                                           56      6    89%   81-82, 114-122, 135
distutils\command\bdist_rpm.py                                                                           265    243     8%   155-197, 200-230, 233-276, 279-400, 407, 414-578, 582-598
distutils\command\build.py                                                                                69      8    88%   74-75, 84, 90, 123-126
distutils\command\build_clib.py                                                                           87     20    77%   88-106, 134, 147-153
distutils\command\build_ext.py                                                                           358     83    77%   148-149, 154-156, 187, 198, 228, 239, 251-260, 295-298, 320-322, 337, 343, 353-354, 356-357, 365, 438, 492-493, 496-497, 524, 535-536, 563, 583, 618, 625, 632-634, 641-656, 663-676, 716, 773-810
distutils\command\build_py.py                                                                            204     17    92%   65-69, 158, 185, 194, 198, 215-216, 232, 274, 281, 323, 340-341
distutils\command\build_scripts.py                                                                        96     23    76%   56, 85-86, 92-95, 99-100, 125-126, 129-137, 148-149, 156-157
distutils\command\check.py                                                                                71      4    94%   83-84, 114, 145
distutils\command\clean.py                                                                                34      0   100%
distutils\command\config.py                                                                              162    105    35%   67, 72, 77, 82, 94-104, 107-116, 119-123, 126-132, 135-149, 153-154, 159-160, 179-187, 197-207, 213-222, 237-246, 261-273, 302-314, 332-333, 346, 357
distutils\command\install.py                                                                             303     44    85%   126, 376-377, 390, 538-583, 589, 602-603, 685, 705, 712, 746-752, 768, 775-780
distutils\command\install_data.py                                                                         50      0   100%
distutils\command\install_egg_info.py                                                                     42      3    93%   47, 49, 51
distutils\command\install_headers.py                                                                      24      1    96%   35
distutils\command\install_lib.py                                                                          96      4    96%   120-123, 180, 211
distutils\command\install_scripts.py                                                                      32      7    78%   50-56, 59
distutils\command\sdist.py                                                                               224     19    92%   162, 180, 218, 260, 279, 286, 329-330, 334-335, 394, 406-409, 466-467, 470, 475, 499, 517
distutils\compilers\C\base.py                                                                            404    102    75%   199, 211-216, 220-221, 229-230, 240, 253-257, 270-275, 
283, 309, 325, 338, 354, 362, 404, 406, 427, 434, 441, 457-462, 473, 478-479, 500, 507, 519, 530, 533, 554-555, 579, 650-651, 655, 661, 693, 759, 778, 863, 869, 875, 911, 976, 1078-1081, 1105, 1118, 1125, 1132, 1138, 1141, 1150, 1170, 1203, 1209, 1217, 1248-1255, 1283-1287, 1294-1299, 1335-1350, 1371, 1380-1390
distutils\compilers\C\cygwin.py                                                                          120     42    65%   61, 97-104, 108-128, 148-202, 222-223, 229-230, 237, 255-257, 269, 311, 333
distutils\compilers\C\errors.py                                                                            6      0   100%
distutils\compilers\C\msvc.py                                                                            285     77    73%   50-52, 84, 119, 135, 138-139, 143-144, 151, 166-168, 189, 288, 296, 393, 402-403, 408, 412-451, 455, 474-489, 508, 514, 521, 546, 548, 558, 578, 593, 598, 603-614
distutils\compilers\C\tests\test_base.py                                                                  43      0   100%
distutils\compilers\C\tests\test_cygwin.py                                                                46     13    72%   28-35, 39-42, 73-76
distutils\compilers\C\tests\test_mingw.py                                                                 34     17    50%   13-14, 18-27, 31-33, 37-40, 48
distutils\compilers\C\tests\test_msvc.py                                                                  79      4    95%   71, 82, 93-94
distutils\compilers\C\tests\test_unix.py                                                                 206     12    94%   70, 88, 101, 148, 160, 175, 188, 203, 218, 237, 271, 304
distutils\compilers\C\unix.py                                                                            157     52    67%   139, 156-159, 170-196, 203, 214-233, 257, 259, 264, 266, 268, 295-298, 305, 334, 353, 376-388
distutils\compilers\C\zos.py                                                                              66     48    27%   111-137, 140-142, 145-161, 164, 184-216
distutils\core.py                                                                                         90     21    77%   136, 149-153, 156, 186, 203-216, 253, 264, 278
distutils\cygwinccompiler.py                                                                               7      0   100%
distutils\debug.py                                                                                         2      0   100%
distutils\dep_util.py                                                                                      7      2    71%   9-14
distutils\dir_util.py                                                                                     96     13    86%   76, 127, 132, 173-178, 181, 224, 232-233
distutils\dist.py                                                                                        612    125    80%   268-270, 273-276, 288-289, 329-330, 333-334, 339, 367, 
411, 419, 424, 448, 450, 453-454, 504, 520, 554, 562-563, 568, 578-582, 588-589, 608-609, 617-621, 627, 673, 686-697, 713-716, 731, 733, 744-755, 765-780, 791-808, 852-853, 860, 879, 910, 913, 916, 929, 931, 935-939, 976, 980-989, 1036, 1048, 1142, 1175, 1193, 1210-1212, 1296, 1299, 1302, 1305, 1346
distutils\errors.py                                                                                       32      0   100%
distutils\extension.py                                                                                   101     26    74%   153, 186-187, 204-206, 224, 226, 228, 231-252
distutils\fancy_getopt.py                                                                                222     34    85%   99-106, 111, 123, 127, 163, 167, 172, 190, 203, 214, 260, 266-267, 291, 345, 358, 367, 381-383, 396, 427-428, 434, 458, 462-471
distutils\file_util.py                                                                                   116     24    79%   29-30, 35-36, 40-41, 46-47, 54-55, 108, 119-121, 125-126, 135, 151-153, 187, 190, 195, 200
distutils\filelist.py                                                                                    183      2    99%   195, 353
distutils\log.py                                                                                          36     13    64%   27-29, 33-38, 45-46, 50, 54
distutils\spawn.py                                                                                        64      6    91%   40-44, 52, 79
distutils\sysconfig.py                                                                                   257     69    73%   49, 56, 98, 122, 142-143, 155, 159-161, 176-181, 208-210, 216, 226-229, 251-255, 261, 266-275, 278, 282, 387, 461, 475-514
distutils\tests\__init__.py                                                                                2      0   100%
distutils\tests\support.py                                                                                48      8    83%   108-120
distutils\tests\test_archive_util.py                                                                     238    185    22%   32-38, 42, 46, 53-56, 60-61, 64-66, 69-71, 78, 86, 89-102, 105-111, 125-133, 138-189, 193-204, 207-230, 233-234, 240-243, 246-259, 262-267, 271-276, 279-285, 288-294, 299-324, 330-353
distutils\tests\test_bdist.py                                                                             24      1    96%   46
distutils\tests\test_bdist_dumb.py                                                                        42      0   100%
distutils\tests\test_bdist_rpm.py                                                                         73     47    36%   25-28, 49-83, 92-127
distutils\tests\test_build.py                                                                             27      3    89%   28, 30-31
distutils\tests\test_build_clib.py                                                                        79     14    82%   112-134
distutils\tests\test_build_ext.py                                                                        323      7    98%   72-73, 104, 147, 478, 485-486
distutils\tests\test_build_py.py                                                                         114      5    96%   55, 78-79, 144-145
distutils\tests\test_build_scripts.py                                                                     51      0   100%
distutils\tests\test_check.py                                                                             95      4    96%   13-14, 186-187
distutils\tests\test_clean.py                                                                             23      0   100%
distutils\tests\test_cmd.py                                                                               78      0   100%
distutils\tests\test_config_cmd.py                                                                        62     13    79%   37-54
distutils\tests\test_core.py                                                                              63      0   100%
distutils\tests\test_dir_util.py                                                                          88      8    91%   50-55, 100-101
distutils\tests\test_dist.py                                                                             287     19    93%   93-151, 185, 264-266
distutils\tests\test_extension.py                                                                         44      0   100%
distutils\tests\test_file_util.py                                                                         61      2    97%   70-71
distutils\tests\test_filelist.py                                                                         174      5    97%   302-303, 328-336
distutils\tests\test_install.py                                                                          158      6    96%   67-73, 125, 211
distutils\tests\test_install_data.py                                                                      49      0   100%
distutils\tests\test_install_headers.py                                                                   20      0   100%
distutils\tests\test_install_lib.py                                                                       78      0   100%
distutils\tests\test_install_scripts.py                                                                   33      0   100%
distutils\tests\test_log.py                                                                                8      0   100%
distutils\tests\test_modified.py                                                                          78      0   100%
distutils\tests\test_sdist.py                                                                            249     39    84%   143-167, 432-470
distutils\tests\test_spawn.py                                                                             81      4    95%   26-27, 38-39
distutils\tests\test_sysconfig.py                                                                        178     77    57%   34-35, 62-69, 83-111, 117-172, 226, 287-300, 313-315   
distutils\tests\test_text_file.py                                                                         43      0   100%
distutils\tests\test_util.py                                                                             132     13    90%   94, 132-157
distutils\tests\test_version.py                                                                           38      1    97%   51
distutils\tests\test_versionpredicate.py                                                                   0      0   100%
distutils\tests\unix_compat.py                                                                            11      1    91%   5
distutils\text_file.py                                                                                   103     28    73%   85, 100, 105-107, 131-140, 143, 153, 170-172, 217, 223-224, 232, 242, 251, 266-267, 286
distutils\unixccompiler.py                                                                                 2      0   100%
distutils\util.py                                                                                        195     24    88%   59, 63, 175-182, 203-204, 214, 218-220, 292, 295, 302-303, 328-330, 350, 471, 475, 480, 489
distutils\version.py                                                                                     105     18    83%   67, 73, 77-80, 85, 89-92, 200, 202, 206-209, 329, 332  
distutils\versionpredicate.py                                                                             57      5    91%   113, 116, 126, 135, 170
distutils\zosccompiler.py                                                                                  2      0   100%
docs\conf.py                                                                                              15      0   100%
------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                                   9607   1904    80%

====================================================================================== mypy ======================================================================================= 
Found 162 errors in 40 files (checked 101 source files)
============================================================================= short test summary info ============================================================================= 
FAILED conftest.py::mypy-status
FAILED distutils/_modified.py::mypy
FAILED distutils/archive_util.py::mypy
FAILED distutils/cmd.py::mypy
FAILED distutils/command/bdist.py::mypy
FAILED distutils/command/bdist_rpm.py::mypy
FAILED distutils/command/build_clib.py::mypy
FAILED distutils/command/build_ext.py::mypy
FAILED distutils/command/build_py.py::mypy
FAILED distutils/command/check.py::mypy
FAILED distutils/command/install.py::mypy
FAILED distutils/command/install_lib.py::mypy
FAILED distutils/command/sdist.py::mypy
FAILED distutils/compilers/C/base.py::mypy
FAILED distutils/compilers/C/tests/test_mingw.py::TestMinGW32Compiler::test_customize_compiler_with_msvc_python - FileNotFoundError: [WinError 2] The system cannot find the file...FAILED distutils/compilers/C/unix.py::mypy
FAILED distutils/dir_util.py::mypy
FAILED distutils/dist.py::mypy
FAILED distutils/extension.py::mypy
FAILED distutils/fancy_getopt.py::mypy
FAILED distutils/filelist.py::mypy
FAILED distutils/spawn.py::mypy
FAILED distutils/sysconfig.py::mypy
FAILED distutils/tests/__init__.py::mypy
FAILED distutils/tests/compat/py39.py::mypy
FAILED distutils/tests/test_archive_util.py::mypy
FAILED distutils/tests/test_bdist_rpm.py::mypy
FAILED distutils/tests/test_build_ext.py::mypy
FAILED distutils/tests/test_build_py.py::mypy
FAILED distutils/tests/test_build_scripts.py::mypy
FAILED distutils/tests/test_check.py::mypy
FAILED distutils/tests/test_dir_util.py::mypy
FAILED distutils/tests/test_dist.py::mypy
FAILED distutils/tests/test_extension.py::mypy
FAILED distutils/tests/test_file_util.py::mypy
FAILED distutils/tests/test_filelist.py::mypy
FAILED distutils/tests/test_sdist.py::mypy
FAILED distutils/tests/test_spawn.py::mypy
FAILED distutils/tests/test_sysconfig.py::mypy
FAILED distutils/tests/test_text_file.py::mypy
FAILED distutils/tests/unix_compat.py::mypy
FAILED distutils/util.py::mypy
=================================================== 42 failed, 487 passed, 29 skipped, 2 xfailed, 1 warning in 78.35s (0:01:18) =================================================== 
py: exit 1 (79.83 seconds) C:\Users\thanos\Projects\personal\distutils> pytest --mypy pid=13952
  py: FAIL code 1 (86.14=setup[6.31]+cmd[79.83] seconds)
  evaluation failed :( (86.41 seconds)

(EDIT: Replaced output with output when run on the correct branch. Whoops.)

This probably deserves its own issue.

@abravalheri
Copy link
Contributor

abravalheri commented Mar 12, 2025

but pytest-mypy doesn't do anything because --mypy isn't provided as a positional argument for tox to pass along to pytest.

In theory the tests use pytest-enabler which should automatically activate mypy without the need for --mypy (or -p mypy) when pytest-mypy is installed in the environment.

@Sachaa-Thanasius
Copy link
Contributor Author

Sachaa-Thanasius commented Mar 12, 2025

Ah, gotcha. Glancing at the config, pytest-enabler is intentionally off because "distutils isn't ready yet". Guess that answers that.

distutils/pyproject.toml

Lines 86 to 88 in b53777a

[tool.pytest-enabler.mypy]
# Disabled due to jaraco/skeleton#143
# Disabled as distutils isn't ready yet

@Avasam
Copy link
Contributor

Avasam commented Mar 20, 2025

Mypy tests have been re-enabled in #349

@Avasam
Copy link
Contributor

Avasam commented Mar 21, 2025

________________________ distutils/compilers/C/unix.py _________________________
 326: error: Unused "type: ignore" comment [unused-ignore]

As expected, since you fixed the underlying issue. You can just remove that type-ignore

@Sachaa-Thanasius
Copy link
Contributor Author

This should be good to go now.

@Avasam
Copy link
Contributor

Avasam commented May 3, 2025

@abravalheri tests have been re-enabled and this PR passes.

@jaraco jaraco merged commit 42dfd06 into pypa:main May 4, 2025
22 checks passed
@Sachaa-Thanasius Sachaa-Thanasius deleted the fix-annotation branch May 4, 2025 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants