pandera icon indicating copy to clipboard operation
pandera copied to clipboard

mypy plugin causes internal error when optional columns are present in DataFrameModel

Open benfogelson opened this issue 2 years ago • 2 comments

Describe the bug A clear and concise description of what the bug is.

  • [X] I have checked that this issue has not already been reported.
  • [X] I have confirmed this bug exists on the latest version of pandera.
  • [X] (optional) I have confirmed this bug exists on the master branch of pandera.

Note: Please read this guide detailing how to provide the necessary information for us to reproduce your bug.

Code Sample, a copy-pastable example

example.py:

from typing import Optional

import pandera as pa

class MyModel(pa.DataFrameModel):
    my_optional_column: Optional[pa.typing.Series[int]]

pyproject.toml:

[tool.mypy]
files = "example.py"
plugins = ["pandera.mypy"]

Shell:

❯ mypy --show-traceback
example.py:5: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.3.0
Traceback (most recent call last):
  File "mypy/semanal.py", line 6269, in accept
  File "mypy/nodes.py", line 1127, in accept
  File "mypy/semanal.py", line 1565, in visit_class_def
  File "mypy/semanal.py", line 1645, in analyze_class
  File "mypy/semanal.py", line 1672, in analyze_class_body_common
  File "mypy/semanal.py", line 1755, in apply_class_plugin_hooks
  File "/rxrx/data/user/ben.fogelson/.pyenv/versions/3.10.11/envs/pandera-mypy-bug/lib/python3.10/site-packages/pandera/mypy.py", line 93, in _pandera_model_class_maker_callback
    transformer.transform()
  File "/rxrx/data/user/ben.fogelson/.pyenv/versions/3.10.11/envs/pandera-mypy-bug/lib/python3.10/site-packages/pandera/mypy.py", line 125, in transform
    self.erase_field_type_arg()
  File "/rxrx/data/user/ben.fogelson/.pyenv/versions/3.10.11/envs/pandera-mypy-bug/lib/python3.10/site-packages/pandera/mypy.py", line 143, in erase_field_type_arg
    if get_typename(def_.type) in FIELD_GENERICS_FULLNAMES:
  File "/rxrx/data/user/ben.fogelson/.pyenv/versions/3.10.11/envs/pandera-mypy-bug/lib/python3.10/site-packages/pandera/mypy.py", line 164, in get_typename
    return f"{x.type.module_name}.{x.type.name}"
AttributeError: 'UnionType' object has no attribute 'type'
example.py:5: : note: use --pdb to drop into pdb

Expected behavior

Given the documentation on annotating a column as optional, I would expect mypy to pass.

Desktop (please complete the following information):

  • OS: Linux
  • Python version: 3.10.11
  • Pandera version: 0.15.1
  • Mypy version: 1.3.0

benfogelson avatar May 30 '23 17:05 benfogelson

I'm hitting this same issue now too. Any insights on this @cosmicBboy?

The docs suggest this should work but it seems to make mypy quite unhappy in a way that pydantic does not.

kr-hansen avatar Jul 12 '23 00:07 kr-hansen

For folks who are encountering this: this PR addresses the issue as a first approximation. As suggested in the PR, recursion (or another approach) would handle nested optionals, but will merge that PR to unblock folks with a shallow optional/union type.

cosmicBboy avatar Oct 31 '23 00:10 cosmicBboy