Skip to content
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

Django 4.0.5 crashes with mypy and django-stubs #1013

Closed
Thorbenl opened this issue Jun 22, 2022 · 5 comments
Closed

Django 4.0.5 crashes with mypy and django-stubs #1013

Thorbenl opened this issue Jun 22, 2022 · 5 comments
Labels
bug Something isn't working crash "Internal error" crashes from mypy mypy-plugin Issues specific to mypy_django_plugin

Comments

@Thorbenl
Copy link

Thorbenl commented Jun 22, 2022

Bug Report

AttributeError: 'NoneType' object has no attribute 'name'

Looks similar to #625

Traceback

Daemon started
Daemon crashed!
Traceback (most recent call last):
  File "mypy/dmypy_server.py", line 230, in serve
  File "mypy/dmypy_server.py", line 273, in run_command
  File "mypy/dmypy_server.py", line 332, in cmd_run
  File "mypy/dmypy_server.py", line 389, in check
  File "mypy/dmypy_server.py", line 424, in initialize_fine_grained
  File "mypy/build.py", line 154, in build
  File "mypy/build.py", line 230, in _build
  File "mypy/build.py", line 2729, in dispatch
  File "mypy/build.py", line 3087, in process_graph
  File "mypy/build.py", line 3185, in process_stale_scc
  File "mypy/build.py", line 2180, in type_check_first_pass
  File "mypy/checker.py", line 325, in check_first_pass
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 1028, in accept
  File "mypy/checker.py", line 1816, in visit_class_def
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 1099, in accept
  File "mypy/checker.py", line 2178, in visit_block
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 839, in accept
  File "mypy/checker.py", line 3984, in visit_decorator
  File "mypy/checker.py", line 848, in check_func_item
  File "mypy/checker.py", line 1033, in check_func_def
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 1099, in accept
  File "mypy/checker.py", line 2178, in visit_block
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 1243, in accept
  File "mypy/checker.py", line 3899, in visit_for_stmt
  File "mypy/checker.py", line 447, in accept_loop
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 1099, in accept
  File "mypy/checker.py", line 2178, in visit_block
  File "mypy/checker.py", line 433, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checker.py", line 431, in accept
  File "mypy/nodes.py", line 1165, in accept
  File "mypy/checker.py", line 2220, in visit_assignment_stmt
  File "mypy/checker.py", line 2414, in check_assignment
  File "mypy/checkexpr.py", line 3993, in accept
  File "mypy/errors.py", line 962, in report_internal_error
  File "mypy/checkexpr.py", line 3991, in accept
  File "mypy/nodes.py", line 1760, in accept
  File "mypy/checkexpr.py", line 305, in visit_call_expr
  File "mypy/checkexpr.py", line 383, in visit_call_expr_inner
  File "mypy/checkexpr.py", line 892, in check_call_expr_with_callee_type
  File "mypy/checkexpr.py", line 957, in check_call
  File "mypy/checkexpr.py", line 1085, in check_callable_call
  File "mypy/checkexpr.py", line 772, in apply_function_plugin
  File "/Users/thorbenluepkes/work/venv/lib/python3.10/site-packages/mypy_django_plugin/transformers/orm_lookups.py", line 40, in typecheck_queryset_filter
    lookup_type = django_context.resolve_lookup_expected_type(ctx, model_cls, lookup_kwarg)
  File "/Users/thorbenluepkes/work/venv/lib/python3.10/site-packages/mypy_django_plugin/django/context.py", line 375, in resolve_lookup_expected_type
    lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
  File "/Users/thorbenluepkes/work/venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1187, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/Users/thorbenluepkes/work/venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1626, in names_to_path
    name = opts.pk.name
AttributeError: 'NoneType' object has no attribute 'name'

To Reproduce

  • django==4.0.5
  • mypy==0.960
  • django-stubs==1.12.0
  • pydantic==1.9.1

Instal these packages and run mypy

Your Environment

  • Mypy version used: 0.960
  • Mypy command-line flags: --pretty --show-error-codes
  • Mypy configuration options from mypy.ini (and other config files): ```
[mypy]
check_untyped_defs = True
#disallow_any_generics = True
#disallow_untyped_calls = True
#disallow_untyped_decorators = True
ignore_errors = False
ignore_missing_imports = True
#implicit_reexport = False
strict_optional = True
allow_redefinition = True
strict_equality = True
no_implicit_optional = True
warn_unused_ignores = True
warn_redundant_casts = True
warn_unused_configs = True
warn_unreachable = True
warn_no_return = True

plugins =
    mypy_django_plugin.main

[mypy.plugins.django-stubs]
django_settings_module = newmarkets.settings
  • Python version used: 3.10.2
  • Operating system and version: Mac OS 12.5

Using a bash script to run dmypy

FILES=$(git ls-files --cached --modified --others \
  --exclude 'venv' \
  --exclude 'node_modules' \
   "$(git rev-parse --show-toplevel)/*.py" | grep -v /migrations/ | grep -v 'test.*.py' | sort | uniq)
CHECK_OPTIONS="--pretty --show-error-codes"
dmypy run -- $CHECK_OPTIONS $FILES

Filters out some django-specific files, and exlucdes nodes modules and virtual env.

It is not an issue on mypy version 0.931 and before. The guys over at Mypy assume its something inside the mypy-django-plugin, you can read more here python/mypy#13005

@Thorbenl Thorbenl added the bug Something isn't working label Jun 22, 2022
@Thorbenl
Copy link
Author

Push.

@sobolevn
Copy link
Member

Hi, we need a minimal repro to be able to fix that 👋

@Thorbenl
Copy link
Author

Thorbenl commented Aug 5, 2022

Hi, we need a minimal repro to be able to fix that 👋

@sobolevn Sorry, pretty difficult for me to create a reproductive repo. Im pretty sure it has to with one of our models, but I would love to debug this and find out where its thrown :(

  File "/Users/thorbenluepkes/work/newmarkets/venv/lib/python3.10/site-packages/mypy_django_plugin/transformers/orm_lookups.py", line 40, in typecheck_queryset_filter
    lookup_type = django_context.resolve_lookup_expected_type(ctx, model_cls, lookup_kwarg)
  File "/Users/thorbenluepkes/work/newmarkets/venv/lib/python3.10/site-packages/mypy_django_plugin/django/context.py", line 375, in resolve_lookup_expected_type
    lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
  File "/Users/thorbenluepkes/work/newmarkets/venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1217, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/Users/thorbenluepkes/work/newmarkets/venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1656, in names_to_path
    name = opts.pk.name
AttributeError: 'NoneType' object has no attribute 'name'

just suggests its some model, but i cant see in which one its thrown..

@wpwood
Copy link

wpwood commented Oct 11, 2022

FYI, I see a similar stack trace (not identical) in django_stubs == 1.12.0. The stack trace is:

Traceback (most recent call last):
  File "mypy/checkexpr.py", line 4619, in accept
  File "mypy/nodes.py", line 1822, in accept
  File "mypy/checkexpr.py", line 385, in visit_call_expr
  File "mypy/checkexpr.py", line 505, in visit_call_expr_inner
  File "mypy/checkexpr.py", line 1155, in check_call_expr_with_callee_type
  File "mypy/checkexpr.py", line 1238, in check_call
  File "mypy/checkexpr.py", line 1438, in check_callable_call
  File "mypy/checkexpr.py", line 995, in apply_function_plugin
  File "/Users/billwoodward/.pyenv/versions/backend-3.9.10/lib/python3.9/site-packages/mypy_django_plugin/transformers/querysets.py", line 180, in extract_proper_type_queryset_values_list
    row_type = get_values_list_row_type(
  File "/Users/billwoodward/.pyenv/versions/backend-3.9.10/lib/python3.9/site-packages/mypy_django_plugin/transformers/querysets.py", line 124, in get_values_list_row_type
    lookup_field_type = get_field_type_from_lookup(
  File "/Users/billwoodward/.pyenv/versions/backend-3.9.10/lib/python3.9/site-packages/mypy_django_plugin/transformers/querysets.py", line 53, in get_field_type_from_lookup
    lookup_field = django_context.resolve_lookup_into_field(model_cls, lookup)
  File "/Users/billwoodward/.pyenv/versions/backend-3.9.10/lib/python3.9/site-packages/mypy_django_plugin/django/context.py", line 366, in resolve_lookup_into_field
    lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
  File "/Users/billwoodward/.pyenv/versions/backend-3.9.10/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1135, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/Users/billwoodward/.pyenv/versions/backend-3.9.10/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1516, in names_to_path
    name = opts.pk.name
AttributeError: 'NoneType' object has no attribute 'name'

Dropping into pdb and getting the value of model_cls in extract_proper_type_queryset_values_list, I get my BaseModel class, which I have been able to whittle down to the very minimal:

from django.db import models

class BaseModel(models.Model):
    pass

Obviously, it used to do more, but I can cause the crash with just this code. Also, this is obviously meant to be an abstract class that other classes inherit from. It used to have abstract = True in the Meta section, but that made no difference.

I am on Django 3.2.16, mypy 0.982, django-stubs 1.12.0.

@intgr intgr added mypy-plugin Issues specific to mypy_django_plugin crash "Internal error" crashes from mypy labels Nov 8, 2022
@flaeppe
Copy link
Member

flaeppe commented Jan 24, 2023

I think this should be closed via: #1328

@intgr intgr closed this as completed Jan 25, 2023
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 mypy-plugin Issues specific to mypy_django_plugin
Development

No branches or pull requests

5 participants