Discovered on Windows10 using Anaconda Python 3.6.1 with the pyzmq library installed using pip install zmq.
Pylint output:
44,50,error,E1101:Module 'zmq' has no 'REQ' member
60,50,error,E1101:Module 'zmq' has no 'REP' member
Given that this is an inaccurate report from pylint, perhaps ask pylint? I'm not sure if pylint can handle runtime-defined names. Maybe there's something we can do here to help them find what they are after, but the attribute is defined and in zmq.__all__
, so I'm not sure what more there is to do.
@badrobit Pylint does not, cannot and possibly will not handle runtime-defined names. It's simply not a issue with pyzmq. It's a common problem, and you should write a comment to disable pylint E1101 for that line.
If a module includes a name in its __all__
, then that provides a way for the module to signal to tools like pylint that the name will exist at runtime.
Pylint could continue to warn the project defining __all__
that it's including a variable that doesn't exist, and that project can include a comment to disable pylint E0603 on that line if it wants. But the calling project is doing nothing wrong, and the information is available in the imported module's __all__
to confirm that it is an intended variable name of the project (which, if it doesn't exist, is that project's fault, not the importer's).
@chrisjbillington well, however, it is quite hard to decide on what runtime variables exist since zmq in different versions have different enums.
@adamcavendish right, and I see that actually zmq.REP
is not in __all__
as it is defined in source. it too must be getting added to __all__
at runtime, so inspecting source __all__
would still not reveal it,
same problem with zmq.PUB, zmq.LINGER, zmq.SUB, zmq.SUBSCRIBE see also https://github.com/PyCQA/pylint/issues/478
Closing as there doesn't seem to be anything to do. Static analysis isn't going to find dynamically defined names.
Here's a quick workaround cheatsheet for others hitting this. In .pylintrc
, add:
[TYPECHECK]
# zmq.{LINGER,REQ,ROUTER,NOBLOCK} are dynamically generated and so pylint
# doesn't see them, causing false positives.
generated-members=LINGER,REQ,ROUTER,NOBLOCK
(I didn't need REP
but you can add other attributes following the same pattern).
Most helpful comment
Here's a quick workaround cheatsheet for others hitting this. In
.pylintrc
, add:(I didn't need
REP
but you can add other attributes following the same pattern).