Skip to content

RecursionError while checking file #463

Open
@wesmellbetter

Description

@wesmellbetter

I've gotten this error on several files using vscode.

Bug description

When parsing the following a.py:

"""My Trials listing"""

import logging

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.exceptions import BadRequest
from django.db import connection
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from accounts.models import WsbUser
from wsb.forms.my_trials import MyTrialsForm
from wsb.models import Tracker
from wsb.views.find_trials import DisplayTrial
from wsb.views.helpers import build_dog_name, get_high_in_trial
from wsb.views.trial_detail import TrialResult

logger = logging.getLogger(__name__)


@login_required
def my_trials(request):
    """URL entry point view to display all of trials associated with my dogs and ones the user is interested in"""

    dsp_trials = []
    form = None
    have_dogs = False
    choice = "ALL"

    try:
        with connection.cursor() as cursor:
            # make sure there are some My Dogs
            have_dogs = False
            cursor.execute(
                "SELECT pd.dog_id, d.short_name, d.call_name "
                "FROM wsb_packs p, wsb_packdogs pd, wsb_dogs d "
                "WHERE p.user_id = %s and p.pack_type = 'D' and p.id = pd.pack_id and pd.dog_id = d.dog_id "
                "ORDER BY d.dog_id",
                (request.user.id,),
            )
            dogs = cursor.fetchall()
            if dogs:
                have_dogs = True
                # make list of dogs
                dog_choices = [("ALL", "All 'My Dogs'")]
                for dog in dogs:
                    dog_name = build_dog_name(dog[1], dog[2], 0)
                    dog_choices.append((dog[0], dog_name))

                if len(dogs) > 1:
                    form = MyTrialsForm()
                    form.fields["dog_filter"].choices = dog_choices
                else:
                    form = None

                # default to get trials for all 'My Dogs'
                if request.method == "POST":
                    choice = request.POST.get("dog_filter", "ALL")

                # get trials for all 'My Dogs'
                if choice == "ALL":
                    sql = (
                        "SELECT DISTINCT t.event_id, t.start_date, t.open_date, t.close_date, c.club_name, t.city, t.state_id, t.status "
                        "FROM wsb_packs p, wsb_packdogs pd, wsb_results r, wsb_trialclasses tc, wsb_trials t, wsb_clubs c "
                        "WHERE p.user_id = %s and p.pack_type = 'D' and p.id = pd.pack_id and pd.dog_id = r.dog_id "
                        "and r.tc_id = tc.tc_id and tc.event_id = t.event_id and t.club_id = c.id "
                        "ORDER BY t.start_date DESC, t.event_id"
                    )
                    ret = cursor.execute(sql, (request.user.id,))

                # just get trials for single dog
                else:
                    sql = (
                        "SELECT DISTINCT t.event_id, t.start_date, t.open_date, t.close_date, c.club_name, t.city, t.state_id, t.status "
                        "FROM wsb_results r, wsb_trialclasses tc, wsb_trials t, wsb_clubs c "
                        "WHERE r.dog_id = %s "
                        "and r.tc_id = tc.tc_id and tc.event_id = t.event_id and t.club_id = c.id "
                        "ORDER BY t.start_date DESC, t.event_id"
                    )
                    ret = cursor.execute(sql, (choice,))
                # get trials
                trials = ret.fetchall()

                # convert the results to a list of objects
                for trial in trials:
                    t = DisplayTrial(
                        trial[0],
                        trial[1],
                        trial[2],
                        trial[3],
                        trial[4],
                        trial[5],
                        trial[6],
                        trial[7],
                    )
                    # see if trial is cancelled
                    if trial[7] == "C":
                        t.close_date = "Cancelled"
                        t.open_date = ""
                    elif trial[7] == "P":
                        t.close_date = "Pending Approval"
                    elif trial[7] == "R":
                        t.close_date = "Results Posted"
                        t.open_date = ""

                    dsp_trials.append(t)

                # only show dog selection form if there are more than 1 dog
                if len(dog_choices) > 2:
                    form = MyTrialsForm()
                    form.fields["dog_filter"].choices = dog_choices

                tracker = Tracker(
                    name="MyTrials",
                    type="R",
                    parm1=choice,
                    user_id=(
                        None if request.user.id is None else WsbUser(id=request.user.id)
                    ),
                )
                tracker.save()

        if request.htmx:
            return render(
                request,
                "partial/my_trial_list.html",
                {
                    "form": form,
                    "have_dogs": have_dogs,
                    "trials": dsp_trials,
                    "dog": choice,
                },
            )

        return render(
            request,
            "my_trial_list.html",
            {
                "form": form,
                "have_dogs": have_dogs,
                "trials": dsp_trials,
                "dog": choice,
            },
        )

    except Exception as e:
        logger.exception("Some error")
        raise BadRequest("Error generating trial list; ID:TR1") from e


@login_required
def my_trial_detail(request, id):
    """URL entry point to get trial detail info to be displayed (partial page) for MyTrials"""

    my_dogs = []

    # only process if GET request using HTMX
    if request.method == "GET" & request.htmx:
        try:
            trial_results = []

            event_id = id

            if request.GET.get("mode") == "show":
                template_name = "partial/my_trial_detail_show.html"
                logger.info("Show my-trial details for trial ID: %s", event_id)
            else:
                template_name = "partial/my_trial_detail_hide.html"
                hits = ""
                logger.info("Hide my-trial details for trial ID: %s", event_id)

            # get the dog or ALL
            dog_choice = request.GET.get("dog")

            # get the date format from the settings conf file
            date_format = getattr(settings, "DATE_FORMAT", None)

            with connection.cursor() as cursor:
                if dog_choice == "ALL":
                    # get all of the dogs in My Dogs
                    cursor.execute(
                        "SELECT pd.dog_id "
                        "FROM wsb_packs p, wsb_packdogs pd "
                        "WHERE p.user_id = %s and p.pack_type = 'D' and p.id = pd.pack_id",
                        (request.user.id,),
                    )
                    dogs = cursor.fetchall()
                    for dog in dogs:
                        my_dogs.append(dog[0])
                else:
                    my_dogs = [dog_choice]

                # get the trial info
                cursor.execute(
                    "SELECT t.start_date, c.club_name, t.address, t.city, t.state_id, t.status, t.open_date, t.close_date "
                    "FROM wsb_trials t, wsb_clubs c "
                    "WHERE t.club_id = c.id and t.event_id = %s",
                    (event_id,),
                )
                trial = cursor.fetchone()

                if trial is None:
                    logger.warning("No trial found for: %s", event_id)
                    raise BadRequest("Trial not found; ID:TD1")

                # get all of the fields from the query
                trial_date = trial[0]
                trial_club_name = trial[1]
                trial_address = trial[2]
                trial_city = trial[3]
                trial_state = trial[4]
                trial_status = trial[5]
                trial_open_date = trial[6]
                trial_close_date = trial[7]

                if trial_status == "R":
                    trial_status_desc = "Results Posted"
                    class_only = False
                elif trial_status == "P":
                    trial_status_desc = "Trial in Pending Status"
                    class_only = True
                elif trial_status == "C":
                    trial_status_desc = "Trial Cancelled"
                    class_only = True
                else:
                    trial_status_desc = "Trial Approved and Waiting on Results"
                    class_only = True

                trial = DisplayTrial(
                    event_id,
                    trial_date,
                    trial_open_date,
                    trial_close_date,
                    trial_club_name,
                    trial_city,
                    trial_state,
                    trial_status,
                )

                # see if trial is cancelled
                if trial_status == "C":
                    trial.close_date = "Cancelled"
                    trial.open_date = ""
                elif trial_status == "P":
                    trial.close_date = "Pending Approval"
                elif trial_status == "R":
                    trial.close_date = "Results Posted"
                    trial.open_date = ""

                if not request.htmx or request.GET.get("mode") == "show":
                    if dog_choice == "ALL":
                        # go get any class which MyDogs has a Q for the trial
                        cursor.execute(
                            "SELECT tc.tc_id, c.classname, tc.time_limit, tc.num_starters, tc.num_qual, j.name "
                            "FROM wsb_trialclasses tc, wsb_classnames c, wsb_judges j, wsb_packs p, wsb_packdogs pd, wsb_results r "
                            "WHERE p.user_id = %s and p.pack_type = 'D' and p.id = pd.pack_id and pd.dog_id = r.dog_id and r.tc_id = tc.tc_id "
                            "and tc.classes_id = c.class_id and tc.judge_id = j.judge_id and tc.event_id = %s "
                            "ORDER BY c.display_order",
                            (
                                request.user.id,
                                event_id,
                            ),
                        )
                    else:
                        cursor.execute(
                            "SELECT tc.tc_id, c.classname, tc.time_limit, tc.num_starters, tc.num_qual, j.name "
                            "FROM wsb_trialclasses tc, wsb_classnames c, wsb_judges j, wsb_results r "
                            "WHERE r.dog_id = %s and r.tc_id = tc.tc_id "
                            "and tc.classes_id = c.class_id and tc.judge_id = j.judge_id and tc.event_id = %s "
                            "ORDER BY c.display_order",
                            (
                                dog_choice,
                                event_id,
                            ),
                        )
                    trial_classes = cursor.fetchall()

                    for trial_class in trial_classes:
                        # new class, create entry in trial_result list (table header for class results)
                        tr = TrialResult(
                            "C",
                            trial_class[1],
                            trial_class[5],
                            "",
                            "",
                            trial_class[2],
                            "",
                            "",
                        )
                        # add the class to the trial_result list
                        trial_results.append(tr)

                        # see if this trial has any results
                        if trial_status == "R":
                            cursor.execute(
                                "SELECT r.running_time, r.faults, r.place, d.short_name, d.owner, d.call_name, d.dog_id FROM wsb_results r, wsb_dogs d "
                                "WHERE r.dog_id = d.dog_id and r.tc_id = %s ORDER BY r.place, r.running_time ",
                                (trial_class[0],),
                            )
                            results = cursor.fetchall()

                            if results:
                                for result in results:
                                    # create record for each qualifing result
                                    dog_name = build_dog_name(result[3], result[5], 70)

                                    if result[6] in my_dogs:
                                        tr = TrialResult(
                                            "M",
                                            "",
                                            "",
                                            dog_name,
                                            result[4],
                                            result[0],
                                            result[1],
                                            result[2],
                                        )
                                    else:
                                        tr = TrialResult(
                                            "R",
                                            "",
                                            "",
                                            dog_name,
                                            result[4],
                                            result[0],
                                            result[1],
                                            result[2],
                                        )

                                    trial_results.append(tr)
                            else:
                                # no qualifiers so add a dummy record
                                tr = TrialResult(
                                    "R", "", "", "No Qualifiers", "--", "--", "--", "--"
                                )
                                trial_results.append(tr)

                            # create table footer for this class
                            tr = TrialResult(
                                "T", trial_class[3], trial_class[4], "", "", "", "", ""
                            )
                            trial_results.append(tr)

                    # now get high in trial
                    hits = []
                    # get Novice HIT
                    get_high_in_trial(request, cursor, event_id, "N", hits, dog_choice)

                    # get Advanced HIT
                    get_high_in_trial(request, cursor, event_id, "A", hits, dog_choice)

                    # get Excellent  HIT
                    get_high_in_trial(request, cursor, event_id, "E", hits, dog_choice)

                    # get Master HIT
                    get_high_in_trial(request, cursor, event_id, "M", hits, dog_choice)

            # record report in tracker DB
            if not request.htmx or request.GET.get("mode") == "show":
                tracker = Tracker(
                    name="MyTrialDetail",
                    type="R",
                    parm1=dog_choice,
                    parm2=str(event_id),
                    parm3="Classes" if class_only else "Results",
                    user_id=(
                        None if request.user.id is None else WsbUser(id=request.user.id)
                    ),
                )
                tracker.save()

            # go display the page
            return render(
                request,
                template_name,
                {
                    "title": "AKC Scent Work - Trial Detail",
                    "club": trial_club_name,
                    "date": trial_date.strftime(date_format),
                    "location": trial_address + " " + trial_city + ", " + trial_state,
                    "status": trial_status_desc,
                    "class_only": class_only,
                    "results": trial_results,
                    "hits": hits,
                    "trial": trial,
                    "dog": dog_choice,
                },
            )

        except Exception as e:
            logger.exception("error during report")
            raise BadRequest("Error generating Trial Detail; ID:MTD2") from e

    else:
        # not a GET request or HTMX, so return to trial finder criteria page
        return HttpResponseRedirect(reverse("my_trials"))

Command used

pylint a.py

Pylint output

pylint crashed with a ``AstroidError`` and with the following stacktrace:
Traceback (most recent call last):
  File "c:\Users\dougm\.vscode\extensions\ms-python.pylint-2025.2.0\bundled\libs\pylint\lint\pylinter.py", line 788, in _lint_file
    check_astroid_module(module)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "c:\Users\dougm\.vscode\extensions\ms-python.pylint-2025.2.0\bundled\libs\pylint\lint\pylinter.py", line 1020, in check_astroid_module
    retval = self._check_astroid_module(
        ast_node, walker, rawcheckers, tokencheckers
    )
  File "c:\Users\dougm\.vscode\extensions\ms-python.pylint-2025.2.0\bundled\libs\pylint\lint\pylinter.py", line 1072, in _check_astroid_module
    walker.walk(node)
    ~~~~~~~~~~~^^^^^^
  File "c:\Users\dougm\.vscode\extensions\ms-python.pylint-2025.2.0\bundled\libs\pylint\utils\ast_walker.py", line 92, in walk
    callback(astroid)
    ~~~~~~~~^^^^^^^^^
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 339, in ignore_import_warnings_for_related_fields
    return orig_method(self, node)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 339, in ignore_import_warnings_for_related_fields
    return orig_method(self, node)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 339, in ignore_import_warnings_for_related_fields
    return orig_method(self, node)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 339, in ignore_import_warnings_for_related_fields
    return orig_method(self, node)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 339, in ignore_import_warnings_for_related_fields
    return orig_method(self, node)
  
 ..... more of the same ....

  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 339, in ignore_import_warnings_for_related_fields
    return orig_method(self, node)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 766, in wrap_func
    return with_method(orig_method, *args, **kwargs)
  File "c:\drm\Dev\WSB\.venv\Lib\site-packages\pylint_django\augmentations\__init__.py", line 320, in ignore_import_warnings_for_related_fields
    iterat = consumer.to_consume.items if PY3 else consumer.to_consume.iteritems
             ^^^^^^^^^^^^^^^^^^^
RecursionError: maximum recursion depth exceeded

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "c:\Users\dougm\.vscode\extensions\ms-python.pylint-2025.2.0\bundled\libs\pylint\lint\pylinter.py", line 752, in _lint_files
    self._lint_file(fileitem, module, check_astroid_module)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\dougm\.vscode\extensions\ms-python.pylint-2025.2.0\bundled\libs\pylint\lint\pylinter.py", line 790, in _lint_file
    raise astroid.AstroidError from e
astroid.exceptions.AstroidError

Expected behavior

No crash.

Pylint version

pylint 3.3.4
astroid 3.3.8
Python 3.13.2 (tags/v3.13.2:4f8bb39, Feb  4 2025, 15:23:48) [MSC v.1942 64 bit (AMD64)]

OS / Environment

win32 (Windows)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions