Skip to content

fix Respect VERSIONS file in typeshed #2535#3093

Open
asukaminato0721 wants to merge 4 commits intofacebook:mainfrom
asukaminato0721:2535
Open

fix Respect VERSIONS file in typeshed #2535#3093
asukaminato0721 wants to merge 4 commits 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

This comment has been minimized.

@github-actions

This comment has been minimized.

@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 thread pyrefly/lib/module/typeshed.rs
Copy link
Copy Markdown
Contributor

@connernilsen connernilsen left a comment

Choose a reason for hiding this comment

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

Hey @asukaminato0721, thanks for adding this functionality! Just a few requests and then I think we should be good to import.

Comment thread pyrefly/lib/module/typeshed.rs
Comment thread crates/pyrefly_bundled/src/lib.rs Outdated
Comment thread pyrefly/lib/module/finder.rs
Comment thread pyrefly/lib/module/finder.rs
Comment thread pyrefly/lib/module/finder.rs
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@connernilsen
Copy link
Copy Markdown
Contributor

The changes look good, but seems like there's a failing test now. Can you fix? I'll pull in afterward

Copy link
Copy Markdown
Contributor

@connernilsen connernilsen left a comment

Choose a reason for hiding this comment

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

Requesting changes for the broken test

@asukaminato0721
Copy link
Copy Markdown
Contributor Author

cargo test test::simple::test_tstring
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.14s
     Running unittests lib/lib.rs (target/debug/deps/pyrefly-fc4c0f0a68e04b9c)

running 1 test
test test::simple::test_tstring ... ok

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@connernilsen
Copy link
Copy Markdown
Contributor

Hmm, maybe it's some error on the base revision of your PR. I'll try pulling this in to see if I still see it.

Copy link
Copy Markdown
Contributor

@connernilsen connernilsen left a comment

Choose a reason for hiding this comment

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

Sorry, two more things I caught in a last review

Comment thread pyrefly/lib/module/finder.rs Outdated
Comment thread crates/pyrefly_bundled/src/lib.rs Outdated
@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]

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: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:238: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:318: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:318:51-77: No matching overload found for function `posixpath.join` called with arguments: (Unknown | None, Unknown) [no-matching-overload]
- 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-override-param-name]
- 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-override-param-name]
- 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/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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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` 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/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/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/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:1455: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

✅ 10 improvement(s) | 10 project(s) total | +49, -89 errors

10 improvement(s) across pip, cloud-init, 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 find_for_python_version()
cloud-init ✅ Improvement +2 missing-import find_for_python_version()
aioredis ✅ Improvement +1 missing-import parse_versions()
setuptools ✅ Improvement +7, -64 Removed false positives from incorrect distutils resolution parse_versions()
comtypes ✅ Improvement +1 missing-import parse_versions()
streamlit ✅ Improvement +1, -2 missing-import, missing-module-attribute find_for_python_version()
dd-trace-py ✅ Improvement -16 bad-argument-type parse_versions()
mypy ✅ Improvement +36, -1 missing-import on version-gated typeshed modules 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 (10)

pip (-3)

The PR makes pyrefly respect typeshed's stdlib/VERSIONS metadata, which specifies that distutils is available only for Python 3.0-3.11. Previously, pyrefly would load distutils stubs regardless of the target Python version. When checking pip's code against Python 3.12+, the stubs from setuptools' third-party package could leak in (as the PR description notes), producing type errors that shouldn't occur because the module shouldn't be resolvable at all.

For the first error (line 92), i.install_lib comes from distutils stubs where it's typed as str | None, making the dict literal {"purelib": i.install_lib, "platlib": i.install_lib} have type dict[str, str | None]. The scheme variable is dict[str, str], and MutableMapping.update with a dict[str, str | None] argument doesn't match because str | None is not assignable to str. This is a legitimate type concern when distutils stubs are loaded, but becomes a false positive when distutils shouldn't be available for the target Python version.

For the second error (line 101), prefix at that point can be str | None (from the function parameter home), or Any (from i.install_userbase or i.prefix as typed in distutils stubs). The os.path.join call with a potentially None first argument triggers the no-matching-overload error. Again, this is a consequence of distutils stubs being incorrectly loaded.

For the third error (line 1966 of distlib/util.py), _osx_support.get_platform_osx expects dict[str, str] but receives dict[str, int | str] | dict[str, Any]. This error is also related to how stdlib stubs are resolved for the target Python version.

All three errors are false positives that are correctly removed by making pyrefly respect the Python version constraints in typeshed's VERSIONS file, which prevents distutils (and potentially other version-constrained stdlib modules) from being incorrectly resolved when targeting Python 3.12+.

Attribution: The changes in pyrefly/lib/module/typeshed.rs (adding BundledTypeshedStdlib::[find_for_python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs), is_available_for_python_version(), parse_versions(), and the VersionRange struct) and pyrefly/lib/module/finder.rs (the find_import_internal() changes that call ts.[find_for_python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs) instead of ts.find() for non-typeshed origins, and the find_import_prefixes() changes filtering by modules_for_python_version()) are responsible. These changes make pyrefly respect the stdlib/VERSIONS file from typeshed, so modules like distutils (marked 3.0-3.11) are no longer available when checking against Python 3.12+. This eliminates the false downstream errors that arose from incorrectly resolving distutils types.

cloud-init (+2)

The crypt module was part of the Python stdlib from 3.0 through 3.12 and was removed in 3.13. The typeshed VERSIONS file records this as crypt: 3.0-3.12. The PR makes pyrefly respect this metadata, so when the configured Python version is 3.13+, import crypt correctly produces a missing-import error. Both mypy and pyright agree with this diagnosis. The cloud-init code handles this gracefully with try/except ImportError, but the type checker is correct to flag that the module doesn't exist in the stdlib for the target Python version. This is a genuine improvement — pyrefly now correctly models stdlib module availability across Python versions, matching the behavior of mypy and pyright.
Attribution: The changes in pyrefly/lib/module/typeshed.rs (new BundledTypeshedStdlib methods like find_for_python_version(), is_available_for_python_version(), version_range(), and modules_for_python_version()) combined with the changes in pyrefly/lib/module/finder.rs (the find_import_internal() function now calls ts.[find_for_python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs) instead of ts.find() for non-typeshed origins) cause pyrefly to gate stdlib module resolution by the configured Python version. The VERSIONS file entry crypt: 3.0-3.12 means that when cloud-init is checked against Python 3.13+, import crypt correctly resolves to a missing-import error.

aioredis (+1)

The distutils module was removed from CPython's standard library in Python 3.12 (PEP 632). The typeshed stdlib/VERSIONS file records distutils: 3.0-3.11. The aioredis project imports from distutils.version import StrictVersion at line 11 of connection.py. This import genuinely fails at runtime on Python 3.12+ unless setuptools is installed as a third-party dependency. Pyrefly is now correctly respecting the typeshed VERSIONS metadata to flag this as a missing import when the configured Python version is 3.12+. Pyright also flags this (confirmed by the cross-check annotation). This is a correct new error catching a real compatibility issue in the aioredis codebase (which is archived and unmaintained).
Attribution: The PR adds stdlib/VERSIONS parsing in pyrefly/lib/module/typeshed.rs (the parse_versions() function and VersionRange struct), and modifies pyrefly/lib/module/finder.rs to call find_for_python_version() instead of find() when resolving stdlib imports. This gates bundled stdlib modules by the active python_version, so distutils (which has range 3.0-3.11 in VERSIONS) is correctly rejected when the configured Python version is 3.12+. The PR's own test test_removed_stdlib_module_respects_python_version explicitly tests this exact scenario with import distutils on Python 3.12.

setuptools (+7, -64)

Removed false positives from incorrect distutils resolution: 64 errors removed across bad-argument-type, no-matching-overload, unsupported-operation, unexpected-keyword, read-only, bad-assignment, bad-override, bad-return, bad-override-param-name, bad-specialization. All caused by pyrefly resolving distutils from typeshed stdlib stubs on Python 3.12+ instead of letting setuptools's bundled _distutils be the canonical source. Removing these is correct.
New Never-type inference failures: 2 new bad-assignment errors with Never type in setuptools/config/pyprojecttoml.py. The Never type for py_modules attribute indicates a type inference failure, not a real bug. These are minor regressions.
New no-matching-overload errors: 4 new no-matching-overload errors for copy_file and exclude_pattern. Only 1/4 confirmed by pyright. These appear to stem from Unknown-typed arguments not matching overload signatures after the resolution change. Borderline — could be real issues with untyped code or could be overly strict matching.
New bad-argument-type for os.makedirs: 1 new error where path from ChainMap.values() includes int in its union type. The config_vars ChainMap is constructed from local_vars (string values), sysconfig.get_config_vars() (which returns dict[str, Any] and can include int values like SIZEOF_VOID_P, Py_DEBUG, etc.), compat_vars (string values), and fw.vars(). The int in int | str | Unknown comes from sysconfig's int-valued config vars, not from 0o700 (which is the second argument to os.makedirs). The str(path).startswith(home) guard converts path to string for comparison but does not narrow the type of path itself — the original unnarrowed value is passed to os.makedirs. This is a legitimate type concern but practically the code is unlikely to hit non-string paths that also match the home prefix. Pyrefly-only, not flagged by mypy or pyright.

Overall: This is a net improvement. The PR correctly implements stdlib version gating per typeshed's VERSIONS file. The 64 removed errors were false positives caused by pyrefly incorrectly resolving distutils from typeshed's stdlib stubs on Python 3.12+ (where distutils was removed). This caused type conflicts between setuptools's bundled _distutils and typeshed's distutils types.

Of the 7 new errors:

  • 2 bad-assignment errors with Never type (Unknown | None not assignable to py_modules with type Never) are inference failures — the Never type indicates pyrefly failed to resolve the attribute type correctly. These are minor regressions.
  • 4 no-matching-overload errors for copy_file and exclude_pattern — these appear to be from setuptools's bundled distutils calling methods where the overload signatures don't match the Unknown-typed arguments. These are borderline — the Unknown types suggest incomplete type information.
  • 1 bad-argument-type for os.makedirs(path, 0o700) where path is int | str | Unknown from self.config_vars.values()sysconfig.get_config_vars() returns dict[str, Any] which can include int values (e.g., SIZEOF_VOID_P, Py_DEBUG), so the int in the union comes from sysconfig, not from 0o700. The path variable is iterated from self.config_vars.values() and passed directly to os.makedirs() without type narrowing (the str(path).startswith(home) guard converts to string for comparison but doesn't narrow the type of path itself). This is a legitimate type concern but practically unlikely to cause issues at runtime.

The net effect is 64 false positives removed and ~7 new errors added (2 of which contain Never suggesting inference issues). The ratio strongly favors improvement.

Attribution: The changes in pyrefly/lib/module/typeshed.rs (adding parse_versions(), find_for_python_version(), modules_for_python_version(), is_available_for_python_version(), is_known_but_unavailable_for_python_version()) and pyrefly/lib/module/finder.rs (the unavailable_stdlib_module check in find_import_internal() and version filtering in find_import_prefixes()) are the core changes. These make pyrefly respect typeshed's stdlib/VERSIONS file, so on Python 3.12+ distutils is no longer resolved from typeshed's stdlib stubs. The crates/pyrefly_bundled/src/lib.rs changes extract the VERSIONS file from the bundled archive. This eliminates the false type conflicts between setuptools's bundled distutils and typeshed's stdlib distutils stubs.

comtypes (+1)

This is a correct new error. distutils was removed from the Python stdlib in 3.12 (PEP 632), and the typeshed VERSIONS file records distutils: 3.0-3.11. The PR makes pyrefly respect this metadata, so from distutils.core import setup is now correctly flagged as a missing import when the configured Python version is 3.12+. Both mypy and pyright agree with this error. The comtypes test file genuinely depends on a removed module — this is a real issue in the code, not a false positive.
Attribution: The PR adds stdlib/VERSIONS parsing to pyrefly's bundled typeshed resolution. Specifically, parse_versions() in pyrefly/lib/module/typeshed.rs reads the VERSIONS file, and find_for_python_version() gates module resolution on the active python_version. In pyrefly/lib/module/finder.rs, the find_import_internal() function 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) for non-typeshed origins. Since distutils is listed as 3.0-3.11 in VERSIONS, it is correctly rejected when python_version >= 3.12. The comtypes project's test/setup.py imports distutils.core, which is now flagged as missing.

streamlit (+1, -2)

This is a clear improvement. The annotationlib module was introduced in Python 3.14 (per typeshed VERSIONS: annotationlib: 3.14-). Previously, pyrefly found the module in bundled typeshed regardless of Python version, then reported confusing missing-module-attribute errors for Format and ForwardRef. Now, with version-aware resolution, pyrefly correctly reports that the entire module cannot be found for Python versions < 3.14, which is a single, accurate missing-import error. This replaces two misleading errors with one correct error. Pyright also flags this as an error, confirming the diagnosis.
Attribution: The PR adds typeshed's stdlib/VERSIONS file to the bundled data and implements version-gated module resolution in pyrefly/lib/module/typeshed.rs (specifically 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 configured Python version is < 3.14, find_for_python_version() returns None, causing the module to not be found at all — hence the missing-import error instead of the previous missing-module-attribute errors. The finder changes in pyrefly/lib/module/finder.rs apply this version filtering in find_import_internal().

dd-trace-py (-16)

All 16 removed errors are bad-argument-type errors in ddtrace/vendor/psutil/setup.py related to distutils.extension.Extension.__init__. The PR makes pyrefly respect typeshed's stdlib/VERSIONS file, which specifies distutils: 3.0-3.11. On Python 3.12+, distutils is no longer part of the stdlib and pyrefly now correctly stops resolving it from bundled typeshed stubs. Previously, pyrefly was loading the distutils stubs even on 3.12+, and since setuptools.Extension inherits from distutils.extension.Extension, the type checker was checking arguments against the distutils stub signature. The macros list in the code contains a mix of tuple[str, int] and tuple[str, str] entries (e.g., ("PSUTIL_POSIX", 1) and ("PSUTIL_SIZEOF_PID_T", "4")), giving it an inferred type like list[tuple[str, int] | tuple[str, str]] which doesn't match the distutils stub's define_macros parameter type of list[tuple[str, str | None]] | None. With the PR, on Python 3.12+, the distutils typeshed stubs are no longer loaded, so these type mismatches against the distutils signature are no longer reported. This is an improvement in pyrefly's module resolution accuracy, as it now correctly respects Python version-based module availability.
Attribution: The changes in pyrefly/lib/module/typeshed.rs (adding parse_versions(), VersionRange, find_for_python_version(), is_available_for_python_version(), and modules_for_python_version()) and pyrefly/lib/module/finder.rs (the find_import_internal() changes that check ts.[find_for_python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs) instead of ts.find(), and the unavailable_stdlib_module guard) are what caused these errors to disappear. On Python 3.12+, distutils is now correctly gated by the VERSIONS file entry distutils: 3.0-3.11, so the bundled distutils stubs are no longer resolved, eliminating the type mismatch errors from the distutils.extension.Extension.__init__ signature.

mypy (+36, -1)

missing-import on version-gated typeshed modules: 36 new false positive errors where typeshed stubs import other typeshed stubs across Python version boundaries. The PR's bypass for bundled typeshed doesn't cover mypy's own typeshed copy at mypy/typeshed/stdlib/. These are internal typeshed cross-references, not user code importing removed modules. All 36 are pyrefly-only (0/36 in mypy, 0/36 in pyright). This is a regression.
removed bad-override on lib2to3: The bad-override error on FixExitfunc.start_tree disappeared because lib2to3 (removed in Python 3.13) is now filtered out by version gating. This is a minor loss of coverage — the override inconsistency is real but the module is genuinely unavailable on the target Python version. Neutral to minor regression.

Overall: The 36 new missing-import errors are regressions. They occur because mypy bundles its own copy of typeshed at mypy/typeshed/stdlib/, and pyrefly is now applying Python version filtering to imports within those stubs. Modules like asyncore (removed in 3.12), compression.zstd (added in 3.14), and _zstd (added in 3.14) are being rejected when imported by other typeshed stubs. The PR's bundled_typeshed_origin bypass only works for pyrefly's own bundled typeshed, not for typeshed copies found on the search path (like mypy's). These are false positives — typeshed stubs legitimately import each other across version boundaries as part of their internal structure. The removed bad-override error is a minor side effect of the same version gating (lib2to3 is filtered out on Python 3.13+), which is arguably correct behavior but represents lost coverage.

Per-category reasoning:

  • missing-import on version-gated typeshed modules: 36 new false positive errors where typeshed stubs import other typeshed stubs across Python version boundaries. The PR's bypass for bundled typeshed doesn't cover mypy's own typeshed copy at mypy/typeshed/stdlib/. These are internal typeshed cross-references, not user code importing removed modules. All 36 are pyrefly-only (0/36 in mypy, 0/36 in pyright). This is a regression.
  • removed bad-override on lib2to3: The bad-override error on FixExitfunc.start_tree disappeared because lib2to3 (removed in Python 3.13) is now filtered out by version gating. This is a minor loss of coverage — the override inconsistency is real but the module is genuinely unavailable on the target Python version. Neutral to minor regression.

Attribution: The PR adds stdlib/VERSIONS-based filtering in pyrefly/lib/module/typeshed.rs (new find_for_python_version() and is_available_for_python_version() methods) and pyrefly/lib/module/finder.rs (the bundled_typeshed_origin check). The intent is that when resolving imports from user code, modules gated by VERSIONS are filtered. However, the code has a special case: if bundled_typeshed_origin { ts.find(module) } else { ts.find_for_python_version(module, config.[python_version()](https://github.com/facebook/pyrefly/blob/main/pyrefly/lib/module/typeshed.rs)) } — meaning imports from within bundled typeshed should bypass version filtering. The 36 new missing-import errors suggest this bypass isn't working correctly for all cases. Looking at the errors: _zstd.pyi imports compression.zstd, asynchat.pyi imports asyncore, compression/zstd/__init__.pyi imports compression.zstd._zstdfile. These are all typeshed-internal imports. The bundled_typeshed_origin check only applies when the importing file's origin is bundled typeshed, but the issue is that the mypy project has its own copy of typeshed at mypy/typeshed/stdlib/ which is NOT bundled typeshed — it's on the search path as regular files. So the bundled_typeshed_origin bypass doesn't apply, and version filtering rejects these cross-version imports within mypy's own typeshed copy.

discord.py (-1)

The analysis is factually correct. The code at line 90 imports ZstdDecompressor from the third-party zstandard package, and at line 95 falls back to importing from compression.zstd (stdlib, Python 3.14+). The third-party zstandard package's ZstdDecompressor does indeed have a decompressobj() method, while the stdlib compression.zstd.ZstdDecompressor (Python 3.14+) does not have this method. If pyrefly was incorrectly resolving the import to the stdlib compression.zstd module (which shouldn't exist on Python < 3.14), it would report the decompressobj attribute as missing. The PR's version-gating of stdlib modules would correctly exclude compression.zstd on Python < 3.14, allowing the third-party zstandard import to be properly resolved, thus fixing the false positive error.
Attribution: The PR adds stdlib VERSIONS file parsing in pyrefly/lib/module/typeshed.rs (the parse_versions() function and find_for_python_version() method) and gates bundled stdlib module resolution by Python version in pyrefly/lib/module/finder.rs (the find_import_internal() function). The compression module is listed as compression: 3.14- in the VERSIONS file. For Python versions < 3.14, compression.zstd.ZstdDecompressor is now correctly unavailable from the stdlib, so pyrefly no longer confuses it with the third-party zstandard.ZstdDecompressor. This removes the false missing-attribute error because the correct type (from zstandard) is now resolved, which does have decompressobj.

attrs (+1, -2)

This is an improvement in error quality. Previously, pyrefly would resolve annotationlib (a 3.14+ module) even when targeting an earlier Python version, then produce confusing downstream errors about missing attributes within the module. Now it correctly reports a single missing-import error because the module doesn't exist for the configured Python version. The net effect is: 1 new correct error replaces 2 confusing/incorrect errors. The new error is also consistent with pyright's behavior. The code in attrs uses a PY_3_14_PLUS guard, but type checkers don't narrow on arbitrary boolean variables — they would need sys.version_info >= (3, 14) for version narrowing. So the error is technically correct for the configured Python version.
Attribution: The PR adds stdlib/VERSIONS parsing in pyrefly/lib/module/typeshed.rs (the parse_versions() function and VersionRange struct) and gates module resolution on Python version via find_for_python_version() in the same file. The find_import_internal() function in 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) for non-typeshed origins. Since annotationlib: 3.14- in the VERSIONS file, and the default Python version is < 3.14, the module is now correctly rejected at the import level rather than being partially resolved.


Was this helpful? React with 👍 or 👎

Classification by primer-classifier (10 LLM)

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

3 participants