Skip to content

fix Respect VERSIONS file in typeshed #2535#3093

Open
asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
asukaminato0721:2535
Open

fix Respect VERSIONS file in typeshed #2535#3093
asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
asukaminato0721:2535

Conversation

@asukaminato0721
Copy link
Copy Markdown
Contributor

@asukaminato0721 asukaminato0721 commented Apr 10, 2026

Summary

Fixes #2535

making bundled stdlib resolution respect typeshed’s stdlib/VERSIONS metadata.

bundled stdlib modules are now gated by the active python_version, so import distutils is rejected on Python 3.12+, and removed stdlib names are also filtered out of prefix results instead of leaking back in through third-party stubs.

Test Plan

add test

@github-actions
Copy link
Copy Markdown

Diff from mypy_primer, showing the effect of this PR on open source code:

pip (https://github.com/pypa/pip)
- ERROR src/pip/_internal/locations/_distutils.py:92:22-76: No matching overload found for function `typing.MutableMapping.update` called with arguments: (dict[str, str | None]) [no-matching-overload]
- ERROR src/pip/_internal/locations/_distutils.py:101:41-107:10: No matching overload found for function `posixpath.join` called with arguments: (str | Any | None, Literal['include'], Literal['site'], str, str) [no-matching-overload]
- ERROR src/pip/_vendor/distlib/util.py:1966:66-93: Argument `dict[str, int | str] | dict[str, Any]` is not assignable to parameter `_config_vars` with type `dict[str, str]` in function `_osx_support.get_platform_osx` [bad-argument-type]

cloud-init (https://github.com/canonical/cloud-init)
+ ERROR cloudinit/distros/netbsd.py:15:12-17: Cannot find module `crypt` [missing-import]
+ ERROR cloudinit/sources/DataSourceAzure.py:157:20-25: Cannot find module `crypt` [missing-import]

jax (https://github.com/google/jax)
+ ERROR jax/_src/compilation_cache.py:27:3-31: Cannot find module `compression` [missing-import]

materialize (https://github.com/MaterializeInc/materialize)
- ERROR ci/deploy/pypi.py:55:12-69: Returned type `tuple[str | None, str | None]` is not assignable to declared return type `tuple[str, str]` [bad-return]

aioredis (https://github.com/aio-libs/aioredis)
+ ERROR aioredis/connection.py:11:1-44: Cannot find module `distutils.version` [missing-import]

setuptools (https://github.com/pypa/setuptools)
- ERROR setuptools/__init__.py:85:29-49: Unexpected keyword argument `ignore_option_errors` in function `distutils.dist.Distribution.parse_config_files` [unexpected-keyword]
- ERROR setuptools/__init__.py:87:27-31: Argument `_install_setup_requires.MinimalDistribution` is not assignable to parameter `dist` with type `Distribution` in function `_fetch_build_eggs` [bad-argument-type]
- ERROR setuptools/__init__.py:168:5-17: Class member `Command.distribution` overrides parent class `Command` in an inconsistent manner [bad-override]
- ERROR setuptools/__init__.py:185:9-29: Class member `Command.reinitialize_command` overrides parent class `Command` in an inconsistent manner [bad-override]
- ERROR setuptools/_distutils/cmd.py:319:16-23: Returned type `distutils.cmd.Command | None` is not assignable to declared return type `setuptools._distutils.cmd.Command` [bad-return]
- ERROR setuptools/_distutils/cmd.py:334:54-83: No matching overload found for function `distutils.dist.Distribution.reinitialize_command` called with arguments: (Command | str, bool | Unknown) [no-matching-overload]
- ERROR setuptools/_distutils/command/build_ext.py:328:21-33: Argument `Literal[0, 1] | bool` is not assignable to parameter `verbose` with type `bool` in function `setuptools._distutils.compilers.C.base.new_compiler` [bad-argument-type]
- ERROR setuptools/_distutils/command/build_py.py:224:39-70: No matching overload found for function `posixpath.abspath` called with arguments: (str | None) [no-matching-overload]
- ERROR setuptools/_distutils/command/install.py:681:29-33: Argument `int | str | Any` is not assignable to parameter `name` with type `PathLike[bytes] | PathLike[str] | bytes | str` in function `os.makedirs` [bad-argument-type]
+ ERROR setuptools/_distutils/command/install.py:681:29-33: Argument `int | str | Unknown` is not assignable to parameter `name` with type `PathLike[bytes] | PathLike[str] | bytes | str` in function `os.makedirs` [bad-argument-type]
- ERROR setuptools/_distutils/command/install_headers.py:39:38-64: No matching overload found for function `setuptools._distutils.cmd.Command.copy_file` called with arguments: (Any, Unknown | None) [no-matching-overload]
+ ERROR setuptools/_distutils/command/install_headers.py:39:38-64: No matching overload found for function `setuptools._distutils.cmd.Command.copy_file` called with arguments: (Unknown, Unknown | None) [no-matching-overload]
- ERROR setuptools/_distutils/command/install_lib.py:152:25-37: Argument `Literal[0, 1] | bool` is not assignable to parameter `verbose` with type `bool` in function `setuptools._distutils.util.byte_compile` [bad-argument-type]
- ERROR setuptools/_distutils/command/sdist.py:284:42-44: Argument `str | None` is not assignable to parameter `item` with type `str` in function `setuptools._distutils.filelist.FileList.append` [bad-argument-type]
- ERROR setuptools/_distutils/command/sdist.py:389:38-61: No matching overload found for function `setuptools._distutils.filelist.FileList.exclude_pattern` called with arguments: (None, prefix=str) [no-matching-overload]
+ ERROR setuptools/_distutils/command/sdist.py:389:38-61: No matching overload found for function `setuptools._distutils.filelist.FileList.exclude_pattern` called with arguments: (None, prefix=Unknown) [no-matching-overload]
- ERROR setuptools/_distutils/command/sdist.py:415:13-37: Argument `tuple[Unknown | None, list[str]]` is not assignable to parameter `args` with type `tuple[StrOrBytesPath, Iterable[str]]` in function `setuptools._distutils.cmd.Command.execute` [bad-argument-type]
- ERROR setuptools/_distutils/command/sdist.py:493:33-58: No matching overload found for function `posixpath.join` called with arguments: (Unknown | None, str) [no-matching-overload]
+ ERROR setuptools/_distutils/command/sdist.py:493:33-58: No matching overload found for function `posixpath.join` called with arguments: (Unknown | None, Unknown) [no-matching-overload]
- ERROR setuptools/_distutils/compilers/C/base.py:1250:34-43: Argument `list[tuple[str, None, str]]` is not assignable to parameter `option_table` with type `list[tuple[str, str | None, str]] | None` in function `distutils.fancy_getopt.FancyGetopt.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/compilers/C/tests/test_mingw.py:48:38-46: Argument `MinGW32Compiler` is not assignable to parameter `compiler` with type `CCompiler` in function `distutils.sysconfig.customize_compiler` [bad-argument-type]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:84:40-74: `(var: Unknown) -> Literal['xxx'] | Unknown` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:126:36-39: `(v: Unknown) -> Literal['xxx']` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:132:36-39: `(v: Unknown) -> Literal['gcc']` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:138:36-39: `(v: Unknown) -> Literal['g++']` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:152:36-39: `(v: Unknown) -> Literal['gcc', 'yes'] | None` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:164:36-39: `(v: Unknown) -> Literal['gcc -pthread -B /bar', 'yes'] | None` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:179:36-39: `(v: Unknown) -> Literal['gcc', 'no'] | None` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:192:36-39: `(v: Unknown) -> Literal['x86_64-pc-linux-gnu-gcc-4.4.2', 'yes'] | None` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:207:36-39: `(v: Unknown) -> Literal['cc', 'yes'] | None` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:222:36-39: `(v: Unknown) -> Literal['cc', 'no'] | None` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:239:36-39: `(v: Unknown) -> Literal['gcc-4.2', 'gcc-4.2 -bundle -undefined dynamic_lookup ']` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:240:37-41: `(*args: Unknown, *, _orig: Overload[() -> dict[str, int | str], (arg: str, /, *args: str) -> list[int | str]] | Unknown = ...) -> dict[str, int | str] | list[int | str | None] | Unknown` is not assignable to attribute `get_config_vars` with type `Overload[
-   () -> dict[str, int | str]
-   (arg: str, /, *args: str) -> list[int | str]
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:265:36-39: `(v: Unknown) -> Unknown` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:266:37-41: `(*args: Unknown, *, _orig: Overload[() -> dict[str, int | str], (arg: str, /, *args: str) -> list[int | str]] | Unknown = ...) -> dict[str, int | str] | list[int | str | None] | Unknown` is not assignable to attribute `get_config_vars` with type `Overload[
-   () -> dict[str, int | str]
-   (arg: str, /, *args: str) -> list[int | str]
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:336:36-39: `(v: Unknown) -> Unknown` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:337:37-41: `(*args: Unknown, *, _orig: Overload[() -> dict[str, int | str], (arg: str, /, *args: str) -> list[int | str]] | Unknown = ...) -> dict[str, int | str] | list[int | str | None] | Unknown` is not assignable to attribute `get_config_vars` with type `Overload[
-   () -> dict[str, int | str]
-   (arg: str, /, *args: str) -> list[int | str]
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:369:36-39: `(v: Unknown) -> Literal['gcc-4.2', 'gcc-4.2 -bundle -undefined dynamic_lookup ']` is not assignable to attribute `get_config_var` with type `Overload[
-   (name: Literal['SO']) -> int | str | None
-   (name: str) -> int | str | None
- ]` [bad-assignment]
- ERROR setuptools/_distutils/compilers/C/tests/test_unix.py:370:37-41: `(*args: Unknown, *, _orig: Overload[() -> dict[str, int | str], (arg: str, /, *args: str) -> list[int | str]] | Unknown = ...) -> dict[str, int | str] | list[int | str | None] | Unknown` is not assignable to attribute `get_config_vars` with type `Overload[
-   () -> dict[str, int | str]
-   (arg: str, /, *args: str) -> list[int | str]
- ]` [bad-assignment]
- ERROR setuptools/_distutils/dist.py:697:25-41: Argument `PathLike[str] | str | None` is not assignable to parameter `script_name` with type `PathLike[bytes] | PathLike[str] | bytes | str` in function `distutils.core.gen_usage` [bad-argument-type]
- ERROR setuptools/_distutils/dist.py:713:29-45: Argument `PathLike[str] | str | None` is not assignable to parameter `script_name` with type `PathLike[bytes] | PathLike[str] | bytes | str` in function `distutils.core.gen_usage` [bad-argument-type]
- ERROR setuptools/_distutils/dist.py:883:57-61: Argument `Self@setuptools._distutils.dist.Distribution` is not assignable to parameter `dist` with type `distutils.dist.Distribution` in function `setuptools._distutils.cmd.Command.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/dist.py:972:44-56: Argument `Command | str` is not assignable to parameter `command` with type `str` in function `Distribution.get_command_obj` [bad-argument-type]
- ERROR setuptools/_distutils/dist.py:980:23-35: Cannot set item in `dict[str, bool]` [unsupported-operation]
- ERROR setuptools/_distutils/sysconfig.py:423:9-15: Unexpected keyword argument `errors` in function `distutils.text_file.TextFile.__init__` [unexpected-keyword]
- ERROR setuptools/_distutils/tests/test_build_ext.py:502:54-67: `+` is not supported between `Literal['etree']` and `int` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:502:54-67: `+` is not supported between `Literal['etree']` and `None` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:509:57-70: `+` is not supported between `Literal['etree']` and `int` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:509:57-70: `+` is not supported between `Literal['etree']` and `None` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:518:70-85: `+` is not supported between `Literal['portmap']` and `int` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:518:70-85: `+` is not supported between `Literal['portmap']` and `None` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:524:60-75: `+` is not supported between `Literal['portmap']` and `int` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_build_ext.py:524:60-75: `+` is not supported between `Literal['portmap']` and `None` [unsupported-operation]
- ERROR setuptools/_distutils/tests/test_dir_util.py:115:37-41: Argument `None` is not assignable to parameter `dst` with type `str` in function `distutils.dir_util.copy_tree` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_dir_util.py:134:20-36: Argument `TestDirUtil.test_mkpath_exception_uncached.FailPath` is not assignable to parameter `name` with type `str` in function `distutils.dir_util.mkpath` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_dist.py:227:33-42: `Literal['one,two']` is not assignable to attribute `command_packages` with type `list[str] | None` [bad-assignment]
- ERROR setuptools/_distutils/tests/test_dist.py:235:39-44: Argument `Literal['ok2']` is not assignable to parameter `level` with type `int` in function `distutils.dist.Distribution.announce` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:66:23-24: Argument `Literal[1]` is not assignable to parameter `name` with type `str` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:73:31-37: Argument `Literal['file']` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:75:31-42: Argument `list[int | str]` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:78:33-79: Argument `list[Path]` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:82:33-51: Argument `tuple[Literal['file1'], Literal['file2']]` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:84:33-51: Argument `set[str]` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:86:33-57: Argument `Iterator[Any]` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:88:33-65: Argument `list[Path | str]` is not assignable to parameter `sources` with type `list[str]` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_extension.py:114:57-61: Unexpected keyword argument `chic` in function `distutils.extension.Extension.__init__` [unexpected-keyword]
- ERROR setuptools/_distutils/tests/test_install.py:179:20-26: `Literal['user']` is not assignable to attribute `user` with type `bool` [bad-assignment]
- ERROR setuptools/_distutils/tests/test_sysconfig.py:50:31-65: Argument `int | str | None` is not assignable to parameter `*args` with type `PathLike[str] | str` in function `pathlib.Path.__new__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_sysconfig.py:62:31-65: Argument `int | str | None` is not assignable to parameter `*args` with type `PathLike[str] | str` in function `pathlib.Path.__new__` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_sysconfig.py:109:42-46: Argument `TestSysconfig.customize_compiler.compiler` is not assignable to parameter `compiler` with type `CCompiler` in function `distutils.sysconfig.customize_compiler` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_util.py:69:29-62: Argument `Path` is not assignable to parameter `pathname` with type `str` in function `distutils.util.convert_path` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_version.py:55:42-50: Argument `object` is not assignable to parameter `other` with type `StrictVersion | str` in function `distutils.version.StrictVersion._cmp` [bad-argument-type]
- ERROR setuptools/_distutils/tests/test_version.py:77:41-49: Argument `object` is not assignable to parameter `other` with type `LooseVersion | str` in function `distutils.version.LooseVersion._cmp` [bad-argument-type]
- ERROR setuptools/command/__init__.py:16:9-37: Cannot set item in `list[str]` [unsupported-operation]
- ERROR setuptools/command/bdist_egg.py:237:25-39: Argument `Unknown | None` is not assignable to parameter `directory` with type `PathLike[bytes] | PathLike[str] | bytes | str` in function `distutils.dir_util.remove_tree` [bad-argument-type]
- ERROR setuptools/command/bdist_egg.py:317:51-77: No matching overload found for function `posixpath.join` called with arguments: (Unknown | None, str) [no-matching-overload]
+ ERROR setuptools/command/bdist_egg.py:317:51-77: No matching overload found for function `posixpath.join` called with arguments: (Unknown | None, Unknown) [no-matching-overload]
- ERROR setuptools/command/bdist_rpm.py:16:5-17: Class member `bdist_rpm.distribution` overrides parent class `bdist_rpm` in an inconsistent manner [bad-override]
- ERROR setuptools/command/build.py:13:5-17: Class member `build.distribution` overrides parent class `build` in an inconsistent manner [bad-override]
- ERROR setuptools/command/build_clib.py:25:5-17: Class member `build_clib.distribution` overrides parent class `build_clib` in an inconsistent manner [bad-override]
- ERROR setuptools/command/build_ext.py:90:5-17: Class member `build_ext.distribution` overrides parent class `build_ext` in an inconsistent manner [bad-override]
- ERROR setuptools/command/build_ext.py:159:9-25: Class member `build_ext.get_ext_filename` overrides parent class `build_ext` in an inconsistent manner [bad-param-name-override]
- ERROR setuptools/command/build_py.py:42:5-17: Class member `build_py.distribution` overrides parent class `build_py` in an inconsistent manner [bad-override]
- ERROR setuptools/command/egg_info.py:297:21-34: Argument `Unknown | None` is not assignable to parameter `name` with type `str` in function `distutils.cmd.Command.mkpath` [bad-argument-type]
- ERROR setuptools/command/egg_info.py:484:9-15: Class member `FileList.extend` overrides parent class `FileList` in an inconsistent manner [bad-param-name-override]
- ERROR setuptools/command/install.py:35:5-17: Class member `install.distribution` overrides parent class `install` in an inconsistent manner [bad-override]
- ERROR setuptools/command/install_lib.py:16:5-17: Class member `install_lib.distribution` overrides parent class `install_lib` in an inconsistent manner [bad-override]
- ERROR setuptools/command/install_lib.py:94:9-18: Class member `install_lib.copy_tree` overrides parent class `install_lib` in an inconsistent manner [bad-override]
- ERROR setuptools/command/install_scripts.py:16:5-17: Class member `install_scripts.distribution` overrides parent class `install_scripts` in an inconsistent manner [bad-override]
- ERROR setuptools/command/sdist.py:53:5-17: Class member `sdist.distribution` overrides parent class `sdist` in an inconsistent manner [bad-override]
+ ERROR setuptools/config/pyprojecttoml.py:446:31-52: `Unknown | None` is not assignable to attribute `py_modules` with type `Never` [bad-assignment]
+ ERROR setuptools/config/pyprojecttoml.py:448:29-48: `Unknown | None` is not assignable to attribute `packages` with type `Never` [bad-assignment]
- ERROR setuptools/dist.py:995:9-28: Cannot set field `global_options` [read-only]
- ERROR setuptools/dist.py:996:9-26: Cannot set field `negative_opt` [read-only]
- ERROR setuptools/tests/config/test_pyprojecttoml.py:392:53-55: Argument `dict[@_, @_]` is not assignable to parameter `script_args` with type `list[str] | None` in function `distutils.core.run_setup` [bad-argument-type]
- ERROR setuptools/tests/config/test_setupcfg.py:79:35-60: `None` is not assignable to upper bound `Distribution | DistributionMetadata` of type variable `Target` [bad-specialization]
- ERROR setuptools/tests/config/test_setupcfg.py:376:24-49: Argument `list[str] | str | None` is not assignable to parameter `iterable` with type `Iterable[str]` in function `set.__init__` [bad-argument-type]
- ERROR setuptools/tests/config/test_setupcfg.py:387:24-49: Argument `list[str] | str | None` is not assignable to parameter `iterable` with type `Iterable[str]` in function `set.__init__` [bad-argument-type]
- ERROR setuptools/tests/test_bdist_wheel.py:224:23-31: Argument `distutils.dist.Distribution | setuptools.dist.Distribution` is not assignable to parameter `dist` with type `setuptools.dist.Distribution` in function `setuptools.Command.__init__` [bad-argument-type]
- ERROR setuptools/tests/test_build_ext.py:53:33-61: Argument `int | str | None` is not assignable to parameter `suffix` with type `str | tuple[str, ...]` in function `str.endswith` [bad-argument-type]
- ERROR setuptools/tests/test_config_discovery.py:624:54-56: Argument `dict[@_, @_]` is not assignable to parameter `script_args` with type `list[str] | None` in function `distutils.core.run_setup` [bad-argument-type]
- ERROR setuptools/tests/test_editable_install.py:255:38-42: Argument `distutils.dist.Distribution` is not assignable to parameter `dist` with type `setuptools.dist.Distribution` in function `setuptools.Command.__init__` [bad-argument-type]
- ERROR setuptools/tests/test_sdist.py:809:9-27: Cannot set field `sub_commands` [read-only]

comtypes (https://github.com/enthought/comtypes)
+ ERROR comtypes/test/setup.py:3:1-33: Cannot find module `distutils.core` [missing-import]

streamlit (https://github.com/streamlit/streamlit)
- ERROR lib/tests/testutil.py:161:31-37: Could not import `Format` from `annotationlib` [missing-module-attribute]
- ERROR lib/tests/testutil.py:161:39-49: Could not import `ForwardRef` from `annotationlib` [missing-module-attribute]
+ ERROR lib/tests/testutil.py:161:5-49: Cannot find module `annotationlib` [missing-import]

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ERROR ddtrace/vendor/psutil/setup.py:306:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:321:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:330:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `libraries` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:339:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:354:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:358:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:373:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:377:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:392:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:396:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:409:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `libraries` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:412:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:422:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:426:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:437:23-29: Argument `list[tuple[str, int]]` is not assignable to parameter `define_macros` with type `list[tuple[str, str | None]] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `include_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `undef_macros` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `runtime_library_dirs` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_objects` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_compile_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `extra_link_args` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `export_symbols` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `swig_opts` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `depends` with type `list[str] | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]
- ERROR ddtrace/vendor/psutil/setup.py:440:9-25: Unpacked keyword argument `bool | Unknown` is not assignable to parameter `language` with type `str | None` in function `distutils.extension.Extension.__init__` [bad-argument-type]

mypy (https://github.com/python/mypy)
+ ERROR mypy/typeshed/stdlib/_zstd.pyi:3:1-74: Cannot find module `compression.zstd` [missing-import]
+ ERROR mypy/typeshed/stdlib/asynchat.pyi:1:8-16: Cannot find module `asyncore` [missing-import]
+ ERROR mypy/typeshed/stdlib/bz2.pyi:12:5-49: Cannot find module `_compression` [missing-import]
+ ERROR mypy/typeshed/stdlib/compression/zstd/__init__.pyi:4:1-54: Cannot find module `compression.zstd._zstdfile` [missing-import]
+ ERROR mypy/typeshed/stdlib/compression/zstd/__init__.pyi:7:8-13: Cannot find module `_zstd` [missing-import]
+ ERROR mypy/typeshed/stdlib/compression/zstd/__init__.pyi:8:1-102: Cannot find module `_zstd` [missing-import]
+ ERROR mypy/typeshed/stdlib/compression/zstd/_zstdfile.pyi:3:1-41: Cannot find module `compression._common` [missing-import]
+ ERROR mypy/typeshed/stdlib/compression/zstd/_zstdfile.pyi:4:1-38: Cannot find module `compression.zstd` [missing-import]
+ ERROR mypy/typeshed/stdlib/compression/zstd/_zstdfile.pyi:9:1-87: Cannot find module `_zstd` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/ccompiler.pyi:3:1-55: Cannot find module `distutils.file_util` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:5:1-52: Cannot find module `distutils.command.bdist_dumb` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:11:1-58: Cannot find module `distutils.command.build_scripts` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:12:1-42: Cannot find module `distutils.command.check` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:13:1-42: Cannot find module `distutils.command.clean` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:14:1-44: Cannot find module `distutils.command.config` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:17:1-64: Cannot find module `distutils.command.install_egg_info` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:18:1-62: Cannot find module `distutils.command.install_headers` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:21:1-48: Cannot find module `distutils.command.register` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:23:1-44: Cannot find module `distutils.command.upload` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/cmd.pyi:25:1-55: Cannot find module `distutils.file_util` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:5:1-52: Cannot find module `distutils.command.bdist_dumb` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:11:1-58: Cannot find module `distutils.command.build_scripts` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:12:1-42: Cannot find module `distutils.command.check` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:13:1-42: Cannot find module `distutils.command.clean` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:14:1-44: Cannot find module `distutils.command.config` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:17:1-64: Cannot find module `distutils.command.install_egg_info` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:18:1-62: Cannot find module `distutils.command.install_headers` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:21:1-48: Cannot find module `distutils.command.register` [missing-import]
+ ERROR mypy/typeshed/stdlib/distutils/dist.pyi:23:1-44: Cannot find module `distutils.command.upload` [missing-import]
+ ERROR mypy/typeshed/stdlib/gzip.pyi:11:5-58: Cannot find module `_compression` [missing-import]
- ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi:12:9-19: Class member `FixExitfunc.start_tree` overrides parent class `BaseFix` in an inconsistent manner [bad-override]
+ ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi:2:1-31: Cannot find module `lib2to3` [missing-import]
+ ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools_imports.pyi:1:1-31: Cannot find module `lib2to3` [missing-import]
+ ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_long.pyi:1:1-31: Cannot find module `lib2to3` [missing-import]
+ ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_operator.pyi:1:1-31: Cannot find module `lib2to3` [missing-import]
+ ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_reduce.pyi:1:1-31: Cannot find module `lib2to3` [missing-import]
+ ERROR mypy/typeshed/stdlib/lib2to3/fixes/fix_set_literal.pyi:1:1-31: Cannot find module `lib2to3` [missing-import]
+ ERROR mypy/typeshed/stdlib/lzma.pyi:45:5-40: Cannot find module `_compression` [missing-import]
+ ERROR mypy/typeshed/stdlib/smtpd.pyi:1:8-16: Cannot find module `asynchat` [missing-import]
+ ERROR mypy/typeshed/stdlib/smtpd.pyi:2:8-16: Cannot find module `asyncore` [missing-import]

discord.py (https://github.com/Rapptz/discord.py)
- ERROR discord/utils.py:1454:37-68: Object of class `ZstdDecompressor` has no attribute `decompressobj` [missing-attribute]

attrs (https://github.com/python-attrs/attrs)
- ERROR src/attr/_compat.py:27:16-45: No attribute `get_annotations` in module `annotationlib` [missing-attribute]
+ ERROR src/attr/_compat.py:21:12-25: Cannot find module `annotationlib` [missing-import]
- ERROR src/attr/_compat.py:28:25-45: No attribute `Format` in module `annotationlib` [missing-attribute]

@github-actions
Copy link
Copy Markdown

Primer Diff Classification

✅ 12 improvement(s) | 12 project(s) total | +53, -100 errors

12 improvement(s) across pip, cloud-init, jax, materialize, aioredis, setuptools, comtypes, streamlit, dd-trace-py, mypy, discord.py, attrs.

Project Verdict Changes Error Kinds Root Cause
pip ✅ Improvement -3 bad-argument-type, no-matching-overload parse_versions()
cloud-init ✅ Improvement +2 missing-import parse_versions()
jax ✅ Improvement +1 missing-import find_for_python_version()
materialize ✅ Improvement -1 bad-return find_for_python_version()
aioredis ✅ Improvement +1 missing-import parse_versions()
setuptools ✅ Improvement +7, -74 Removed bad-override errors on distribution attribute has_module()
comtypes ✅ Improvement +1 missing-import find_for_python_version()
streamlit ✅ Improvement +1, -2 missing-import, missing-module-attribute parse_versions()
dd-trace-py ✅ Improvement -16 bad-argument-type parse_versions()
mypy ✅ Improvement +39, -1 missing-import on typeshed stdlib stubs find_for_python_version()
discord.py ✅ Improvement -1 missing-attribute parse_versions()
attrs ✅ Improvement +1, -2 missing-attribute, missing-import parse_versions()
Detailed analysis

✅ Improvement (12)

pip (-3)

The PR implements support for typeshed's stdlib/VERSIONS file, which tracks which stdlib modules are available in which Python versions. distutils is marked as available only in 3.0-3.11, meaning it's unavailable in Python 3.12+. Before this PR, pyrefly would always load distutils stubs regardless of the target Python version, leading to type errors caused by applying stubs for a module that was removed from the stdlib.

The three removed errors all stem from distutils stub type information:

  1. Line 92 (no-matching-overload on scheme.update): With distutils stubs loaded, i.install_lib is typed as str | None (from the distutils.command.install stubs), making the dict literal {"purelib": i.install_lib, "platlib": i.install_lib} have type dict[str, str | None]. Since scheme is dict[str, str], calling scheme.update(dict[str, str | None]) fails because str | None is not assignable to str.

  2. Line 101 (no-matching-overload on os.path.join): The variable prefix at this point could be i.install_userbase (line 98) or i.prefix (line 100), both of which have types from distutils stubs that include None or Any. The resulting type str | Any | None for the first argument to os.path.join causes a no-matching-overload error since os.path.join expects str arguments.

  3. Line 1966 (bad-argument-type on _osx_support.get_platform_osx): The _osx_support module is also a stdlib module with version restrictions in the VERSIONS file. With the stubs loaded, the parameter type dict[str, str] is too narrow for the argument being passed.

With the PR, when targeting Python 3.12+, these distutils and related stubs are correctly excluded based on the VERSIONS file. When the distutils module stubs are not available, the imports on lines 22-25 would cause the distutils types to resolve as Any (or the module to be treated as unavailable), which makes all attribute accesses on distutils objects return Any. Since Any is compatible with all types, the three type errors disappear.

This is an improvement in correctness — pyrefly now correctly models which stdlib modules exist for the configured Python version, avoiding spurious errors from applying stubs for modules that don't exist in the target runtime.

Attribution: The changes in pyrefly/lib/module/typeshed.rs (adding parse_versions(), find_for_python_version(), is_available_for_python_version(), and modules_for_python_version()) and pyrefly/lib/module/finder.rs (the unavailable_stdlib_module check and the modified typeshed lookup using find_for_python_version()) cause pyrefly to respect the stdlib/VERSIONS file. For Python >= 3.12, distutils (marked as 3.0-3.11 in VERSIONS) is no longer resolved from typeshed stubs. This means distutils-related types become unresolved/Any, which removes the strict overload and argument type errors that depended on precise distutils stub types.

cloud-init (+2)

These are correct new errors. The crypt module was removed from the Python stdlib in Python 3.13 (available only in 3.0-3.12 per typeshed VERSIONS). The PR correctly implements version-aware module resolution, and both mypy and pyright agree these imports are invalid for the target Python version. The cloud-init code handles the missing module at runtime via try/except, but the type checker is right to flag that the module doesn't exist for the configured version. This is an improvement in pyrefly's accuracy — it now correctly respects stdlib module availability across Python versions, matching mypy and pyright behavior.
Attribution: The PR adds support for respecting the typeshed stdlib/VERSIONS file. Specifically:

  1. pyrefly/lib/module/typeshed.rs adds parse_versions(), VersionRange, and methods like find_for_python_version() and is_available_for_python_version() that check whether a module is available for the configured Python version.
  2. pyrefly/lib/module/finder.rs modifies find_import_internal() to call ts.find_for_python_version(module, config.[python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs)) instead of ts.find(module), filtering out modules not available for the target Python version.
  3. The VERSIONS file includes crypt: 3.0-3.12, so for Python 3.13+ (the likely default or configured version), crypt is correctly reported as unavailable.
  4. crates/pyrefly_bundled/third_party/typeshed/stdlib/VERSIONS is added with the full version metadata, and crates/pyrefly_bundled/src/lib.rs adds bundled_typeshed_versions() to extract it.

jax (+1)

The compression module is indeed only available in Python 3.14+ per typeshed's VERSIONS file. The JAX code at line 27 does from compression import zstd inside a try/except block, which is a standard pattern for optional imports. Both mypy and pyright also flag this as a missing import. While the code handles the ImportError gracefully at runtime, the type checker is correct to report that this module doesn't exist for the configured Python version. The new error is a true positive: the compression module is not available for the Python version being checked, and pyrefly is correctly reporting it as missing. Whether this is due to explicit stdlib version metadata checking or simply because the module is not found in the available stubs, the end result is the same — the error accurately reflects that the module cannot be resolved.
Attribution: The PR adds support for respecting the typeshed stdlib/VERSIONS file. The key changes are in pyrefly/lib/module/typeshed.rs (adding VersionRange parsing and find_for_python_version()) and pyrefly/lib/module/finder.rs (using is_available_for_python_version() to filter modules). Before this PR, pyrefly would resolve any module that had stubs in typeshed regardless of Python version. Now it correctly checks version ranges. The compression module has compression: 3.14- in the VERSIONS file, so for Python < 3.14 it's now correctly reported as unavailable.

materialize (-1)

The PR makes pyrefly respect the typeshed stdlib/VERSIONS file, which correctly marks distutils as available only for Python 3.0-3.11. For projects targeting Python 3.12+, distutils is no longer resolvable through typeshed stubs, so the bad-return error on line 55 disappears because pyrefly can't determine the return types of distutils.core.run_setup(). When the module can't be resolved, the types of distribution.metadata.name and distribution.metadata.version likely become Unknown/Any, which are assignable to str, making the return type compatible with tuple[str, str]. The original error was technically correct (in the distutils stubs, DistributionMetadata.name and DistributionMetadata.version are typed as str | None), but the removal is a side effect of a correct improvement — pyrefly now properly handles stdlib module availability by Python version. The project may also get a separate module resolution error for distutils. This is an improvement in pyrefly's module resolution accuracy, though it trades a precise type error for a potentially less informative unresolved module situation.
Attribution: The changes in pyrefly/lib/module/typeshed.rs (adding find_for_python_version(), is_available_for_python_version(), and parse_versions()) and pyrefly/lib/module/finder.rs (the unavailable_stdlib_module check and the switch from ts.find(module) to ts.find_for_python_version(module, config.[python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs))) caused pyrefly to no longer resolve distutils for Python 3.12+. Since distutils: 3.0-3.11 is in the VERSIONS file, the module is now correctly treated as unavailable, which means the type information for distutils.core.[run_setup()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs) is no longer available, and the bad-return error disappears.

aioredis (+1)

The distutils module was removed from the Python standard library in Python 3.12 (PEP 632). The typeshed VERSIONS file records distutils: 3.0-3.11. The aioredis project imports from distutils.version import StrictVersion on line 11, which is a real issue for Python 3.12+. Pyright also flags this. The PR intentionally implements version-aware module resolution by reading the typeshed VERSIONS file, and this is correct behavior — distutils genuinely doesn't exist in Python 3.12+. The aioredis project would need to migrate to packaging.version or similar. This is pyrefly correctly catching a real compatibility issue.
Attribution: The PR adds support for respecting the typeshed stdlib/VERSIONS file. Specifically:

  1. pyrefly/lib/module/typeshed.rs adds parse_versions(), VersionRange, and methods like find_for_python_version() and is_available_for_python_version() to the BundledTypeshedStdlib struct.
  2. pyrefly/lib/module/finder.rs modifies find_import_internal() to call ts.find_for_python_version(module, config.[python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs)) instead of ts.find(module), filtering out modules not available for the configured Python version.
  3. The VERSIONS file itself is bundled (added to crates/pyrefly_bundled/third_party/typeshed/stdlib/VERSIONS) and records distutils: 3.0-3.11.

When pyrefly's configured Python version is 3.12+, distutils and its submodules are now correctly reported as unavailable.

setuptools (+7, -74)

Removed bad-override errors on distribution attribute: 12 bad-override false positives removed (Command:2, install_lib:2, bdist_rpm:1, build:1, build_clib:1, build_ext:1, build_py:1, install:1, install_scripts:1, sdist:1), plus 2 bad-param-name-override errors (build_ext:1, FileList:1) for 14 total override-related false positives. Setuptools intentionally overrides distribution with its own Distribution type and has different method signatures. The conflicts arose from pyrefly seeing typeshed's distutils.cmd.Command.distribution type vs setuptools' override. Now that typeshed distutils stubs are excluded for Python 3.12+, these are correctly gone.
Removed bad-argument-type errors from Distribution type conflicts: 38 false positives removed. These arose from two different Distribution types being visible (typeshed's distutils.dist.Distribution vs setuptools' Distribution). With typeshed distutils excluded, only one Distribution type exists.
Removed no-matching-overload errors: 6 false positives removed. These were caused by overload signatures in typeshed's distutils stubs not matching setuptools' actual usage patterns.
Removed unsupported-operation, unexpected-keyword, read-only, bad-assignment, bad-return, bad-specialization, bad-param-name-override errors: 18 false positives removed. All stem from the same root cause: typeshed distutils stubs defining different APIs than setuptools' own distutils implementation.
New no-matching-overload errors: 4 new errors involving Unknown types in copy_file calls. These are borderline — the Unknown types come from untyped attributes, and the overload matching is stricter without typeshed providing type context. 3/4 are pyrefly-only, suggesting these may be too strict.
New bad-assignment errors with Never type: 2 new errors where py_modules has type Never. The Never type strongly suggests an inference failure — pyrefly couldn't determine the correct type for the attribute. This is a minor regression.
New bad-argument-type error: 1 new error where path is int | str | Unknown but os.makedirs expects path types. This is pyrefly-only and arises from imprecise type inference on ChainMap.values(). The ChainMap combines local_vars (str values), sysconfig.get_config_vars() (which returns dict[str, Any] and can include int values like Py_DEBUG), compat_vars (str), and fw.vars(). The int in the union is technically correct since sysconfig config vars can be integers, but at this point in the code the values being iterated are practically always strings at runtime.

Overall: This is a clear net improvement. The PR correctly implements typeshed VERSIONS file support, which is a standard mechanism used by mypy and pyright. The key change is that for Python 3.12+, typeshed's distutils stubs (which define distutils: 3.0-3.11) are no longer loaded. This eliminates 74 false positives that arose from type conflicts between typeshed's distutils stubs and setuptools' own bundled distutils implementation. The 7 new errors are a mix: (1) 2 bad-assignment errors with Never type suggest inference failures (regression), (2) 4 no-matching-overload errors involve Unknown types from untyped code — these are borderline but mostly pyrefly-only, and (3) 1 bad-argument-type with int | str | Unknown is questionable. However, the net effect of removing 74 false positives while adding 7 errors (some of which may be legitimate) is strongly positive.

Attribution: The PR adds stdlib VERSIONS file support in pyrefly/lib/module/typeshed.rs (new BundledTypeshedStdlib methods: has_module(), is_available_for_python_version(), find_for_python_version(), modules_for_python_version()). The find_import_internal() function in pyrefly/lib/module/finder.rs now calls find_for_python_version() instead of find() for non-bundled-typeshed origins, and checks unavailable_stdlib_module to avoid using typeshed third-party stubs that shadow removed stdlib modules. Since distutils: 3.0-3.11 in the VERSIONS file, for Python 3.12+ (setuptools' default), pyrefly no longer loads typeshed's distutils stubs. This means setuptools' own _distutils package is now the sole source of distutils types, eliminating the type conflicts that caused the 74 false positives. The 7 new errors arise because without typeshed's distutils stubs providing certain type information, some types resolve differently (e.g., Unknown propagation from untyped code).

comtypes (+1)

This is a correct new error. The distutils module was removed from the Python standard library in Python 3.12 (PEP 632). The typeshed VERSIONS file records distutils: 3.0-3.11. The PR makes pyrefly respect this metadata, so when the configured Python version is ≥3.12, importing distutils correctly produces a missing-import error. Both mypy and pyright agree with this diagnostic. The code in comtypes/test/setup.py genuinely imports a module that doesn't exist in the target Python version.
Attribution: The PR adds support for respecting the typeshed stdlib/VERSIONS file. Specifically:

  1. pyrefly/lib/module/typeshed.rs now parses the VERSIONS file and adds find_for_python_version() and is_available_for_python_version() methods to BundledTypeshedStdlib.
  2. pyrefly/lib/module/finder.rs now calls ts.find_for_python_version(module, config.[python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs)) instead of ts.find(module) when resolving imports from non-bundled-typeshed origins.
  3. The VERSIONS file includes distutils: 3.0-3.11, so when the configured Python version is 3.12+, distutils is no longer found as a valid stdlib module.
  4. The new test test_removed_stdlib_module_respects_python_version in pyrefly/lib/test/imports.rs explicitly tests this exact scenario.

streamlit (+1, -2)

This is an improvement in error reporting. The annotationlib module is only available in Python 3.14+ (per typeshed's VERSIONS file). The PR correctly implements version-aware module resolution. Previously, pyrefly found the annotationlib stubs but reported two confusing missing-module-attribute errors for Format and ForwardRef. Now it correctly reports a single missing-import error for the entire module, which is the actual root cause. Pyright agrees with this assessment (co-reports the error). The net change is: 1 new correct error, 2 removed misleading errors — better error quality overall.
Attribution: The PR adds stdlib/VERSIONS file parsing in pyrefly/lib/module/typeshed.rs (the parse_versions() function and VersionRange struct) and uses it in pyrefly/lib/module/finder.rs via find_for_python_version() and is_available_for_python_version(). The VERSIONS file contains annotationlib: 3.14-, meaning the module is only available from Python 3.14 onwards. When the project's configured Python version is < 3.14, pyrefly now correctly reports missing-import for the entire module instead of the previous behavior where it found the module stubs but couldn't resolve the attributes properly.

dd-trace-py (-16)

The 16 removed bad-argument-type errors were all about type mismatches when calling Extension.__init__, where Extension was being resolved to distutils.extension.Extension via typeshed stubs. The PR makes pyrefly respect the typeshed stdlib/VERSIONS file, which specifies that distutils is only available for Python 3.0-3.11. For projects targeting Python 3.12+, pyrefly now correctly stops resolving distutils stubs from typeshed.

The actual type errors are real against the distutils stubs: the macros list contains tuples like ("PSUTIL_POSIX", 1) and ("PSUTIL_WINDOWS", 1) where the second element is int, but distutils.extension.Extension.__init__'s define_macros parameter expects list[tuple[str, str | None]] | None. So list[tuple[str, int]] is not assignable to list[tuple[str, str | None]] | None.

The code uses a try/except pattern (lines 44-53) where Extension is imported from setuptools first, falling back to distutils.core only when setuptools is unavailable. Previously, pyrefly may have been resolving Extension to the distutils type stubs (either through the fallback branch or through the distutils stubs being available). With the PR, on Python 3.12+ the distutils stubs are no longer available from typeshed, so Extension resolves only to setuptools.Extension, which either has different type annotations for define_macros that accept int values, or the type is resolved differently such that these errors no longer appear.

Removing these errors is correct behavior — pyrefly should not check against stubs for modules that don't exist in the target Python version. This is an improvement in pyrefly's module resolution accuracy.

Attribution: The PR adds support for the typeshed stdlib/VERSIONS file. Specifically:

  1. pyrefly/lib/module/typeshed.rs adds parse_versions(), VersionRange, and methods like find_for_python_version() and is_available_for_python_version() that check whether a module is available for the configured Python version.
  2. pyrefly/lib/module/finder.rs modifies find_import_internal() to call ts.find_for_python_version(module, config.[python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs)) instead of ts.find(module), filtering out modules not available for the target Python version.
  3. The VERSIONS file specifies distutils: 3.0-3.11, so for Python 3.12+, distutils stubs are no longer resolved, eliminating the bad-argument-type errors that were checking against those stubs.

mypy (+39, -1)

missing-import on typeshed stdlib stubs: 39 new missing-import errors on typeshed's own stdlib stubs. Typeshed is carefully maintained so that for any given Python version, all internal imports resolve correctly — stubs use sys.version_info guards and the VERSIONS file to ensure consistency. These errors indicate the new version filtering has a bug: it's either loading stubs that shouldn't be loaded for the configured version, filtering out modules that should be available, or not properly respecting sys.version_info branch narrowing. All 39 are pyrefly-only (not flagged by mypy or pyright). This is a regression.
removed bad-override on lib2to3: The removed bad-override error on FixExitfunc.start_tree is a consequence of lib2to3 being correctly excluded for the configured Python version (lib2to3 was removed after 3.12). This is neutral/expected — the error disappears because the file is no longer loaded.

Overall: This PR implements version-aware module resolution for typeshed's stdlib. The 39 new missing-import errors all occur in typeshed's own stdlib stubs, and none are flagged by mypy or pyright.

The errors fall into two groups:

  1. Modules only available in Python 3.14+ (e.g., compression.zstd, compression._common._streams, _zstd, annotationlib): These modules were added to typeshed for Python 3.14. If pyrefly is configured for < 3.14, these modules correctly don't exist, but the stubs guard their imports with sys.version_info >= (3, 14) checks, so the imports should never be reached for older versions.

  2. Modules removed in newer Python versions (e.g., asynchat, asyncore, distutils removed after 3.11; lib2to3 removed after 3.12): If the configured Python version is beyond their removal version, these modules correctly don't exist.

The critical observation is in bz2.pyi: line 9 has if sys.version_info >= (3, 14): importing from compression._common._streams, and line 11-12 has else: importing from _compression. The error is reported on line 12 (the else branch). This means either:

  • Pyrefly is configured for Python 3.14+ but is still evaluating the else branch (a version narrowing bug)
  • Pyrefly is configured for Python < 3.14 but _compression is being incorrectly filtered out
  • Both branches are being evaluated regardless of version

Similarly, _zstd.pyi imports from compression.zstd import ... unconditionally (no version guard), but _zstd.pyi itself should only be loaded for Python 3.14+ according to typeshed's VERSIONS file. If pyrefly loads _zstd.pyi but doesn't make compression.zstd available, that's a bug in the version filtering.

Typeshed stubs are carefully maintained to be internally consistent for any given Python version — for any valid version, all imports within loaded stubs resolve correctly. The fact that all 39 errors are pyrefly-only (0/39 in mypy, 0/39 in pyright) confirms these are false positives caused by a bug in the new version-aware resolution. The most likely issue is that pyrefly is applying version filtering to determine which modules exist, but either:

  • Not correctly applying version filtering to determine which stub files get loaded in the first place
  • Not properly interacting with sys.version_info guards when narrowing which branches to type-check
  • Loading stubs for one version but resolving imports for another

The removed bad-override on lib2to3 is expected — the module is correctly excluded for the configured version, so the file is no longer loaded.

Overall, 39 new false positive missing-import errors on typeshed's own internally-consistent stubs is a regression.

Attribution: The PR adds support for respecting the stdlib/VERSIONS file in typeshed. Key changes:

  1. pyrefly/lib/module/typeshed.rs — Added VersionRange parsing and find_for_python_version() / is_available_for_python_version() methods that filter modules based on the configured Python version.
  2. pyrefly/lib/module/finder.rs — Modified find_import_internal() to call find_for_python_version() instead of find() for non-bundled-typeshed origins, and find_import_prefixes() to use modules_for_python_version().
  3. crates/pyrefly_bundled/src/lib.rs — Added bundled_typeshed_versions() to extract the VERSIONS file from the archive.

The 39 new missing-import errors occur because modules like asynchat (removed 3.12), asyncore (removed 3.12), _compression (removed 3.14), compression.zstd (added 3.14), _zstd (added 3.14), lib2to3 (removed 3.13), distutils (removed 3.12), etc. are now correctly filtered based on the configured Python version. The mypy project's configured Python version causes these modules to be unavailable.

discord.py (-1)

This is a clear improvement. The PR fixes pyrefly to respect typeshed's stdlib/VERSIONS file, which specifies which stdlib modules are available for which Python versions. The compression module (including compression.zstd) was added in Python 3.14. Before this fix, pyrefly was incorrectly resolving ZstdDecompressor to the compression.zstd stdlib stub even for earlier Python versions, and that stub doesn't have decompressobj. The zstandard third-party library's ZstdDecompressor does have decompressobj() — it's a well-documented API. Removing this false positive is correct behavior.
Attribution: The PR adds VERSIONS file parsing in pyrefly/lib/module/typeshed.rs (the parse_versions() function and VersionRange struct) and uses it in pyrefly/lib/module/finder.rs via find_for_python_version() and is_available_for_python_version(). Before this change, pyrefly would find compression.zstd.ZstdDecompressor in the bundled typeshed stdlib stubs regardless of the target Python version. Since compression is only available from Python 3.14+, and discord.py likely targets an earlier version, pyrefly was incorrectly resolving the import to the stdlib stub. The stdlib compression.zstd.ZstdDecompressor stub apparently doesn't define decompressobj, causing the false positive. Now that pyrefly respects VERSIONS, it correctly excludes compression.zstd for pre-3.14 Python versions, so the ZstdDecompressor from the zstandard third-party package (which has decompressobj) is used instead, or the import is simply treated as untyped (with # type: ignore).

attrs (+1, -2)

This is a net improvement. Previously, pyrefly found annotationlib in typeshed regardless of Python version, but then produced two false-positive missing-attribute errors because it couldn't properly resolve the module's contents. Now, pyrefly respects the VERSIONS file and correctly reports that annotationlib cannot be found for the configured Python version (< 3.14). The new missing-import error is correct — pyright also flags it — because annotationlib genuinely doesn't exist before Python 3.14. The code guards this with if PY_3_14_PLUS: at runtime, but type checkers that don't narrow on version checks will flag the import. The two removed false positives (claiming get_annotations and Format don't exist on annotationlib when they do) are clearly wrong errors being removed. Net: -2 false positives, +1 correct error = improvement.
Attribution: The PR adds support for respecting the typeshed stdlib/VERSIONS file. The key changes are in pyrefly/lib/module/typeshed.rs (adding VersionRange, parse_versions(), find_for_python_version(), is_available_for_python_version()) and pyrefly/lib/module/finder.rs (using find_for_python_version() instead of find() for non-bundled-typeshed origins, and filtering unavailable modules). Since annotationlib is listed as annotationlib: 3.14- in the VERSIONS file, and the project is presumably configured for Python < 3.14, pyrefly now correctly reports missing-import instead of finding the module but failing on its attributes.


Was this helpful? React with 👍 or 👎

Classification by primer-classifier (12 LLM)

@asukaminato0721 asukaminato0721 marked this pull request as ready for review April 10, 2026 09:42
Copilot AI review requested due to automatic review settings April 10, 2026 09:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Pyrefly’s bundled typeshed integration to respect typeshed’s stdlib/VERSIONS metadata so that stdlib module availability is gated by the active python_version (e.g., distutils is rejected on Python 3.12+), and removed stdlib names no longer leak back into prefix completions via third-party stubs.

Changes:

  • Bundle typeshed/stdlib/VERSIONS and expose it via pyrefly_bundled::bundled_typeshed_versions().
  • Parse VERSIONS into version ranges and use it to gate stdlib module lookup and module-prefix enumeration by Python version.
  • Add tests covering version-gated import failures and prefix filtering.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pyrefly/lib/test/imports.rs Adds a regression test ensuring distutils import fails on Python 3.12.
pyrefly/lib/module/typeshed.rs Parses stdlib/VERSIONS and adds Python-version-aware stdlib module filtering APIs + unit test.
pyrefly/lib/module/finder.rs Gates bundled-stdlib resolution and prefix results by configured Python version; avoids third-party shadowing of removed stdlib.
crates/pyrefly_bundled/update.py Ensures stdlib/VERSIONS is included when trimming the upstream typeshed archive.
crates/pyrefly_bundled/third_party/typeshed/stdlib/VERSIONS Adds the typeshed stdlib version-availability metadata file to the repo.
crates/pyrefly_bundled/src/lib.rs Generalizes archive extraction and adds bundled_typeshed_versions() + test.
crates/pyrefly_bundled/build.rs Adds rerun-if-changed for stdlib/VERSIONS to keep the bundle up to date.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +44 to +48
min: min.parse()?,
max: if max.is_empty() {
None
} else {
Some(max.parse()?)
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stdlib/VERSIONS entries are major.minor ranges (e.g. distutils: 3.0-3.11), but this parses the max as PythonVersion { micro: 0 }. Since interpreter discovery records the full X.Y.Z (see PythonEnvironment::get_env_from_interpreter), a runtime like Python 3.11.9 will compare as > 3.11.0 and incorrectly mark modules as unavailable.

Suggestion: compare version ranges using only (major, minor), or normalize the parsed max to include all micros (e.g. treat 3.11 as 3.11.* by setting micro to u32::MAX). It would also be good to add a test that uses a non-zero micro (e.g. 3.11.9) to prevent regressions.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Respect VERSIONS file in typeshed

2 participants