You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm in the process of removing/forbiding the run of mypy via pre-commit/hatch on jupyter_client and likely other places as running via pre-commit/hach can (often?) swallow error.
try to clone jupyter client main, currently 0bce36fb216d228d755f6c1ca3473cfb4e0f29a6, and run:
$ hatch run typing:test # noerror
$ pre-commit run --all-files --hook-stage manual mypy #no error
$ mypy # this works and detect **real** issues.
My guess is pre-commit/hatch create envs just to run those tools, and if something goes wrong and mypy run in those envs, it may find the wrong version of your package.
You should always run mypy in a typing environment. Typing dependencies are not runtime dependencies. Sometimes they are, but sometimes they are not. That's not the problem.
Your hatch task literally just runs pre-commit. So it's not anything to do with hatch, you are just running pre-commit inside hatch.
When you are running mypy without pre-commit, you probably forgot to install the dependencies. If I do that, I get lots of errors, but they all come from missing traitlets ipykernel jupyter_core, which are installed by the pre-commit hook, or types-pexpect types-paramiko types-netifaces types-psutil types-python-dateutil, which are installed by --install-types in the pre-commit hook (though you really should list them explicitly and not use that flag, it will cache better). These are not runtime dependencies, by the way.
If I do all that, it passes, just like the pre-commit hook. So then enforces that you should always run it in pre-commit.
I do have those dependencies installed; and I tried to running it directly i hatch as well (with local modifs), I am aware that that hatch calls pre-commit I find it horrendous to nest that many env but anyway, I was not the one who made those choices). Running via pre-commit did miss a typo in a PR (options not option), and I do not really understand why/when pre-commit swallows errors but it sometime (often) does.
I agree that we should run mypy, but enforcing it via pre-commit seem weird.
Here is the specific commit PR where mypy was not failing because of pre-commit:
jupyter_client[8e73d8af] $ pre-commit run --all-files --hook-stage manual mypy
mypy.....................................................................Passed
jupyter_client[8e73d8af] $ mypy
jupyter_client/session.py:133: error: Incompatible types in assignment (expression has type "None", variable has type Module) [assignment]
orjson = None
^~~~
jupyter_client/session.py: note: In function "orjson_packer":
jupyter_client/session.py:142: error: Unexpected keyword argument "options" for "dumps"; did you mean "option"? [call-arg]
return orjson.dumps(obj, default=json_default, options=options)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
jupyter_client/session.py: note: At top level:
jupyter_client/session.py:157: error: Skipping analyzing "msgpack": module is installed, but missing library stubs or py.typed marker
[import-untyped]
import msgpack # type:ignore[import-not-found]
^
jupyter_client/session.py:157: note: Error code "import-untyped" not covered by "type: ignore" comment
jupyter_client/session.py:157: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
We don't "enforce it" via pre-commit, we just have a check for that which you can skip (with a description these days, too!). If we could find it reliable in tox/nox/hatch, then we could also check for that, but I don't know of a good way to do that reliably.
You are missing msgpack locally, does installing that change things? Missing dependencies cause other failures that look unrelated. Is there a way I can find that commit, is there a link to the PR? I don't see orjson in the code. By the way, IIRC mypy runs faster if orson is installed.
That import tells mypy to treat orjson as Any if it's not installed. It wasn't added to the pre-commit additional_dependencies, so it is Any, and can't tell that there's a mistake. Same happens locally if you don't install orjson. Don't ever do that - add it to pyproject.toml if you have to, that is, it doesn't support typing and you don't want to write stubs.
I'd love improvements to the experience here, there are some quirks:
You need to specify args (even if empty), because the mypy hook has the ignore imports flag (terrible). MyPy could offer their own hook to fix this, I think.
You can't pull dependencies from pyproject.toml; I understand that pre-commit wants to stay general (and the author hates pyproject.toml, and toml in general) - I think prek might fix this eventually though!
You can't lock anything other than mypy and get auto-updates; another thing I think prek might fix eventually
But you do want a controlled environment for mypy, it's not something you should run in a normal environment.
That said, I use mypy in pre-commit in almost every project I work on, including packaging, pybind11, scikit-build-core, cibuildwheel, pipx, check-sdist, nox, boost-histogram, hist, flake8-errmsg, plumbum, and others, and it works perfectly and reliably, never missing anything that a manual run would not.
The commit is part of jupyter/jupyter_client#1064
If you think there are really no issues, feel free to close. It's just not the first time for me that I end up with issue with mypy + precommit (and yes it seems to works great like 99% of the time)
You can't pull dependencies from pyproject.toml; I understand that pre-commit wants to stay general (and the author hates pyproject.toml, and toml in general) - I think prek might fix this eventually though!
This is my biggest reason I never run mypy with pre-commit. Duplicating dependencies between pyproject.toml and .pre-commit.config.yaml is something I'll inevitably screw up. I never never never want to manually keep things in sync :) I also have high hopes for prek solving this problem, but until then my ideal workflow is typechecking in GitHub actions and manually with uv run --only-dev mypy. I would like to not have to think about what dependency groups I need for running a task, and I'm hoping uv provides pixi-like task running functionality to solve this as well.
My other reason to avoid pre-commit for mypy is that it isn't fast enough for something that happens at commit time my taste, but that's subjective. I'm hoping ty solves this one for me ;)
You don't necessarily have these dependencies in pyproject.toml, though. Typing dependencies are not the same as runtime dependencies, and putting them in dev will require uv to solve them together (IIRC there is a way to tell uv to not solve all dependency groups together, but it's something you need to configure. For example, types-PyYAML is only a typing dependency of this project (sp-repo-review), not a runtime dependency. So it is only in .pre-commit-config.yaml.
I find mypy fast enough for pre-commit after it runs the first time. Once ty is stable enough to have a pre-commit hook, I'd be happy to have it checked here too. :)
I'd be interested in allowing alternatives if there's some way to tell they are there. Something like detecting a nox/tox job for typing isn't reliable. I think currently the best way is for a user to have this in their pyproject.toml:
[tool.repo-review.ignore]
PC140 = "Using `uv run --only-dev mypy` to run mypy"
That indicates that it's supported, just via a different mechanism.
You don't necessarily have these dependencies in pyproject.toml, though. Typing dependencies are not the same as runtime dependencies, and putting them in dev will require uv to solve them together (IIRC there is a way to tell uv to not solve all dependency groups together, but it's something you need to configure. For example, types-PyYAML is only a typing dependency of this project (sp-repo-review), not a runtime dependency. So it is only in .pre-commit-config.yaml.
Yeah, understood. I didn't meant to communicate my typing dependencies would always be in my dev group, just that I would prefer to manage my dependencies using groups and not have to sync anything to .pre-commit-config.yaml. I would replace --only-dev with --no-dev --group typing or something to solve that problem!
Activity
Carreau commentedon Dec 11, 2025
see python/mypy#13916
henryiii commentedon Dec 11, 2025
You should always run mypy in a typing environment. Typing dependencies are not runtime dependencies. Sometimes they are, but sometimes they are not. That's not the problem.
Your hatch task literally just runs pre-commit. So it's not anything to do with hatch, you are just running pre-commit inside hatch.
When you are running mypy without pre-commit, you probably forgot to install the dependencies. If I do that, I get lots of errors, but they all come from missing
traitlets ipykernel jupyter_core, which are installed by the pre-commit hook, ortypes-pexpect types-paramiko types-netifaces types-psutil types-python-dateutil, which are installed by--install-typesin the pre-commit hook (though you really should list them explicitly and not use that flag, it will cache better). These are not runtime dependencies, by the way.If I do all that, it passes, just like the pre-commit hook. So then enforces that you should always run it in pre-commit.
Carreau commentedon Dec 11, 2025
I do have those dependencies installed; and I tried to running it directly i hatch as well (with local modifs), I am aware that that hatch calls pre-commit I find it horrendous to nest that many env but anyway, I was not the one who made those choices). Running via pre-commit did miss a typo in a PR (options not option), and I do not really understand why/when pre-commit swallows errors but it sometime (often) does.
I agree that we should run mypy, but enforcing it via pre-commit seem weird.
Carreau commentedon Dec 11, 2025
Here is the specific commit PR where mypy was not failing because of pre-commit:
henryiii commentedon Dec 11, 2025
We don't "enforce it" via pre-commit, we just have a check for that which you can skip (with a description these days, too!). If we could find it reliable in tox/nox/hatch, then we could also check for that, but I don't know of a good way to do that reliably.
You are missing
msgpacklocally, does installing that change things? Missing dependencies cause other failures that look unrelated. Is there a way I can find that commit, is there a link to the PR? I don't seeorjsonin the code. By the way, IIRC mypy runs faster if orson is installed.henryiii commentedon Dec 11, 2025
I found the PR at jupyter/jupyter_client#1064, pre-commit is working perfectly.
That import tells mypy to treat
orjsonasAnyif it's not installed. It wasn't added to the pre-commitadditional_dependencies, so it isAny, and can't tell that there's a mistake. Same happens locally if you don't installorjson. Don't ever do that - add it to pyproject.toml if you have to, that is, it doesn't support typing and you don't want to write stubs.henryiii commentedon Dec 11, 2025
I'd love improvements to the experience here, there are some quirks:
args(even if empty), because the mypy hook has the ignore imports flag (terrible). MyPy could offer their own hook to fix this, I think.But you do want a controlled environment for mypy, it's not something you should run in a normal environment.
That said, I use mypy in pre-commit in almost every project I work on, including
packaging,pybind11,scikit-build-core,cibuildwheel,pipx,check-sdist,nox,boost-histogram,hist,flake8-errmsg,plumbum, and others, and it works perfectly and reliably, never missing anything that a manual run would not.Carreau commentedon Dec 12, 2025
The commit is part of jupyter/jupyter_client#1064
If you think there are really no issues, feel free to close. It's just not the first time for me that I end up with issue with mypy + precommit (and yes it seems to works great like 99% of the time)
mfisher87 commentedon Feb 28, 2026
This is my biggest reason I never run mypy with pre-commit. Duplicating dependencies between pyproject.toml and .pre-commit.config.yaml is something I'll inevitably screw up. I never never never want to manually keep things in sync :) I also have high hopes for prek solving this problem, but until then my ideal workflow is typechecking in GitHub actions and manually with
uv run --only-dev mypy. I would like to not have to think about what dependency groups I need for running a task, and I'm hopinguvprovidespixi-like task running functionality to solve this as well.My other reason to avoid pre-commit for mypy is that it isn't fast enough for something that happens at commit time my taste, but that's subjective. I'm hoping
tysolves this one for me ;)henryiii commentedon Feb 28, 2026
You don't necessarily have these dependencies in pyproject.toml, though. Typing dependencies are not the same as runtime dependencies, and putting them in dev will require uv to solve them together (IIRC there is a way to tell uv to not solve all dependency groups together, but it's something you need to configure. For example,
types-PyYAMLis only a typing dependency of this project (sp-repo-review), not a runtime dependency. So it is only in.pre-commit-config.yaml.I find mypy fast enough for pre-commit after it runs the first time. Once ty is stable enough to have a pre-commit hook, I'd be happy to have it checked here too. :)
henryiii commentedon Feb 28, 2026
I'd be interested in allowing alternatives if there's some way to tell they are there. Something like detecting a nox/tox job for typing isn't reliable. I think currently the best way is for a user to have this in their
pyproject.toml:That indicates that it's supported, just via a different mechanism.
mfisher87 commentedon Mar 1, 2026
Yeah, understood. I didn't meant to communicate my typing dependencies would always be in my
devgroup, just that I would prefer to manage my dependencies using groups and not have to sync anything to.pre-commit-config.yaml. I would replace--only-devwith--no-dev --group typingor something to solve that problem!mfisher87 commentedon Mar 3, 2026
Related: astral-sh/uv#5903