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

brain_gi uses wrong Gtk version for analysis #2190

Open
kulikjak opened this issue May 23, 2023 · 1 comment · May be fixed by #2453
Open

brain_gi uses wrong Gtk version for analysis #2190

kulikjak opened this issue May 23, 2023 · 1 comment · May be fixed by #2453
Labels
Brain 🧠 Needs a brain tip

Comments

@kulikjak
Copy link

Steps to reproduce

This only happens on systems where both Gtk 3 and Gtk 4 are available.

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

cell = Gtk.CellRendererText()
#cell.props.xalign = 1.0

Gtk.Builder().connect_signals({})

When you run pylint on this code, it works as expected; however, when you uncomment the cell.props.xalign line, it breaks with
test.py:8:0: E1101: Instance of 'Builder' has no 'connect_signals' member (no-member)
(connect_signals is only available in Gtk3, not in Gtk4)

Current behavior

test.py:8:0: E1101: Instance of 'Builder' has no 'connect_signals' member (no-member)

Expected behavior

E1101 is not there (as Builder does have connect_signals member in Gtk 3.0).

More info

I did a little bit more digging and found out that in the second (failing) case, following exception is raised in _register_require_version:
Namespace Gtk is already loaded with version 4.0

Debug prints in each function in brain_gi.py further showed that in the first case, require_version is handled first as expected. In the second case, _register_require_version is called after everything else has been processed, which is wrong (newer Gtk was already loaded at this point).

I found this in astroid 2.12.5 and pylint 2.15.2 with Python 3.7 and 3.11, but I also tried the latest and greatest (astroid 2.15.5 & pylint 2.17.4), and the same issue is still reproducible.

This issue was initially reported here:
pylint-dev/pylint#6352

@marmarek
Copy link

More specifically, in the too early case, the import is called this way:

  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/usr/lib/python3.12/site-packages/pylint/__main__.py", line 10, in <module>
    pylint.run_pylint()
  File "/usr/lib/python3.12/site-packages/pylint/__init__.py", line 34, in run_pylint
    PylintRun(argv or sys.argv[1:])
  File "/usr/lib/python3.12/site-packages/pylint/lint/run.py", line 211, in __init__
    linter.check(args)
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 701, in check
    ast_per_fileitem = self._get_asts(fileitems, data)
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 716, in _get_asts
    ast_per_fileitem[fileitem] = self.get_ast(
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 976, in get_ast
    return MANAGER.ast_from_file(filepath, modname, source=True)
  File "/usr/lib/python3.12/site-packages/astroid/manager.py", line 151, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
  File "/usr/lib/python3.12/site-packages/astroid/builder.py", line 140, in file_build
    return self._post_build(module, builder, encoding)
  File "/usr/lib/python3.12/site-packages/astroid/builder.py", line 164, in _post_build
    self.delayed_assattr(delayed)
  File "/usr/lib/python3.12/site-packages/astroid/builder.py", line 236, in delayed_assattr
    for inferred in node.expr.infer():
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_classes.py", line 1090, in _infer_attribute
    for owner in node.expr.infer(context):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/bases.py", line 179, in _infer_stmts
    for inf in stmt.infer(context=context):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/bases.py", line 179, in _infer_stmts
    for inf in stmt.infer(context=context):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_classes.py", line 1756, in _infer
    for callee in self.func.infer(context):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_classes.py", line 1090, in _infer_attribute
    for owner in node.expr.infer(context):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/bases.py", line 179, in _infer_stmts
    for inf in stmt.infer(context=context):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_ng.py", line 170, in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 90, in inner
    yield next(generator)
  File "/usr/lib/python3.12/site-packages/astroid/decorators.py", line 49, in wrapped
    for res in _func(node, context, **kwargs):
  File "/usr/lib/python3.12/site-packages/astroid/nodes/node_classes.py", line 2870, in _infer
    stmts = module.getattr(name, ignore_locals=module is self.root())
  File "/usr/lib/python3.12/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 353, in getattr
    result = [self.import_module(name, relative_only=True)]
  File "/usr/lib/python3.12/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 453, in import_module
    return AstroidManager().ast_from_module_name(
  File "/usr/lib/python3.12/site-packages/astroid/manager.py", line 263, in ast_from_module_name
    return hook(modname)
  File "/usr/lib/python3.12/site-packages/astroid/brain/brain_gi.py", line 193, in _import_gi_module
    __import__(m)

and in the good case, it's called this way:

  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/usr/lib/python3.12/site-packages/pylint/__main__.py", line 10, in <module>
    pylint.run_pylint()
  File "/usr/lib/python3.12/site-packages/pylint/__init__.py", line 34, in run_pylint
    PylintRun(argv or sys.argv[1:])
  File "/usr/lib/python3.12/site-packages/pylint/lint/run.py", line 211, in __init__
    linter.check(args)
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 704, in check
    self._lint_files(ast_per_fileitem, check_astroid_module)
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 752, in _lint_files
    self._lint_file(fileitem, module, check_astroid_module)
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 788, in _lint_file
    check_astroid_module(module)
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 1017, in check_astroid_module
    retval = self._check_astroid_module(
  File "/usr/lib/python3.12/site-packages/pylint/lint/pylinter.py", line 1069, in _check_astroid_module
    walker.walk(node)
  File "/usr/lib/python3.12/site-packages/pylint/utils/ast_walker.py", line 94, in walk
    self.walk(child)
  File "/usr/lib/python3.12/site-packages/pylint/utils/ast_walker.py", line 91, in walk
    callback(astroid)
  File "/usr/lib/python3.12/site-packages/pylint/checkers/variables.py", line 2077, in visit_importfrom
    self._check_module_attrs(node, module, name.split("."))
  File "/usr/lib/python3.12/site-packages/pylint/checkers/variables.py", line 3086, in _check_module_attrs
    module = next(module.getattr(name)[0].infer())
  File "/usr/lib/python3.12/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 353, in getattr
    result = [self.import_module(name, relative_only=True)]
  File "/usr/lib/python3.12/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 453, in import_module
    return AstroidManager().ast_from_module_name(
  File "/usr/lib/python3.12/site-packages/astroid/manager.py", line 263, in ast_from_module_name
    return hook(modname)
  File "/usr/lib/python3.12/site-packages/astroid/brain/brain_gi.py", line 193, in _import_gi_module
    __import__(m)

marmarek added a commit to marmarek/astroid that referenced this issue Jun 24, 2024
When importing Gtk, it looks like this:

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk

It is vital that gi.require_version() is made before related 'from
gi.repository import ...'. The brain_gi tries to do that using
transforms. And it works unless Gtk is imported as part of delayed
assattr handling.

Fix this by handling transforms earlier.

Fixes pylint-dev#2190
Fixes pylint-dev/pylint#6352
marmarek added a commit to marmarek/astroid that referenced this issue Jun 25, 2024
When importing Gtk, it looks like this:

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk

It is vital that gi.require_version() is made before related 'from
gi.repository import ...'. The brain_gi tries to do that using
transforms. And it works unless Gtk is imported as part of delayed
assattr handling.

Fix this by adding early transforms that are called before delayed
assattr.

Fixes pylint-dev#2190
Fixes pylint-dev/pylint#6352
marmarek added a commit to marmarek/astroid that referenced this issue Jun 25, 2024
When importing Gtk, it looks like this:

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk

It is vital that gi.require_version() is made before related 'from
gi.repository import ...'. The brain_gi tries to do that using
transforms. And it works unless Gtk is imported as part of delayed
assattr handling.

Fix this by adding early transforms that are called before delayed
assattr.

Fixes pylint-dev#2190
Fixes pylint-dev/pylint#6352
marmarek added a commit to marmarek/astroid that referenced this issue Jun 27, 2024
When importing Gtk, it looks like this:

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk

It is vital that gi.require_version() is made before related 'from
gi.repository import ...'. The brain_gi tries to do that using
transforms. And it works unless Gtk is imported as part of delayed
assattr handling.

Fix this by adding early transforms that are called before delayed
assattr.

Fixes pylint-dev#2190
Fixes pylint-dev/pylint#6352
marmarek added a commit to QubesOS/qubes-continuous-integration that referenced this issue Jul 5, 2024
Workaround for pylint-dev/astroid#2190

The patch isn't used in this repo yet, but it's referenced from other
repos.
marmarek added a commit to QubesOS/qubes-desktop-linux-manager that referenced this issue Jul 5, 2024
pylint confuses GTK3 and GTK4, see details at
Workaround for pylint-dev/astroid#2190
marmarek added a commit to QubesOS/qubes-desktop-linux-manager that referenced this issue Jul 5, 2024
pylint confuses GTK3 and GTK4, see details at
Workaround for pylint-dev/astroid#2190
marmarek added a commit to QubesOS/qubes-desktop-linux-manager that referenced this issue Jul 7, 2024
pylint confuses GTK3 and GTK4, see details at
Workaround for pylint-dev/astroid#2190
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Brain 🧠 Needs a brain tip
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants