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

Crash for python 3.12 and 3.13, AttributeError: 'TreeRebuilder' object has no attribute 'visit_typealias' (works for 3.9) #10133

Closed
jzohrab opened this issue Dec 11, 2024 · 3 comments
Labels
Duplicate 🐫 Duplicate of an already existing issue

Comments

@jzohrab
Copy link

jzohrab commented Dec 11, 2024

When parsing the following file:

"""
/bookmarks endpoint
"""

from flask import Blueprint, request, render_template, jsonify
from lute.bookmarks.datatables import get_data_tables_list
from lute.models.book import Text, TextBookmark
from lute.models.repositories import BookRepository
from lute.utils.data_tables import DataTablesFlaskParamParser
from lute.db import db

bp = Blueprint("bookmarks", __name__, url_prefix="/bookmarks")


@bp.route("/<int:bookid>/datatables", methods=["POST"])
def datatables_bookmarks(bookid):
    "Get datatables json for bookmarks."
    parameters = DataTablesFlaskParamParser.parse_params(request.form)
    data = get_data_tables_list(parameters, bookid, db.session)
    return jsonify(data)


@bp.route("/<int:bookid>", methods=["GET"])
def bookmarks(bookid):
    "Get all bookarks for given bookid."
    br = BookRepository(db.session)
    book = br.find(bookid)

    text_dir = "rtl" if book.language.right_to_left else "ltr"
    return render_template("bookmarks/list.html", book=book, text_dir=text_dir)


@bp.route("/add", methods=["POST"])
def add_bookmark():
    "Add bookmark"
    data = request.json
    title = data.get("title")
    try:
        book_id = int(data.get("book_id"))
        page_num = int(data.get("page_num"))
    except ValueError:
        return jsonify(
            success=False, reason="Invalid book_id or page_num provided.", status=200
        )

    if book_id is None or page_num is None or title is None:
        return jsonify(
            success=False,
            reason="Missing value for required parameter 'title' or 'book_id' or page_num.",
            status=200,
        )

    tx = (
        db.session.query(Text)
        .filter(Text.bk_id == book_id)
        .filter(Text.order == page_num)
        .first()
    )
    bookmark = TextBookmark(title=title, text=tx)

    db.session.add(bookmark)
    db.session.commit()
    return jsonify(success=True, status=200)


@bp.route("/delete", methods=["POST"])
def delete_bookmark():
    "Delete bookmark"
    data = request.json
    bookmark_id = None
    try:
        bookmark_id = int(data.get("bookmark_id"))
    except ValueError:
        return jsonify(
            success=False,
            reason=f"Invalid bookmark_id ({data.get('bookmark_id')}) provided.",
            status=200,
        )

    if bookmark_id is None:
        return jsonify(
            success=False,
            reason="Missing required parameter 'bookmark_id'.",
            status=200,
        )

    db.session.query(TextBookmark).filter(TextBookmark.id == bookmark_id).delete()
    db.session.commit()
    return jsonify(success=True, status=200)


@bp.route("/edit", methods=["POST"])
def edit_bookmark():
    "Edit bookmark"
    data = request.json
    bookmark_id = None
    try:
        bookmark_id = int(data.get("bookmark_id"))
    except ValueError:
        return jsonify(
            success=False, reason="Invalid bookmark_id provided.", status=200
        )
    new_title = data.get("new_title", "").strip()

    if bookmark_id is None or new_title == "":
        return jsonify(
            success=False,
            reason="Missing value for required parameter 'new_title' or 'bookmark_id'.",
            status=200,
        )

    db.session.query(TextBookmark).filter(TextBookmark.id == bookmark_id).update(
        {"title": new_title}
    )
    db.session.commit()
    return jsonify(success=True, status=200)

pylint crashed with a AstroidError and with the following stacktrace:

Traceback (most recent call last):
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/lint/pylinter.py", line 811, in _lint_file
    check_astroid_module(module)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/lint/pylinter.py", line 1085, in check_astroid_module
    retval = self._check_astroid_module(
        ast_node, walker, rawcheckers, tokencheckers
    )
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/lint/pylinter.py", line 1135, in _check_astroid_module
    walker.walk(node)
    ~~~~~~~~~~~^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/utils/ast_walker.py", line 94, in walk
    self.walk(child)
    ~~~~~~~~~^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/utils/ast_walker.py", line 94, in walk
    self.walk(child)
    ~~~~~~~~~^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/utils/ast_walker.py", line 94, in walk
    self.walk(child)
    ~~~~~~~~~^^^^^^^
  [Previous line repeated 1 more time]
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/utils/ast_walker.py", line 91, in walk
    callback(astroid)
    ~~~~~~~~^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/checkers/typecheck.py", line 1084, in visit_attribute
    inferred = list(node.expr.infer())
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 171, in infer
    yield from self._infer(context=context, **kwargs)
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/bases.py", line 177, in _infer_stmts
    for inf in stmt.infer(context=context):
               ~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/bases.py", line 177, in _infer_stmts
    for inf in stmt.infer(context=context):
               ~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/bases.py", line 177, in _infer_stmts
    for inf in stmt.infer(context=context):
               ~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/bases.py", line 177, in _infer_stmts
    for inf in stmt.infer(context=context):
               ~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/inference.py", line 279, in infer_call
    yield from callee.infer_call_result(caller=self, context=callcontext)
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 2290, in infer_call_result
    if self.is_subtype_of("builtins.type", context) and len(caller.args) == 3:
       ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 2238, in is_subtype_of
    return any(anc.qname() == type_name for anc in self.ancestors(context=context))
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 2238, in <genexpr>
    return any(anc.qname() == type_name for anc in self.ancestors(context=context))
                                                   ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 2399, in ancestors
    for baseobj in stmt.infer(context):
                   ~~~~~~~~~~^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/inference.py", line 431, in infer_subscript
    for value in self.value.infer(context):
                 ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/inference.py", line 358, in infer_attribute
    for owner in self.expr.infer(context):
                 ~~~~~~~~~~~~~~~^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/bases.py", line 177, in _infer_stmts
    for inf in stmt.infer(context=context):
               ~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/node_ng.py", line 184, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
                     ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 143, in raise_if_nothing_inferred
    yield next(generator)
          ~~~~^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/decorators.py", line 112, in wrapped
    for res in _func(node, context, **kwargs):
               ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/inference.py", line 304, in infer_import
    yield self.do_import_module(self.real_name(name))
          ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/_base_nodes.py", line 146, in do_import_module
    return mymodule.import_module(
           ~~~~~~~~~~~~~~~~~~~~~~^
        modname,
        ^^^^^^^^
    ...<2 lines>...
        use_cache=use_cache,
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 530, in import_module
    return AstroidManager().ast_from_module_name(
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        absmodname, use_cache=use_cache
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/manager.py", line 246, in ast_from_module_name
    return self.ast_from_file(found_spec.location, modname, fallback=False)
           ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/manager.py", line 138, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/builder.py", line 144, in file_build
    module, builder = self._data_build(data, modname, path)
                      ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/builder.py", line 204, in _data_build
    module = builder.visit_module(node, modname, node_file, package)
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/rebuilder.py", line 254, in visit_module
    [self.visit(child, newnode) for child in node.body],
     ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/astroid/rebuilder.py", line 609, in visit
    visit_method = getattr(self, visit_name)
AttributeError: 'TreeRebuilder' object has no attribute 'visit_typealias'

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

Traceback (most recent call last):
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/lint/pylinter.py", line 775, in _lint_files
    self._lint_file(fileitem, module, check_astroid_module)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jeff/Documents/Projects/lute-v3/.venv/lib/python3.13/site-packages/pylint/lint/pylinter.py", line 813, in _lint_file
    raise astroid.AstroidError from e
astroid.exceptions.AstroidError

The above stack trace was with python 3.13, it was the same for 3.12.
It works for python 3.9.

I'm installing pylint using flit: "pylint>=2.17.5,<3",

Following versions as resolved by flit/pip:

  • In 3.9, pylint==2.17.7; astroid==2.15.8
  • In 3.12.8: pylint==2.17.7; astroid==2.15.8

My .pylintrc:

[BASIC]
# Good variable names which should always be accepted.
# Also works for arguments.
good-names=ex,_
good-names-rgxs=[a-z]

# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=3

[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX

[MESSAGES CONTROL]
# Disable the message, report, category or checker with the given id(s).
disable=too-few-public-methods, duplicate-code

[VARIABLES]

# Argument names that match this expression will be ignored.
# This includes some pytest fixtures that are "setup" methods for functions:
# app_context, empty_db, etc
ignored-argument-names=app_context|empty_db|dummy|^ignored_|^unused_,|^_

Cheers and thank you very much! Let me know if you need more from me.

@Pierre-Sassoulas
Copy link
Member

Thank you for opening the issue, pylint<3 is not compatible with python 3.12, do you mind upgrading to pylint 3.3.2 and report back please ? (Right now pylint is not compatible with python 3.13.1 in any version)

@jacobtylerwalls
Copy link
Member

Duplicate of #8782

@jacobtylerwalls jacobtylerwalls marked this as a duplicate of #8782 Dec 11, 2024
@jacobtylerwalls jacobtylerwalls closed this as not planned Won't fix, can't repro, duplicate, stale Dec 11, 2024
@jacobtylerwalls jacobtylerwalls added the Duplicate 🐫 Duplicate of an already existing issue label Dec 11, 2024
@jzohrab
Copy link
Author

jzohrab commented Dec 11, 2024

Thank you @Pierre-Sassoulas , I upgraded and it worked with python 3.12. Thanks for taking the time, appreciated!

Apologies for not seeing the dup, I should have checked first. Thanks both, have a good one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate 🐫 Duplicate of an already existing issue
Projects
None yet
Development

No branches or pull requests

3 participants