From e6ae438fd29d54ec6aca84f750c55b58da998151 Mon Sep 17 00:00:00 2001 From: Claudiu Popa Date: Sat, 28 Feb 2015 19:13:33 +0200 Subject: Make the --py3k flag commutative with the -E flag. Also, this patch fixes the leaks of error messages from the Python 3 checker when the errors mode was activated. Closes issue #437. --- ChangeLog | 4 +++ pylint/lint.py | 18 ++++++++++ pylint/test/regrtest_data/py3k_error_flag.py | 11 ++++++ pylint/test/test_self.py | 50 +++++++++++++++++++++++++++- pylint/utils.py | 5 +++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 pylint/test/regrtest_data/py3k_error_flag.py diff --git a/ChangeLog b/ChangeLog index 821e826..bdf395a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -48,6 +48,10 @@ RELEASE DATE -- VERSION emitted when the `cmp` argument for the `list.sort` or `sorted builtin` is encountered. + * Make the --py3k flag commutative with the -E flag. Also, this patch + fixes the leaks of error messages from the Python 3 checker when + the errors mode was activated. Closes issue #437. + 2015-01-16 -- 1.4.1 diff --git a/pylint/lint.py b/pylint/lint.py index 7274c78..5ac51c2 100644 --- a/pylint/lint.py +++ b/pylint/lint.py @@ -455,6 +455,7 @@ class PyLinter(configuration.OptionsManagerMixIn, self.register_checker(self) self._dynamic_plugins = set() self._python3_porting_mode = False + self._error_mode = False self.load_provider_defaults() if reporter: self.set_reporter(reporter) @@ -583,8 +584,16 @@ class PyLinter(configuration.OptionsManagerMixIn, def error_mode(self): """error mode: enable only errors; no reports, no persistent""" + self._error_mode = True self.disable_noerror_messages() self.disable('miscellaneous') + if self._python3_porting_mode: + self.disable('all') + for msg_id in self._checker_messages('python3'): + if msg_id.startswith('E'): + self.enable(msg_id) + else: + self.disable('python3') self.set_option('reports', False) self.set_option('persistent', False) @@ -592,6 +601,15 @@ class PyLinter(configuration.OptionsManagerMixIn, """Disable all other checkers and enable Python 3 warnings.""" self.disable('all') self.enable('python3') + if self._error_mode: + # The error mode was activated, using the -E flag. + # So we'll need to enable only the errors from the + # Python 3 porting checker. + for msg_id in self._checker_messages('python3'): + if msg_id.startswith('E'): + self.enable(msg_id) + else: + self.disable(msg_id) self._python3_porting_mode = True # block level option handling ############################################# diff --git a/pylint/test/regrtest_data/py3k_error_flag.py b/pylint/test/regrtest_data/py3k_error_flag.py new file mode 100644 index 0000000..c12d250 --- /dev/null +++ b/pylint/test/regrtest_data/py3k_error_flag.py @@ -0,0 +1,11 @@ +"""Contains both normal error messages and Python3 porting error messages.""" +# pylint: disable=bad-builtin, too-few-public-methods + +raise Exception, 1 # Error emitted here with the Python 3 checker. + + +class Test(object): + """dummy""" + + def __init__(self): + return 42 diff --git a/pylint/test/test_self.py b/pylint/test/test_self.py index 1734889..9c296b8 100644 --- a/pylint/test/test_self.py +++ b/pylint/test/test_self.py @@ -11,10 +11,12 @@ # this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +import contextlib import sys import os from os.path import join, dirname, abspath import tempfile +import textwrap import unittest import six @@ -28,6 +30,17 @@ from pylint.reporters.json import JSONReporter HERE = abspath(dirname(__file__)) + +@contextlib.contextmanager +def _patch_streams(out): + sys.stderr = sys.stdout = out + try: + yield + finally: + sys.stderr = sys.__stderr__ + sys.stdout = sys.__stdout__ + + class MultiReporter(BaseReporter): def __init__(self, reporters): self._reporters = reporters @@ -85,6 +98,15 @@ class RunTC(unittest.TestCase): sys.stderr = sys.__stderr__ sys.stdout = sys.__stdout__ + def _test_output(self, args, expected_output): + out = six.StringIO() + with _patch_streams(out): + with self.assertRaises(SystemExit): + Run(args) + + actual_output = out.getvalue() + self.assertEqual(expected_output.strip(), actual_output.strip()) + def test_pkginfo(self): """Make pylint check itself.""" self._runtest(['pylint.__pkginfo__'], reporter=TextReporter(six.StringIO()), @@ -151,7 +173,33 @@ class RunTC(unittest.TestCase): rc_code = 2 if six.PY2 else 0 self._runtest([join(HERE, 'functional', 'unpacked_exceptions.py'), '--py3k', '-j 2'], - code=rc_code) + code=rc_code) + + @unittest.skipIf(sys.version_info[0] > 2, "Requires the --py3k flag.") + def test_py3k_commutative_with_errors_only(self): + + # Test what gets emitted with -E only + module = join(HERE, 'regrtest_data', 'py3k_error_flag.py') + expected = textwrap.dedent(""" + No config file found, using default configuration + ************* Module py3k_error_flag + Explicit return in __init__ + """) + self._test_output([module, "-E", "--msg-template='{msg}'"], + expected_output=expected) + + # Test what gets emitted with -E --py3k + expected = textwrap.dedent(""" + No config file found, using default configuration + ************* Module py3k_error_flag + Use raise ErrorClass(args) instead of raise ErrorClass, args. + """) + self._test_output([module, "-E", "--py3k", "--msg-template='{msg}'"], + expected_output=expected) + + # Test what gets emitted with --py3k -E + self._test_output([module, "--py3k", "-E", "--msg-template='{msg}'"], + expected_output=expected) if __name__ == '__main__': diff --git a/pylint/utils.py b/pylint/utils.py index 6685c4a..6c5b975 100644 --- a/pylint/utils.py +++ b/pylint/utils.py @@ -225,6 +225,11 @@ class MessagesHandlerMixIn(object): self._msgs_state = {} self.msg_status = 0 + def _checker_messages(self, checker): + for checker in self._checkers[checker.lower()]: + for msgid in checker.msgs: + yield msgid + def disable(self, msgid, scope='package', line=None, ignore_unknown=False): """don't output message of the given id""" assert scope in ('package', 'module') -- cgit v1.2.1