Hi everyone :wave: I’m trying to incorporate `mypy...
# general
s
Hi everyone 👋 I’m trying to incorporate
mypy
as a pants check goal, but I’m having some trouble, specifically with 3rd party plugins. My
mypy.ini
file (see snippet below) declares plugins for pydantic and strawberry, both of which are defined in poetry in my pyproject.toml.
Copy code
[mypy]
plugins = pydantic.mypy, strawberry.ext.mypy_plugin
The problem I’m running into is that mypy can’t import the plugin, despite having run
pants generate-lockfile
recently with the most up-to-date dependencies.
Copy code
mypy.ini:8:1: error: Error importing plugin "pydantic.mypy": No module named 'pydantic'  [misc]
    plugins = pydantic.mypy, strawberry.ext.mypy_plugin
I tried looking through past threads to understand what needs to be done to support 3rd party libraries with mypy, but I’m getting a bit lost.
b
Sorry for the trouble. Can you share your pants.toml file?
w
Hard to debug without the pants.toml - but I've used something like this in the past (fastapi on Pants 2.17):
Copy code
[mypy]
lockfile = "build-support/python/mypy.lock"
version = "mypy==1.2.0"
extra_requirements = ["pydantic"]
mypy.ini
Copy code
[mypy]
plugins = pydantic.mypy
s
Of course!
Copy code
[GLOBAL]
pants_version = "2.20.0"
colors = true

# Packages needed for pants to run various goals
backend_packages = [
  "pants.backend.python",
  "pants.backend.experimental.python.lint.ruff.check",
  "pants.backend.experimental.python.lint.ruff.format",
  "pants.backend.python.typecheck.mypy",
]

[anonymous-telemetry]
enabled = true
repo_id = "88035b17-7ce9-48d2-a168-4d5d20095e4e"

[source]
# Directory structure rooted around a shared modules directory and various services
root_patterns = [
  "/shared",
  "/services",
  "/cron_jobs",
  "/tests",
  "/scripts",
  "/docker/localstack"
]

[python]
# The default interpreter constraints for code in this repo. Individual targets can override
#  this with the `interpreter_constraints` field. See
#  <https://www.pantsbuild.org/docs/python-interpreter-compatibility>.

# Modify this if you don't have Python 3.9 on your machine.
# This can be a range, such as [">=3.8,<3.11"], but it's usually recommended to restrict
# to a single minor version.
interpreter_constraints = ["CPython==3.10.*"]

# Enable the "resolves" mechanism, which turns on lockfiles for user code. See
# <https://www.pantsbuild.org/docs/python-third-party-dependencies>. This also adds the
# `generate-lockfiles` goal for Pants to generate the lockfile for you.
enable_resolves = true

[python.resolves]
python-default = "lockfiles/python-default.lock"

[python-bootstrap]
# We search for interpreters both on the $PATH and in the `$(pyenv root)/versions` folder.
# If you're using macOS, you may want to leave off the <PATH> entry to avoid using the
# problematic system Pythons. See
# <https://www.pantsbuild.org/docs/python-interpreter-compatibility#changing-the-interpreter-search-path>.

search_path = ["<PYENV_LOCAL>"]

[ruff]
config = "ruff.toml"

[mypy]
config = "mypy.ini"
args = ["--show-error-codes", "--pretty", "--show-column-numbers"]
requirements = [
  "pydantic>=2.6.3",
  "sqlalchemy>=2.0.0",
  "strawberry-graphql>=0.217.0",
]
w
Can you provide a rough folder layout of what you're trying to typecheck against where the
mypy.ini
is? I've upgraded my project to 2.20, it seems to still work, but when I put a mypy.ini in the "wrong" place, then everything blew up and I got the same pydantic error
s
My
mypy.ini
file is at the root of my project. I then have most of my code in the top-level shared and services packages.
w
Yeah, that's what I just tested and it fails - whereas when I have my mypy.ini files in the source roots, it seems to work... That's interesting to note
s
Oh interesting, so for your project, there’s a single root package, and you have the mypy.ini within that?
w
Its a monorepo, so per sub-project I had a separate mypy.ini - i havent looked at that project in a while, so I'll need to look at it again tonight to make sure its doing what I think
Man, this bug just rocked my world - I wonder if my mypy config isn't being used in my 2.20 repo.... Intriguing. I'll have to look at this again when I'm back at my computer Anyways, for your case, have you tried something like this? Explicitly specify your resolve? pants.toml
Copy code
[mypy]
install_from_resolve = "python-default"
requirements = ["pydantic>=2.6.3"]
s
I haven’t yet tried the
install_from_resolve
configuration, let me give that a shot
w
Okay, no idea if it'll work - but in my projects, I split up the tooling and tooling deps from the production. Just a force of habit maybe
Sorry, you may not need the
requirements
as I'm guessing pydantic is already in your python-default resolve? I just did a quick shot, and that caused some weird conflicts that I didn't feel like resolving. But, I put a mypy.ini in the root folder, and then did:
Copy code
[mypy]
install_from_resolve = "python-default"
and it seems to work again (confirmed that mypy was using pydantic, and when I change this plugin everything blows up)
s
I think that did the trick! Just to tie up loose ends, any idea why this fix worked?
w
The docs need some tweaks, but generally they're explained here: https://www.pantsbuild.org/2.20/reference/subsystems/mypy#install_from_resolve The "tool" (mypy) needs to be installed with the resolve
👀 1
Otherwise mypy is living off on it's own > The resolve's entire lockfile will be installed, unless specific requirements are listed via the
requirements
option, in which case only those requirements will be installed. This is useful if you don't want to invalidate the tool's outputs when the resolve incurs changes to unrelated requirements. mypy doesnt know about pydantic, essentially
👀 1