Skip to content

Plugin regression with mypy 0.99x: FieldDoesNotExist #1261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
intgr opened this issue Nov 15, 2022 · 4 comments · Fixed by #1329
Closed

Plugin regression with mypy 0.99x: FieldDoesNotExist #1261

intgr opened this issue Nov 15, 2022 · 4 comments · Fixed by #1329
Labels
bug Something isn't working crash "Internal error" crashes from mypy help wanted Extra attention is needed mypy-plugin Issues specific to mypy_django_plugin

Comments

@intgr
Copy link
Collaborator

intgr commented Nov 15, 2022

mypy_django_plugin causes a mypy internal error when running typecheck_tests.py on Django 3.2 source with mypy 0.991. Does not occur with Django 4.0.

See typecheck failures in PR #1260.

I have not yet had the time to investigate this. Any help would be welcome.

  File "/home/runner/work/django-stubs/django-stubs/mypy_django_plugin/transformers/fields.py", line 117, in set_descriptor_types_for_field_callback
  File "/home/runner/work/django-stubs/django-stubs/mypy_django_plugin/transformers/fields.py", line 215, in transform_into_proper_return_type
  File "/home/runner/work/django-stubs/django-stubs/mypy_django_plugin/transformers/fields.py", line 41, in _get_current_field_from_assignment
  File "/opt/hostedtoolcache/Python/3.8.14/x64/lib/python3.8/site-packages/django/db/models/options.py", line 610, in get_field
  File "mypy/checkexpr.py", line 1004, in apply_function_plugin
  File "mypy/checkexpr.py", line 1181, in check_call_expr_with_callee_type
  File "mypy/checkexpr.py", line 1264, in check_call
  File "mypy/checkexpr.py", line 1466, in check_callable_call
  File "mypy/checkexpr.py", line 410, in visit_call_expr
  File "mypy/checkexpr.py", line 4665, in accept
  File "mypy/checkexpr.py", line 530, in visit_call_expr_inner
  File "mypy/nodes.py", line 1841, in accept
/home/runner/work/django-stubs/django-stubs/django-source/tests/model_fields/models.py:176: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
FieldDoesNotExist: RenamedField has no field named 'modelname'
@intgr intgr added bug Something isn't working help wanted Extra attention is needed mypy-plugin Issues specific to mypy_django_plugin crash "Internal error" crashes from mypy labels Nov 15, 2022
@intgr intgr mentioned this issue Dec 8, 2022
@intgr
Copy link
Collaborator Author

intgr commented Jan 9, 2023

Please let me know if this issue affects any real codebase as well. Currently it has only been observed in our CI.

Possible work-around: downgrade to mypy 0.982.

@flaeppe
Copy link
Member

flaeppe commented Jan 22, 2023

From my digging:

RenamedField is declared in Django's test suite like:

class RenamedField(models.Model):
    modelname = models.IntegerField(name="fieldname", choices=((1, 'One'),))

It should be noted that name= isn't a documented argument/feature and it seems that it renames the instance(?) attribute on the model. As such, you'd access the field value like: RenamedField().fieldname. If you do RenamedField().modelname you get a FieldDoesNotExist in your face.

I'm only guessing, but perhaps it could be useful to avoid shadowing? e.g.

class X(models.Model):
    _type = models.IntegerField(name="type")

In any case, the plugin doesn't support the name= argument and we could try to catch FieldDoesNotExist around .get_field(...) here:

if field_name is None:
return None
model_cls = django_context.get_model_class_by_fullname(outer_model_info.fullname)
if model_cls is None:
return None
current_field = model_cls._meta.get_field(field_name)
return current_field

@flaeppe
Copy link
Member

flaeppe commented Jan 22, 2023

I'm suspecting that should be good enough until there would be any support for name= (if at all). Since we check

if field_name is None:
    return None

a couple of lines before. As such, field_name is seen to appear on the class definition (if not None)

@flaeppe
Copy link
Member

flaeppe commented Jan 22, 2023

See my fix in #1329

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working crash "Internal error" crashes from mypy help wanted Extra attention is needed mypy-plugin Issues specific to mypy_django_plugin
Development

Successfully merging a pull request may close this issue.

2 participants