pylint-dev / astroid

A common base representation of python source code for pylint and other projects
https://pylint.readthedocs.io/projects/astroid/en/latest/
GNU Lesser General Public License v2.1
528 stars 274 forks source link

brain_gi generates incorrectly classifies some functions as methods #2594

Open jhenstridge opened 2 weeks ago

jhenstridge commented 2 weeks ago

6 years ago, there was a bug report about pylint giving spurious errors for certain functions provided by the pygobject bindings:

https://gitlab.gnome.org/GNOME/pygobject/-/issues/217

A workaround was committed that hid the problem by hiding the FunctionInfo.__get__ method from Python while still making it act like a descriptor at the C level.

The next version of pygobject removes this workaround as it was causing some problems for other improvements I was making. So I decided to track down the root cause of the problem, which led me to the astroid/brain/brain_gi.py code.

It decides that anything that inspect.ismethoddescriptor() returns true for is a method and should be given the signature (self, *args, **kwargs):

https://github.com/pylint-dev/astroid/blob/ba7df4acab0e985d1a6274def9f1798a9a7ce40d/astroid/brain/brain_gi.py#L134-L136

FunctionInfo objects meet this criteria since they have a __get__ method but no __set__ method. This signature is fine when the FunctionInfo object is being used to represent a method on a class, but is inappropriate when it represents a plain function at the module level. The fact that it has provides descriptor behaviour is irrelevant since it is stored in the module instance dict rather than being an attribute of the module type.

Using a (*args, **kwargs) signature would probably fix the bug. Alternatively, the next pygobject release will also support inspect.signature() on FunctionInfo objects, providing info about the actual function arguments.

Steps to reproduce

  1. Install current git version of pygobject
  2. Run pylint on a program that calls a module level function with no arguments (such as gi.repository.GLib.get_monotonic_time())

Current behavior

See an E1120 error complaining about a missing "self" parameter.

Expected behavior

The error should not be generated

python -c "from astroid import __pkginfo__; print(__pkginfo__.version)" output

3.2.4

jacobtylerwalls commented 2 weeks ago

Thanks for the report. Would you like to submit your proposed solution?