Thanks to visit codestin.com
Credit goes to github.com

Skip to content

MNT Use pyrefly instead of mypy for type-checking - #34527

Merged
lorentzenchr merged 11 commits into
scikit-learn:mainfrom
MarcoGorelli:pyrefly
Aug 10, 2026
Merged

MNT Use pyrefly instead of mypy for type-checking#34527
lorentzenchr merged 11 commits into
scikit-learn:mainfrom
MarcoGorelli:pyrefly

Conversation

@MarcoGorelli

@MarcoGorelli MarcoGorelli commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Reference Issues/PRs

closes #34502

I've kept .mypy_cache excluded in .gitignore and some other places because contributors probably still have that folder (unchecked) locally, so this will avoid unexpected issue for them

What does this implement/fix? Explain your changes.

First time contributor introduction

AI usage disclosure

I used AI assistance for:

  • Code generation - I got claude to do a first-pass, and then did the rest manually

Any other comments?

@MarcoGorelli MarcoGorelli changed the title WIP Use pyrefly instead of mypy for type-checking WIP MNT Use pyrefly instead of mypy for type-checking Jul 20, 2026
@MarcoGorelli
MarcoGorelli force-pushed the pyrefly branch 3 times, most recently from cb2cb90 to f9bd7ff Compare July 21, 2026 09:04
Comment thread pyproject.toml
Comment on lines +226 to +227
[tool.pyrefly.errors]
bad-override = false

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

there's hundreds of errors from bad-override due to incompatible constructors

mypy (with the current configuration) doesn't flag these

so, for now, i'd suggest not checking this with pyrefly either

# as xfail.
status = "xfail"
else:
status = "failed"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i'm moving this up from L948 so that check_result can be instantiated with all fields present

Comment thread pyproject.toml
[tool.pyrefly]
project-includes = ["sklearn"]
project-excludes = ["**/sklearn/externals*"]
preset = "legacy"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is similar to mypy's current level of strictness. if you want to opt in to a higher level of strictness, I'd suggest leaving that to a separate PR

@MarcoGorelli
MarcoGorelli marked this pull request as ready for review July 21, 2026 09:50
@MarcoGorelli MarcoGorelli changed the title WIP MNT Use pyrefly instead of mypy for type-checking MNT Use pyrefly instead of mypy for type-checking Jul 21, 2026
Comment thread pyproject.toml
@DeaMariaLeon

Copy link
Copy Markdown
Member

I think there is a mypy mention in the documentation, maybe you want to change that as well?
It's in doc/developers/maintainer.rst ("To avoid type checker (e.g. mypy) errors...")

@MarcoGorelli
MarcoGorelli marked this pull request as draft July 21, 2026 15:51
# FutureWarnings
with warnings.catch_warnings():
warnings.simplefilter("ignore", FutureWarning)
# mypy error: Module has no attribute "__path__"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

__path__ doesn't appear here anyway, not sure what this comment was doing here 😄

@MarcoGorelli
MarcoGorelli marked this pull request as ready for review July 22, 2026 09:48
@MarcoGorelli

Copy link
Copy Markdown
Contributor Author

thanks for your review! have addressed

tagging @AnneBeyer and @adrinjalali as they were involved with #32737

@adrinjalali adrinjalali left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is actually a nice improvement to what we have, I like it.

@AnneBeyer wanna have a look?



if TYPE_CHECKING:
# typing_extensions is available when mypy is installed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

still need some sort of a comment here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure thanks - i've rephrased a bit as it's not a dependency of pyrefly (like it is of mypy), but pyrefly can understand its symbols

@lesteve

lesteve commented Aug 7, 2026

Copy link
Copy Markdown
Member

This is actually a nice improvement to what we have, I like it.

@adrinjalali so that we are on a similar page and remember what we were hoping for if we ever merge this PR: what do you like and what is the improvement exactly?

Here are a few guesses, there could be others:

  • pre-commit mypy check can be slowish, maybe a few seconds in the general use case. I noticed it but honestly I am not sure this is a high priority thing to fix.
  • you have high confidence that pyrefly is better-behaved (please add a few details) than mypy and that we are less likely to fight the typechecker. I can see that a few type annotations were removed in this PR, but I have no idea whether it's because pyrefly is "smarter" or whether the config was done in a way to be less pedantic.

My personal feeling is that broadly speaking there is not a strong interest about typing in scikit-learn and my guess is that it is unlikely that we invest time into adding more typing in the medium-term. Switching to a different typechecker (that feels like maybe a bit less standard) feels more like a risk, and the benefits are not 100% clear to me.

Having said this, I wish we were sometimes more adventurous in scikit-learn where possible and switching a developer tool doesn't affect users's experience too much, so I am open to change my mind if there are good arguments 🤷.

@glevv

glevv commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

@lesteve in my experience, the default behaviour of pyrefly is configured to be very compatible with mypy while also is more "forgivable" in some ways.

There is an option to change preset to a stricter one, which will make contributors fight the typecheker for sure.

In general, default preset shouldn't make life harder for anybody and will speed up the check.

@betatim

betatim commented Aug 10, 2026

Copy link
Copy Markdown
Member

I'd be interested in a switch to a type checker that is faster than mypy. I don't really care for static typing in scikit-learn, so reducing the amount of time spent staring at the pre-commit messages waiting for mypy to "do its thing, what ever that might be" is something I'd be happy to support.

At the same time, because I don't find static typing to be all that useful I am interested in keeping type checking related churn down. This means that if we switch we should switch to a type checker that has some history in terms of being well maintained, widely used and still here in a few years time. From my little investigation about type checkers I think pyrefly ticks those boxes, maybe except for the last one??

@lorentzenchr

Copy link
Copy Markdown
Member

I fully agree with what @betatim said and would like to merge this PR.
@lesteve Fine for you?

@AnneBeyer AnneBeyer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you for taking this on @MarcoGorelli!
From what I understand, it doesn't change the behavior (still ignores the things we want to ignore) while cleaning up the code a bit and taking less time, so I would be happy to see this change as well.

Since we have the linting lock files and a running version in this PR, we can always pin it if future updates would create a maintenance overhead on our end.

One thing I noticed when checking out this PR and testing it by committing something (without changing anything in the installation of pre-commit): I didn't have to install pyrefly myself. The first commit took a bit longer, and from what I understand, it was installed automatically in ~/.cache/pre-commit/..., so we might not even have to add it to the installation instructions? In any case, it looks like it will not even disrupt the contributor experience (except for an unexpected delay on the first commit after merging main).

@MarcoGorelli

Copy link
Copy Markdown
Contributor Author

thanks!

for pre-commit, in general, it doesn't require you to install anything, it handles it all for you

so:

  • if you run pre-commit run pyrefly --all-files, no setup (other than having pre-commit installed) is required
  • if you run pyrefly check yourself, you'll need to have pyrefly installed

same for all the other tools, this isn't unique to pyrefly

@AnneBeyer

Copy link
Copy Markdown
Contributor

Ah, that makes sense. Thank you for the clarification! If I understand correctly, this means that, since we instruct contributors to use pre-commit, we could actually remove ruff and pyrefly from the installation instructions, right? This would be something for a follow-up PR, though.

@lesteve

lesteve commented Aug 10, 2026

Copy link
Copy Markdown
Member

@lorentzenchr feel free to merge it and I guess you will be the main person to deal with the consequences if any 😜 🤞.

It seems like the consensus is:

  • as a project we don't care about typing too much
  • the pre-commit checks is fast instead of a few seconds with mypy and it looks like people care about this
  • we make the bet that pyrefly will be stable enough so we don't have to fight with the typechecker too much.

@lorentzenchr
lorentzenchr merged commit 94a85a8 into scikit-learn:main Aug 10, 2026
38 checks passed
@betatim

betatim commented Aug 10, 2026

Copy link
Copy Markdown
Member

Something that we need to look out for is that existing PRs that do not merge main will not use pyrefly when the contributor adds new commits (I think). I'm not sure if the CI for those PRs will use pyrefly or not, I think they will. So there might be some errors due to this. I think the fix is to merge main into the contributors branch and make a commit.

@lesteve

lesteve commented Aug 10, 2026

Copy link
Copy Markdown
Member

Good point, I am not 100% sure what will happen ... as maintainer, it's probably safer to click on "Update branch" and then set automerge rather than merging an not super recent PR directly?

I guess that was implicitly included in "deal with the consequences if any" 😉.

@lesteve

lesteve commented Aug 11, 2026

Copy link
Copy Markdown
Member

For completeness and better awareness, if you push a commit into a branch where mypy is still used (i.e. the vast majority of PRs right now) you will get an error in the linting CI, merging main fixes it.

The error is something like this:

importlib.metadata.PackageNotFoundError: No package metadata was found for pyrefly

I saw this in #34676 (comment).

@lesteve

lesteve commented Aug 11, 2026

Copy link
Copy Markdown
Member

Annoyingly (or at least semi-annoyingly) there is no bot linting comment when linting fails early, I opened #34719 about it.

prady0t pushed a commit to prady0t/scikit-learn that referenced this pull request Sep 2, 2026
@jeremiedbb jeremiedbb mentioned this pull request Sep 8, 2026
14 tasks
jeremiedbb pushed a commit to jeremiedbb/scikit-learn that referenced this pull request Sep 8, 2026
jeremiedbb pushed a commit to jeremiedbb/scikit-learn that referenced this pull request Sep 9, 2026
jeremiedbb pushed a commit to jeremiedbb/scikit-learn that referenced this pull request Sep 9, 2026
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.

Consider switching to pyrefly for typechecking

8 participants