问题
What is the right way to use nose.tools and keep pylint happy?
The following code:
'''
This is a test
'''
import nose.tools
import nose.tools.trivial
nose.tools.assert_equal(1, 1)
nose.tools.assert_equals(1, 1)
nose.tools.trivial.assert_equal(1, 1)
nose.tools.trivial.assert_equals(1, 1)
Results in the following pylint errors:
$ pylint -i y -r n /tmp/aseq.py
************* Module aseq
E1101: 8,0: Module 'nose.tools' has no 'assert_equal' member
E1101: 9,0: Module 'nose.tools' has no 'assert_equals' member
E1101: 11,0: Module 'nose.tools.trivial' has no 'assert_equal' member
E1101: 12,0: Module 'nose.tools.trivial' has no 'assert_equals' member
Of course, one could disable E1101, is there a cleaner way?
回答1:
Instead of disabling E1101, you should put:
ignored-classes=nose.tools,nose.tools.trivial
in .pylintrc, under the [TYPECHECK]
section.
As it stands in the pylint doc, this option is "useful for classes with attributes dynamically set".
回答2:
nose.tools.trivial
simply inspects unittest.TestCase
class on the fly and makes all "public" methods starting from assert
available from nose.tools
or nose.tools.trivial
:
nose/tools/__init__.py:
from nose.tools.nontrivial import *
from nose.tools.nontrivial import __all__ as nontrivial_all
from nose.tools.trivial import *
from nose.tools.trivial import __all__ as trivial_all
__all__ = trivial_all + nontrivial_all
nose/tools/trivial.py:
...
class Dummy(unittest.TestCase):
def nop():
pass
_t = Dummy('nop')
for at in [ at for at in dir(_t)
if at.startswith('assert') and not '_' in at ]:
pepd = pep8(at)
vars()[pepd] = getattr(_t, at)
__all__.append(pepd)
...
Pylint cannot handle this "hacky" behavior.
Consider using nose.tools.eq_
instead of assert_equal
and assert_equals
(these methods are actually the same). Hope that helps.
回答3:
Pylint doesn't understand nose underlying magic. As suggested, solutions include disabling E1101 or ignoring related classes. But the best is to contribute to the pylint-brain project by submitting there a simple description of the part of the API not grasped by Pylint. This should be pretty simple from the doc and example you'll find there.
回答4:
Using pylint 1.4.3 (with astroid 1.3.6, common 0.63.2, Python 2.7.10), the setting that has to be changed is ignored-modules
, and not ignored-classes
:
ignored-modules=nose.tools,nose.tools.trivial
回答5:
Or upgrade your astroid to 1.3.6, the nose problem was fixed: https://bitbucket.org/logilab/astroid/src/fdc592a3609ca7b882e12110d072a0e12f899338/astroid/brain/pynose.py?at=default
来源:https://stackoverflow.com/questions/17156240/nose-tools-and-pylint