Pylint: E0203(access-member-before-definition) wrongly detected in some cases

Created on 18 Jul 2018  路  11Comments  路  Source: PyCQA/pylint

With a combination of Python 3.6 and f-strings pylint shows non-existing errors:

Steps to reproduce

  1. Use Python 3.6 and write a class that defines a new dict in __init__() and then try to access an element of that dict inside an f-string, e.g.:
class TestClass(object):
    def __init__(self):
        self.foo = {"foo": "bar"}
        print(f"this foo is a {self.foo['foo']}")

Current behavior

Pylint shows an error:

$ python3.6 -m pylint -E test_class.py 
************* Module git.test_class
test_class.py:1:1: E0203: Access to member 'foo' before its definition line 3 (access-member-before-definition)

Expected behavior

No error shown

pylint --version output

$ pylint --version
pylint 2.0.0
astroid 2.0.0.dev4
Python 3.6.6 (default, Jun 28 2018, 04:42:43) 
[GCC 5.4.0 20160609]
bug

All 11 comments

When I downgrade to Pylint 1.9.2, this error isn't shown.

Thanks for the report

@brycepg I also reproduced the results from @adrianer (failing in version 2.0.1 but passing in 1.9.2) without square bracket dictionary operators in an f-string, with a use case resembling:

```python
class TestClass(object):
def __init__(self, x):
self.x = x
print(f"{self.x or 'none'}")

Reproducable in 2.1.1

In my setup, pylint warned about line 1 even though the offending line was on line 300. It took quite a bit of time before I realized the f-string was the problem.

Side effect is that I cannot use the # pylint: disable comment on line 300.

If it's helpful, E0118 (used-prior-global-declaration) can likewise be triggered with the f-string in the same manner. Just have a global that you use the global keyword on inside a function, and then print it out via an f-string. Same symptoms: it complains about it on line 1 of the script.

Incidentally, this and the other error can be gotten around simply by using a local dummy variable before processing in the f-string:


fp_num = 0

... do some stuff ...

def print_foo():
    global fp_num
    _fp_num = fp_num
    print(f"fp_num is {_fp_num}")

pylint 2.1.1
astroid 2.0.4
Python 3.6.6 (default, Jun 28 2018, 00:00:00)
[GCC 4.8.4]

Same experience as jonapich, warning shows up on line 1 saying that I used a member prior to initialization on line 67.

Actual issue was using {len(self.member)} in an f-string on line 80.

Thanks for all the examples folks.

Any update on getting this fixed...?

Still actual for pylint 2.4.1 :(

Another example unrelated to f-strings, pylint reports an error for an access before definition when immediately inside a test for a definition, e.g.

if hasattr(self,'_text'):
    return self._text

produces Access to member '_text' before its definition. An if expression that evaluates hasattr with a constant should produce a defined state within the if block. Likewise for other access before definition tests. (I haven't tried them all.)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TBoshoven picture TBoshoven  路  3Comments

GergelyKalmar picture GergelyKalmar  路  3Comments

Hubro picture Hubro  路  3Comments

pylint-bot picture pylint-bot  路  3Comments

sambarluc picture sambarluc  路  3Comments