pylint
pylint copied to clipboard
Pylint can't find some PyGObject classes' members
Bug description
Hello,
I have a simple class inheriting from PyGObject's Gtk.Window
class. Pylint cannot Gtk.Window
's add
and show_all
members, yet the code runs fine:
"""
The main window of the application.
"""
from typing import Tuple
import gi
gi.require_version("Gtk", "3.0")
# pylint: disable=wrong-import-position
from gi.repository import Gtk
# pylint: enable=wrong-import-position
class MainWindow(Gtk.Window):
"""
The main window of the application.
"""
WINDOW_SIZE: Tuple[int, int] = (500, 250)
MAIN_PADDING_PX: int = 10
FRAMES_VERTICAL_SPACE_PX: int = 10
INPUT_FILE_FRAME_LABEL: str = "Input file"
INPUT_FILE_BUTTON_LABEL: str = "Choose input file"
def __init__(self, title: str):
super().__init__(title=title)
self.set_size_request(*self.WINDOW_SIZE)
# --- Add widgets --- #
# Main container
main_box: Gtk.Box = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL,
spacing=self.FRAMES_VERTICAL_SPACE_PX)
self.add(main_box)
MainWindow.__pad_on_all_sides(main_box, self.MAIN_PADDING_PX)
# Input file picker
input_file_frame: Gtk.Frame = Gtk.Frame.new(label=self.INPUT_FILE_FRAME_LABEL)
main_box.pack_start(child=input_file_frame, expand=True, fill=True, padding=0)
hbox: Gtk.Box = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL)
input_file_frame.add(hbox)
self.input_file_button = Gtk.Button.new(label=self.INPUT_FILE_BUTTON_LABEL)
# --- Connect and show --- #
self.connect("destroy", Gtk.main_quit)
self.show_all()
@staticmethod
def __pad_on_all_sides(widget: Gtk.Widget, padding: int) -> None:
widget.set_margin_bottom(padding)
widget.set_margin_top(padding)
widget.set_margin_left(padding)
widget.set_margin_right(padding)
Interestingly, if I remove the following line, pylint stops complaining. It looks like adding a member to the MainWindow class which inherits from Gtk.Window throws off pylint.
self.input_file_button = Gtk.Button.new(label=self.INPUT_FILE_BUTTON_LABEL)
Configuration
I am using pylint's default configuration.
Command used
pylint main_window.py
Pylint output
************* Module main_window
main_window.py:34:8: E1101: Instance of 'MainWindow' has no 'add' member (no-member)
main_window.py:48:8: E1101: Instance of 'MainWindow' has no 'show_all' member (no-member)
------------------------------------------------------------------
Your code has been rated at 6.43/10 (previous run: 6.43/10, +0.00)
Expected behavior
I would expect pylint to find these two members, as they clearly exist since the code runs fine.
Pylint version
pylint 2.13.5
astroid 2.11.2
Python 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0]
OS / Environment
EndeavourOS KDE version 5.17.3-arch1-1 kernel All packages up-to-date
Additional dependencies
astroid==2.11.2 black==22.3.0 click==8.1.2 dill==0.3.4 isort==5.10.1 lazy-object-proxy==1.7.1 mccabe==0.7.0 mypy==0.942 mypy-extensions==0.4.3 pathspec==0.9.0 platformdirs==2.5.1 pycairo==1.21.0 PyGObject==3.42.0 pylint==2.13.5 tomli==2.0.1 typing_extensions==4.1.1 wrapt==1.14.0
Hi @Scrashdown, thanks for the report.
The astroid
project handles most of the static analysis hints for specific projects to help pylint
guess about membership. Unfortunately the "brain" for gi
is completely untested. If you (or anyone else!) have got a cycle for it, there's a model for how to get a new package-specific unittest written in PyCQA/astroid#1505.
The
astroid
project handles most of the static analysis hints for specific projects to helppylint
guess about membership. Unfortunately the "brain" forgi
is completely untested. If you (or anyone else!) have got a cycle for it, there's a model for how to get a new package-specific unittest written in PyCQA/astroid#1505.
Based on that, this seems to work correctly with python3-astroid-2.11.6-1.fc36.noarch
but fails with python3-astroid-2.12.1-1.fc37
, so it would be a regression.
Seems to work correctly with pylint-2.14.4-3.fc37.noarch
and python3-astroid-2.12.13-1.fc37.noarch
for me.
So, this is then no longer an issue?
Not for me, but I'm not the original reporter.
I can confirm this issue is still present with those versions :
pylint 2.17.0
astroid 2.15.0
Python 3.10.9 (main, Dec 19 2022, 17:35:49) [GCC 12.2.0]
I have the same issue on my code AND on the original reporter's code.
Hi, I've also hit this issue. The following code is the shortest reproducible case I found.
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 it like this, 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)
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.
I guess I should report this bug in astroid itself? Sadly, I have no idea how astroid works, so I am afraid I won't be able to fix this, but it's a start.