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

'self'-referencing relationship causes crash #626

Closed
jacobjove opened this issue May 29, 2021 · 3 comments · Fixed by #1495
Closed

'self'-referencing relationship causes crash #626

jacobjove opened this issue May 29, 2021 · 3 comments · Fixed by #1495
Labels
bug Something isn't working crash "Internal error" crashes from mypy mypy-plugin Issues specific to mypy_django_plugin

Comments

@jacobjove
Copy link

Traceback

Traceback (most recent call last):
  File "mypy/checkexpr.py", line 3898, in accept
  File "mypy/nodes.py", line 1555, in accept
  File "mypy/checkexpr.py", line 270, in visit_call_expr
  File "mypy/checkexpr.py", line 347, in visit_call_expr_inner
  File "mypy/checkexpr.py", line 852, in check_call_expr_with_callee_type
  File "mypy/checkexpr.py", line 911, in check_call
  File "mypy/checkexpr.py", line 1023, in check_callable_call
  File "mypy/checkexpr.py", line 732, in apply_function_plugin
  File "/Users/jacob/modularhistory/.venv/lib/python3.9/site-packages/mypy_django_plugin/transformers/orm_lookups.py", line 31, in typecheck_queryset_filter
    lookup_type = django_context.resolve_lookup_expected_type(ctx, model_cls, lookup_kwarg)
  File "/Users/jacob/modularhistory/.venv/lib/python3.9/site-packages/mypy_django_plugin/django/context.py", line 335, in resolve_lookup_expected_type
    lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
  File "/Users/jacob/modularhistory/.venv/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1052, in solve_lookup_type
    _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
  File "/Users/jacob/modularhistory/.venv/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1484, in names_to_path
    pathinfos = field.get_path_info(filtered_relation)
  File "/Users/jacob/modularhistory/.venv/lib/python3.9/site-packages/django/db/models/fields/related.py", line 723, in get_path_info
    opts = self.remote_field.model._meta
AttributeError: 'str' object has no attribute '_meta'
apps/trees/models.py:89: : note: use --pdb to drop into pdb

I did some debugging and found that when this 'str' object has no attribute '_meta' error happens, the value of self.remote_field is 'self'.

To Reproduce

Here's the abridged content of my models.py:

"""Based on https://github.com/peopledoc/django-ltree-demo."""

from typing import Type

from django.core.exceptions import ValidationError
from django.db.models.query import QuerySet
from django.utils.translation import ugettext_lazy as _

from core.models.model import Model


class TreeModel(Model):
    """Implements Postgres ltree for self-referencing hierarchy."""

    parent = models.ForeignKey(
        to='self',
        null=True,
        blank=True,
        related_name='children',
        on_delete=models.CASCADE,
        verbose_name=_('parent'),
    )
    name = models.TextField(verbose_name=_('name'))

    # https://docs.djangoproject.com/en/dev/ref/models/options/#model-meta-options
    class Meta:
        abstract = True

    @property
    def siblings(self) -> QuerySet['TreeModel']:
        """Return the model instances's siblings."""
        # Here is where it fails:
        return self.__class__.objects.exclude(id=self.id).filter(parent_id=self.parent_id)
@sobolevn
Copy link
Member

Yes, looks like we need a special case for it. @iacobfred are you interested in working on this?

@jacobjove
Copy link
Author

I'd be willing to give it a shot. I'm only a de facto developer, though, so it's possible that the typeddjango maintainers might be more pleased with someone else's efforts. ; )

@intgr intgr added mypy-plugin Issues specific to mypy_django_plugin crash "Internal error" crashes from mypy labels Nov 11, 2022
@Kircheneer
Copy link
Contributor

Kircheneer commented Mar 20, 2023

I am running into the same problem - I tried reproducing this in the test framework but couldn't get the error there. Can you give me a hint as to what is wrong with this test case? It just passes fine without an error.

-   case: test_self_referencing
    main: |
        from myapp.models import TreeModel
    installed_apps:
        -   myapp
    files:
        -   path: myapp/__init__.py
        -   path: myapp/models.py
            content: |
                from typing import Type

                from django.db import models
                from django.core.exceptions import ValidationError
                from django.db.models.query import QuerySet


                class TreeModel(models.Model):
                    parent = models.ForeignKey(
                        to='self',
                        null=True,
                        blank=True,
                        related_name='children',
                        on_delete=models.CASCADE,
                    )
                    name = models.TextField()

                    class Meta:
                        abstract = True

                    @property
                    def siblings(self) -> QuerySet['TreeModel']:
                        return self.__class__.objects.exclude(pk=self.pk).filter(parent=self.parent)

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

Successfully merging a pull request may close this issue.

4 participants