pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.29k stars 1.13k forks source link

Field lookup fails for ``geoip2.records.Country.iso_code`` #4911

Open jolaf opened 3 years ago

jolaf commented 3 years ago

Bug description

from geoip2.database import Reader
reader = Reader('/var/lib/GeoIP/GeoLite2-City.mmdb')
response = reader.city('8.8.8.8')
country = response.country
print(type(country), country.iso_code)

Here country has type geoip2.records.Country and the field iso_code is definitely there.

One potential reason for this behavior may be that pylint treats country as geoip2.models.Country, which has no such field.

Configuration

No response

Command used

python3 test.py ; pylint test.py

Pylint output

<class 'geoip2.records.Country'> US
************* Module test
test.py:5: [E1101(no-member), ] Instance of 'Country' has no 'iso_code' member

Expected behavior

<class 'geoip2.records.Country'> US

Pylint version

pylint 2.10.2
astroid 2.7.2
Python 3.8.10 (default, Jun  2 2021, 10:49:15) 
[GCC 9.4.0]

OS / Environment

Ubuntu 20.04.3 LTS \n \l

Additional dependencies

geoipupdate==4.0.6-2 python3-geoip2==2.9.0+dfsg1-2

hippo91 commented 3 years ago

@jolaf thanks for your remark. However i'm unable to reproduce it. When linting:

#pylint: disable=missing-module-docstring
from geoip2.database import Reader
reader = Reader('/var/lib/GeoIP/GeoLite2-City.mmdb')
response = reader.city('8.8.8.8')
country = response.country
print(type(country), country.iso_code)

I got no warnings:

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
python --version
Python 3.8.6
pip freeze
aiohttp==3.7.4.post0
-e
git+https://github.com/hippo91/astroid.git@9f529498dba18ee74ca3b425785bfb2587b1b05f#egg=astroid
async-timeout==3.0.1
attrs==21.2.0
certifi==2021.5.30
chardet==4.0.0
charset-normalizer==2.0.4
geoip2==4.2.0
idna==3.2
isort==5.9.3
lazy-object-proxy==1.6.0
maxminddb==2.0.3
mccabe==0.6.1
multidict==5.1.0
platformdirs==2.2.0
-e
git+https://github.com/hippo91/pylint.git@23488352bc0dbdfa519abb527af3d676244b7106#egg=pylint
requests==2.26.0
toml==0.10.2
typing-extensions==3.10.0.0
urllib3==1.26.6
wrapt==1.12.1
yarl==1.6.3
jolaf commented 3 years ago

Note that I've also filed https://bugs.launchpad.net/ubuntu/+source/python-geoip2/+bug/1941625

hippo91 commented 3 years ago

@jolaf. I have finally been able to reproduce.

hippo91 commented 3 years ago

@jolaf astroid, the inference engine of pylint correctly infers response.country as a <Instance of geoip2.records.Country at 0x0000>. The attributes of this class are not defined statically in the class or one of its ancestors. Instead they are dynamically defined by running through the _valid_attributes set. As astroid do not execute any code, it can not determine the exact collection of attributes thus it yield this false positive. I will build an astroid brain to handle this.