nelfin / pylint-protobuf

A plugin for making Pylint aware of the fields of protobuf-generated classes
MIT License
29 stars 12 forks source link

pylint no-member error with nested enums. #52

Open rshanor opened 3 years ago

rshanor commented 3 years ago

Here is my proto

syntax = "proto3";

message Foo {
    enum Bar {
        BAR_0 = 0;
        BAR_1 = 1;
    }

    int32 foo_2 = 2;
    Bar foo_bar = 3;
}

Compiled with protoc foo.proto --python_out=.

Here is my test script, which runs fine.

"""[summary]
"""
import foo_pb2

def _main():
    test_obj = foo_pb2.Foo()
    test_obj.foo_bar = foo_pb2.Foo.BAR_1

if __name__ == "__main__":
    _main()

But pylint still reports an error.

$ python3 -m pylint --load-plugins=pylint_protobuf test_pylint.py 
************* Module test_pylint
test_pylint.py:7:23: E1101: Class 'Foo' has no 'BAR_1' member (no-member)

------------------------------------------------------------------
Your code has been rated at 1.67/10 (previous run: 1.67/10, +0.00)

I tried with multiple versions of pylint, but get the same error no matter what. Here is my current version info tho.

pylint                     2.7.2
pylint-protobuf            0.20.2 

Thank!

nelfin commented 3 years ago

Hi @rshanor, thanks for the report. This does look like a failure to suppress no-member in this case, could be due to incorrect inference since we explicitly support lifting enum literals into their parent scope. Unfortunately I cannot be sure as I'm not able to reproduce your case with pylint==2.7.2, astroid==2.5.8 and Python 3.8.1:

(venv) ~/p/p/e/issue52 (fix/52-no-member-nested) $ cat foo.proto 
syntax = "proto3";

message Foo {
    enum Bar {
        BAR_0 = 0;
        BAR_1 = 1;
    }

    int32 foo_2 = 2;
    Bar foo_bar = 3;
}
(venv) ~/p/p/e/issue52 (fix/52-no-member-nested) $ cat test_pylint.py 
"""[summary]
"""
import foo_pb2

def _main():
    test_obj = foo_pb2.Foo()
    test_obj.foo_bar = foo_pb2.Foo.BAR_1

if __name__ == "__main__":
    _main()
(venv) ~/p/p/e/issue52 (fix/52-no-member-nested) $ python -m pylint --load-plugins=pylint_protobuf test_pylint.py 

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

Could you copy in the output of pip freeze and python -V here to help me track down a reproducing environment?

rshanor commented 3 years ago

Thanks for the reply @nelfin

I am using Python 3.6.9.

I tried out Python 3.6.9 in a fresh venv and everything worked. I checked this venv which had protobuf version 3.19. I downgraded this venv to my version of protobuf, which did not work!

I realized I was on a super old version of protobuf (3.5.2.post1) I upgraded protobuf to 3.12 and this also worked.

Thanks for the hint!

If you are interested, minimal repro steps.

python3 -m venv /tmp/pylint_test
/tmp/pylint_test/bin/python3 -m pip install pylint pylint-protobuf
/tmp/pylint_test/bin/python -m pip install protobuf==3.5.2.post1
/tmp/pylint_test/bin/python -m pylint --load-plugins=pylint_protobuf test_pylint.py