def test_html_reporter_msg_template(self): expected = ''' <html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>category</th> <th>msg_id</th> </tr> <tr class="even"> <td>warning</td> <td>W0332</td> </tr> </table> </div> </div> </body> </html>'''.strip().splitlines() output = six.StringIO() linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('msg-template', '{category}{msg_id}') linter.open() linter.set_current_module('0123') linter.add_message('lowercase-l-suffix', line=1) linter.reporter.display_results(Section()) self.assertEqual(output.getvalue().splitlines(), expected)
def test_html_reporter_msg_template(self): expected = ''' <html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>category</th> <th>msg_id</th> </tr> <tr class="even"> <td>warning</td> <td>W0332</td> </tr> </table> </div> </div> </body> </html>'''.strip().splitlines() output = six.StringIO() linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('msg-template', '{category}{msg_id}') linter.open() linter.set_current_module('0123') linter.add_message('lowercase-l-suffix', line=1) linter.reporter.display_results(Section()) self.assertEqual(output.getvalue().splitlines(), expected)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): # self.linter.set_reporter(TextReporter()) expected = ( '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n' ) output = StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual(output.getvalue(), expected)
def test_simple_json_output(): output = StringIO() reporter = JSONReporter() linter = PyLinter(reporter=reporter) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module("0123") linter.add_message("line-too-long", line=1, args=(1, 2)) # we call this method because we didn't actually run the checkers reporter.display_messages(None) expected_result = [ [ ("column", 0), ("line", 1), ("message", "Line too long (1/2)"), ("message-id", "C0301"), ("module", "0123"), ("obj", ""), ("path", "0123"), ("symbol", "line-too-long"), ("type", "convention"), ] ] report_result = json.loads(output.getvalue()) report_result = [sorted(report_result[0].items(), key=lambda item: item[0])] assert report_result == expected_result
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_deprecated(self): with warnings.catch_warnings(record=True) as cm: warnings.simplefilter("always") ParseableTextReporter() self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning) def test_parseable_output_regression(self): output = six.StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n') def test_display_results_is_renamed(self): class CustomReporter(TextReporter): def _display(self, layout): return None reporter = CustomReporter() with self.assertRaises(AttributeError): reporter.display_results
def test_addmessage(linter: PyLinter) -> None: linter.set_reporter(testutils.GenericTestReporter()) linter.open() linter.set_current_module("0123") linter.add_message("C0301", line=1, args=(1, 2)) linter.add_message("line-too-long", line=2, args=(3, 4)) assert [ "C: 1: Line too long (1/2)", "C: 2: Line too long (3/4)", ] == linter.reporter.messages
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_deprecated(self): with warnings.catch_warnings(record=True) as cm: warnings.simplefilter("always") ParseableTextReporter() self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning) def test_parseable_output_regression(self): output = six.StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n') def test_display_results_is_renamed(self): class CustomReporter(TextReporter): def _display(self, layout): return None reporter = CustomReporter() with self.assertRaises(AttributeError): reporter.display_results
def test_parseable_output_regression(self): output = six.StringIO() linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n')
def test_parseable_output_regression(self): output = six.StringIO() linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n')
def test_parseable_output_regression(): output = StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option("output-format", "parseable") linter.open() linter.set_current_module("0123") linter.add_message("line-too-long", line=1, args=(1, 2)) assert (output.getvalue() == "************* Module 0123\n" "0123:1: [C0301(line-too-long), ] " "Line too long (1/2)\n")
def test_parseable_output_regression(): output = six.StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) assert output.getvalue() == \ '************* Module 0123\n' \ '0123:1: [C0301(line-too-long), ] ' \ 'Line too long (1/2)\n'
def get_linter_result(score): output = StringIO() reporter = JSONReporter(output) linter = PyLinter(reporter=reporter) checkers.initialize(linter) linter.config.persistent = 0 linter.config.score = score linter.open() linter.set_current_module("0123") linter.add_message("line-too-long", line=1, args=(1, 2)) # we call those methods because we didn't actually run the checkers if score: reporter.display_reports(EvaluationSection(expected_score_message)) reporter.display_messages(None) report_result = json.loads(output.getvalue()) return report_result
def test_parseable_output_regression(): output = StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) assert output.getvalue() == \ '************* Module 0123\n' \ '0123:1: [C0301(line-too-long), ] ' \ 'Line too long (1/2)\n'
def test_html_reporter_type(self): # Integration test for issue #263 # https://bitbucket.org/logilab/pylint/issue/263/html-report-type-problems expected = '''<html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>type</th> <th>module</th> <th>object</th> <th>line</th> <th>col_offset</th> <th>message</th> </tr> <tr class="even"> <td>convention</td> <td>0123</td> <td> </td> <td>1</td> <td>0</td> <td>Exactly one space required before comparison a< 5: print "zero"</td> </tr> </table> </div> </div> </body> </html> ''' output = six.StringIO() with testutils.catch_warnings(): linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module('0123') linter.add_message('bad-whitespace', line=1, args=('Exactly one', 'required', 'before', 'comparison', 'a< 5: print "zero"')) linter.reporter.display_reports(Section()) self.assertMultiLineEqual(output.getvalue(), expected)
def test_html_reporter_type(self): # Integration test for issue #263 # https://bitbucket.org/logilab/pylint/issue/263/html-report-type-problems expected = '''<html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>type</th> <th>module</th> <th>object</th> <th>line</th> <th>col_offset</th> <th>message</th> </tr> <tr class="even"> <td>convention</td> <td>0123</td> <td> </td> <td>1</td> <td>0</td> <td>Exactly one space required before comparison a< 5: print "zero"</td> </tr> </table> </div> </div> </body> </html> ''' output = six.StringIO() with testutils.catch_warnings(): linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module('0123') linter.add_message('bad-whitespace', line=1, args=('Exactly one', 'required', 'before', 'comparison', 'a< 5: print "zero"')) linter.reporter.display_reports(Section()) self.assertMultiLineEqual(output.getvalue(), expected)
def test_addmessage(linter: PyLinter) -> None: linter.set_reporter(testutils.GenericTestReporter()) linter.open() linter.set_current_module("0123") linter.add_message("C0301", line=1, args=(1, 2)) linter.add_message("line-too-long", line=2, args=(3, 4)) assert len(linter.reporter.messages) == 2 assert linter.reporter.messages[0] == Message( msg_id="C0301", symbol="line-too-long", msg="Line too long (1/2)", confidence=interfaces.Confidence( name="UNDEFINED", description="Warning without any associated confidence level.", ), location=MessageLocationTuple( abspath="0123", path="0123", module="0123", obj="", line=1, column=0, end_line=None, end_column=None, ), ) assert linter.reporter.messages[1] == Message( msg_id="C0301", symbol="line-too-long", msg="Line too long (3/4)", confidence=interfaces.Confidence( name="UNDEFINED", description="Warning without any associated confidence level.", ), location=MessageLocationTuple( abspath="0123", path="0123", module="0123", obj="", line=2, column=0, end_line=None, end_column=None, ), )
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = cStringIO.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n')
def get_linter_result(score: bool, message: Dict[str, Any]) -> List[Dict[str, Any]]: output = StringIO() reporter = JSONReporter(output) linter = PyLinter(reporter=reporter) checkers.initialize(linter) linter.namespace.persistent = 0 linter.namespace.score = score linter.open() linter.set_current_module("0123") linter.add_message( message["msg"], line=message["line"], args=message["args"], end_lineno=message["end_line"], end_col_offset=message["end_column"], ) # we call those methods because we didn't actually run the checkers if score: reporter.display_reports(EvaluationSection(expected_score_message)) reporter.display_messages(None) report_result = json.loads(output.getvalue()) return report_result
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_regression(self): output = six.StringIO() linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n')
def test_addmessage_invalid(linter: PyLinter) -> None: linter.set_reporter(testutils.GenericTestReporter()) linter.open() linter.set_current_module("0123") with pytest.raises(InvalidMessageError) as cm: linter.add_message("line-too-long", args=(1, 2)) assert str(cm.value) == "Message C0301 must provide line, got None" with pytest.raises(InvalidMessageError) as cm: linter.add_message("line-too-long", line=2, node="fake_node", args=(1, 2)) assert ( str(cm.value) == "Message C0301 must only provide line, got line=2, node=fake_node" ) with pytest.raises(InvalidMessageError) as cm: linter.add_message("C0321") assert str(cm.value) == "Message C0321 must provide Node, got None"
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def init_linter(self): linter = self.linter linter.open() linter.set_current_module('toto') linter.file_state = FileState('toto') return linter def test_pylint_visit_method_taken_in_account(self): class CustomChecker(checkers.BaseChecker): __implements__ = interfaces.IAstroidChecker name = 'custom' msgs = {'W9999': ('', 'custom', '')} @check_messages('custom') def visit_class(self, _): pass self.linter.register_checker(CustomChecker(self.linter)) self.linter.open() out = six.moves.StringIO() self.linter.set_reporter(text.TextReporter(out)) self.linter.check('abc') def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) self.assertFalse(linter.is_message_enabled('C0202', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) self.assertTrue(linter.is_message_enabled('C0202', line=1)) def test_message_state_scope(self): class FakeConfig(object): confidence = ['HIGH'] linter = self.init_linter() linter.disable('C0202') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0202')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0202')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) linter.config = FakeConfig() self.assertEqual( MSG_STATE_CONFIDENCE, linter.get_message_state_scope('this-is-bad', confidence=interfaces.INFERENCE)) def test_enable_message_block(self): linter = self.init_linter() linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) fs = linter.file_state fs.collect_block_lines(linter.msgs_store, astroid) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) fs = linter.file_state self.assertEqual(17, fs._suppression_mapping['W0613', 18]) self.assertEqual(30, fs._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in fs._suppression_mapping) self.assertEqual(1, fs._suppression_mapping['C0302', 18]) self.assertEqual(1, fs._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, fs._suppression_mapping['E1101', 108]) self.assertEqual(109, fs._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse(linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True self.linter.config.reports = True pylint_strio = 'pylint_%s.txt' % strio files = [pylint_strio, 'pylint_global.txt'] for file in files: self.addCleanup(remove, file) self.linter.check(strio) self.linter.generate_reports() for f in files: self.assertTrue(os.path.exists(f)) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0234') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0234')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('non-iterator-returned')) def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0234') ) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0234')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('non-iterator-returned')) def test_enable_checkers(self): self.linter.disable('design') self.assertFalse('design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue('design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse('similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities'): self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_init_hooks_called_before_load_plugins(self): self.assertRaises(RuntimeError, Run, ['--load-plugins', 'unexistant', '--init-hook', 'raise RuntimeError']) self.assertRaises(RuntimeError, Run, ['--init-hook', 'raise RuntimeError', '--load-plugins', 'unexistant']) def test_analyze_explicit_script(self): self.linter.set_reporter(TestReporter()) self.linter.check(os.path.join(os.path.dirname(__file__), 'data', 'ascript')) self.assertEqual( ['C: 2: Line too long (175/100)'], self.linter.reporter.messages) def test_html_reporter_missing_files(self): output = six.StringIO() self.linter.set_reporter(html.HTMLReporter(output)) self.linter.set_option('output-format', 'html') self.linter.check('troppoptop.py') self.linter.generate_reports() value = output.getvalue() self.assertIn('troppoptop.py', value) self.assertIn('fatal', value) def test_python3_checker_disabled(self): checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertNotIn('python3', checker_names) self.linter.set_option('enable', 'python3') checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertIn('python3', checker_names)
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_deprecated(self): with warnings.catch_warnings(record=True) as cm: warnings.simplefilter("always") ParseableTextReporter() self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning) def test_parseable_output_regression(self): output = six.StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n') @unittest.expectedFailure def test_html_reporter_type(self): # Integration test for issue #263 # https://bitbucket.org/logilab/pylint/issue/263/html-report-type-problems expected = '''<html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>type</th> <th>module</th> <th>object</th> <th>line</th> <th>col_offset</th> <th>message</th> </tr> <tr class="even"> <td>convention</td> <td>0123</td> <td> </td> <td>1</td> <td>0</td> <td>Exactly one space required before comparison a< 5: print "zero"</td> </tr> </table> </div> </div> </body> </html> ''' output = six.StringIO() linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module('0123') linter.add_message('bad-whitespace', line=1, args=('Exactly one', 'required', 'before', 'comparison', 'a< 5: print "zero"')) linter.reporter.display_results(Section()) self.assertMultiLineEqual(output.getvalue(), expected)
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable("I") self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def init_linter(self): linter = self.linter linter.open() linter.set_current_module("toto") linter.file_state = FileState("toto") return linter def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("W0102")) linter.disable("W0101", scope="package") linter.disable("W0102", scope="module", line=1) self.assertFalse(linter.is_message_enabled("W0101")) self.assertFalse(linter.is_message_enabled("W0102", 1)) linter.set_current_module("tutu") self.assertFalse(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("W0102")) linter.enable("W0101", scope="package") linter.enable("W0102", scope="module", line=1) self.assertTrue(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("W0102", 1)) def test_enable_message_category(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("C0121")) linter.disable("W", scope="package") linter.disable("C", scope="module", line=1) self.assertFalse(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("C0121")) self.assertFalse(linter.is_message_enabled("C0121", line=1)) linter.set_current_module("tutu") self.assertFalse(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("C0121")) linter.enable("W", scope="package") linter.enable("C", scope="module", line=1) self.assertTrue(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("C0121")) self.assertTrue(linter.is_message_enabled("C0121", line=1)) def test_message_state_scope(self): class FakeConfig(object): confidence = ["HIGH"] linter = self.init_linter() linter.disable("C0121") self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope("C0121")) linter.disable("W0101", scope="module", line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope("C0121")) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope("W0101", 3)) linter.enable("W0102", scope="module", line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope("W0102", 3)) linter.config = FakeConfig() self.assertEqual( MSG_STATE_CONFIDENCE, linter.get_message_state_scope("this-is-bad", confidence=interfaces.INFERENCE) ) def test_enable_message_block(self): linter = self.init_linter() linter.open() filepath = join(INPUTDIR, "func_block_disable_msg.py") linter.set_current_module("func_block_disable_msg") astroid = linter.get_ast(filepath, "func_block_disable_msg") linter.process_tokens(tokenize_module(astroid)) fs = linter.file_state fs.collect_block_lines(linter.msgs_store, astroid) # global (module level) self.assertTrue(linter.is_message_enabled("W0613")) self.assertTrue(linter.is_message_enabled("E1101")) # meth1 self.assertTrue(linter.is_message_enabled("W0613", 13)) # meth2 self.assertFalse(linter.is_message_enabled("W0613", 18)) # meth3 self.assertFalse(linter.is_message_enabled("E1101", 24)) self.assertTrue(linter.is_message_enabled("E1101", 26)) # meth4 self.assertFalse(linter.is_message_enabled("E1101", 32)) self.assertTrue(linter.is_message_enabled("E1101", 36)) # meth5 self.assertFalse(linter.is_message_enabled("E1101", 42)) self.assertFalse(linter.is_message_enabled("E1101", 43)) self.assertTrue(linter.is_message_enabled("E1101", 46)) self.assertFalse(linter.is_message_enabled("E1101", 49)) self.assertFalse(linter.is_message_enabled("E1101", 51)) # meth6 self.assertFalse(linter.is_message_enabled("E1101", 57)) self.assertTrue(linter.is_message_enabled("E1101", 61)) self.assertFalse(linter.is_message_enabled("E1101", 64)) self.assertFalse(linter.is_message_enabled("E1101", 66)) self.assertTrue(linter.is_message_enabled("E0602", 57)) self.assertTrue(linter.is_message_enabled("E0602", 61)) self.assertFalse(linter.is_message_enabled("E0602", 62)) self.assertTrue(linter.is_message_enabled("E0602", 64)) self.assertTrue(linter.is_message_enabled("E0602", 66)) # meth7 self.assertFalse(linter.is_message_enabled("E1101", 70)) self.assertTrue(linter.is_message_enabled("E1101", 72)) self.assertTrue(linter.is_message_enabled("E1101", 75)) self.assertTrue(linter.is_message_enabled("E1101", 77)) fs = linter.file_state self.assertEqual(17, fs._suppression_mapping["W0613", 18]) self.assertEqual(30, fs._suppression_mapping["E1101", 33]) self.assertTrue(("E1101", 46) not in fs._suppression_mapping) self.assertEqual(1, fs._suppression_mapping["C0302", 18]) self.assertEqual(1, fs._suppression_mapping["C0302", 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, fs._suppression_mapping["E1101", 108]) self.assertEqual(109, fs._suppression_mapping["E1101", 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.init_linter() self.assertTrue(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("unreachable")) self.assertTrue(linter.is_message_enabled("W0102")) self.assertTrue(linter.is_message_enabled("dangerous-default-value")) linter.disable("unreachable", scope="package") linter.disable("dangerous-default-value", scope="module", line=1) self.assertFalse(linter.is_message_enabled("W0101")) self.assertFalse(linter.is_message_enabled("unreachable")) self.assertFalse(linter.is_message_enabled("W0102", 1)) self.assertFalse(linter.is_message_enabled("dangerous-default-value", 1)) linter.set_current_module("tutu") self.assertFalse(linter.is_message_enabled("W0101")) self.assertFalse(linter.is_message_enabled("unreachable")) self.assertTrue(linter.is_message_enabled("W0102")) self.assertTrue(linter.is_message_enabled("dangerous-default-value")) linter.enable("unreachable", scope="package") linter.enable("dangerous-default-value", scope="module", line=1) self.assertTrue(linter.is_message_enabled("W0101")) self.assertTrue(linter.is_message_enabled("unreachable")) self.assertTrue(linter.is_message_enabled("W0102", 1)) self.assertTrue(linter.is_message_enabled("dangerous-default-value", 1)) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = "StringIO" else: strio = "io" self.linter.config.files_output = True pylint_strio = "pylint_%s.txt" % strio files = [pylint_strio, "pylint_global.txt"] for file in files: self.addCleanup(remove, file) self.linter.check(strio) self.linter.generate_reports() for f in files: self.assertTrue(os.path.exists(f)) def test_lint_should_analyze_file(self): self.linter.set_reporter(text.TextReporter()) self.linter.config.files_output = True self.linter.should_analyze_file = lambda *args: False self.addCleanup(remove, "pylint_logilab.txt") self.linter.check("logilab") self.assertTrue(os.path.exists("pylint_logilab.txt")) self.assertFalse(os.path.exists("pylint_logilab_common.txt")) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled("RP0001"), True) self.linter.disable("RP0001") self.assertEqual(self.linter.report_is_enabled("RP0001"), False) self.linter.enable("RP0001") self.assertEqual(self.linter.report_is_enabled("RP0001"), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option("output-format", "text") self.assertEqual(self.linter.reporter.__class__.__name__, "TextReporter") def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, "TestReporter")) self.linter.set_option("output-format", class_name) self.assertEqual(self.linter.reporter.__class__.__name__, "TestReporter") def test_set_option_1(self): linter = self.linter linter.set_option("disable", "C0111,W0142") self.assertFalse(linter.is_message_enabled("C0111")) self.assertFalse(linter.is_message_enabled("W0142")) self.assertTrue(linter.is_message_enabled("W0113")) self.assertFalse(linter.is_message_enabled("missing-docstring")) self.assertFalse(linter.is_message_enabled("star-args")) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option("disable", ("C0111", "W0142")) self.assertFalse(linter.is_message_enabled("C0111")) self.assertFalse(linter.is_message_enabled("W0142")) self.assertTrue(linter.is_message_enabled("W0113")) self.assertFalse(linter.is_message_enabled("missing-docstring")) self.assertFalse(linter.is_message_enabled("star-args")) # no name for W0113 def test_enable_checkers(self): self.linter.disable("design") self.assertFalse("design" in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable("design") self.assertTrue("design" in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(("design", "format", "imports", "metrics", "miscellaneous", "similarities")) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option("disable", "RP0801") self.linter.set_option("disable", "R0801") self.assertFalse("similarities" in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option("reports", False) self.linter.set_option("disable", "R,C,W") checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ("design", "metrics", "similarities", "imports"): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module("0123") self.linter.add_message("C0301", line=1, args=(1, 2)) self.linter.add_message("line-too-long", line=2, args=(3, 4)) self.assertEqual(["C: 1: Line too long (1/2)", "C: 2: Line too long (3/4)"], self.linter.reporter.messages) def test_init_hooks_called_before_load_plugins(self): self.assertRaises(RuntimeError, Run, ["--load-plugins", "unexistant", "--init-hook", "raise RuntimeError"]) self.assertRaises(RuntimeError, Run, ["--init-hook", "raise RuntimeError", "--load-plugins", "unexistant"]) def test_analyze_explicit_script(self): self.linter.set_reporter(TestReporter()) self.linter.check(os.path.join(os.path.dirname(__file__), "data", "ascript")) self.assertEqual(["C: 2: Line too long (175/100)"], self.linter.reporter.messages) def test_html_reporter_missing_files(self): output = six.StringIO() self.linter.set_reporter(html.HTMLReporter(output)) self.linter.set_option("output-format", "html") self.linter.check("troppoptop.py") self.linter.generate_reports() value = output.getvalue() self.assertIn("troppoptop.py", value) self.assertIn("fatal", value) def test_python3_checker_disabled(self): checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertNotIn("python3", checker_names) self.linter.set_option("enable", "python3") checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertIn("python3", checker_names)
def _config_initialization( linter: PyLinter, args_list: list[str], reporter: reporters.BaseReporter | reporters.MultiReporter | None = None, config_file: None | str | Path = None, verbose_mode: bool = False, ) -> list[str]: """Parse all available options, read config files and command line arguments and set options accordingly. """ config_file = Path(config_file) if config_file else None # Set the current module to the configuration file # to allow raising messages on the configuration file. linter.set_current_module(str(config_file) if config_file else "") # Read the configuration file config_file_parser = _ConfigurationFileParser(verbose_mode, linter) try: config_data, config_args = config_file_parser.parse_config_file( file_path=config_file) except OSError as ex: print(ex, file=sys.stderr) sys.exit(32) # Run init hook, if present, before loading plugins if "init-hook" in config_data: exec(utils._unquote(config_data["init-hook"])) # pylint: disable=exec-used # Load plugins if specified in the config file if "load-plugins" in config_data: linter.load_plugin_modules( utils._splitstrip(config_data["load-plugins"])) unrecognized_options_message = None # First we parse any options from a configuration file try: linter._parse_configuration_file(config_args) except _UnrecognizedOptionError as exc: unrecognized_options_message = ", ".join(exc.options) # Then, if a custom reporter is provided as argument, it may be overridden # by file parameters, so we re-set it here. We do this before command line # parsing, so it's still overridable by command line options if reporter: linter.set_reporter(reporter) # Set the current module to the command line # to allow raising messages on it linter.set_current_module("Command line") # Now we parse any options from the command line, so they can override # the configuration file parsed_args_list = linter._parse_command_line_configuration(args_list) # Check if there are any options that we do not recognize unrecognized_options: list[str] = [] for opt in parsed_args_list: if opt.startswith("--"): unrecognized_options.append(opt[2:]) elif opt.startswith("-"): unrecognized_options.append(opt[1:]) if unrecognized_options: msg = ", ".join(unrecognized_options) linter._arg_parser.error(f"Unrecognized option found: {msg}") # Now that config file and command line options have been loaded # with all disables, it is safe to emit messages if unrecognized_options_message is not None: linter.set_current_module(str(config_file) if config_file else "") linter.add_message("unrecognized-option", args=unrecognized_options_message, line=0) linter._emit_stashed_messages() # Set the current module to configuration as we don't know where # the --load-plugins key is coming from linter.set_current_module("Command line or configuration file") # We have loaded configuration from config file and command line. Now, we can # load plugin specific configuration. linter.load_plugin_configuration() # Now that plugins are loaded, get list of all fail_on messages, and enable them linter.enable_fail_on_messages() linter._parse_error_mode() # Link the base Namespace object on the current directory linter._directory_namespaces[Path(".").resolve()] = (linter.config, {}) # parsed_args_list should now only be a list of files/directories to lint. # All other options have been removed from the list. return parsed_args_list
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_deprecated(self): with testutils.catch_warnings() as cm: ParseableTextReporter() self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning) def test_html_reporter_deprecated(self): with testutils.catch_warnings() as caught: HTMLReporter() self.assertEqual(len(caught), 1) self.assertIsInstance(caught[0].message, DeprecationWarning) self.assertEqual(str(caught[0].message), 'This reporter will be removed in Pylint 2.0.') def test_parseable_output_regression(self): output = six.StringIO() with testutils.catch_warnings(): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual( output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n') def test_html_reporter_msg_template(self): expected = ''' <html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>category</th> <th>msg_id</th> </tr> <tr class="even"> <td>warning</td> <td>W0332</td> </tr> </table> </div> </div> </body> </html>'''.strip().splitlines() output = six.StringIO() with testutils.catch_warnings(): linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('msg-template', '{category}{msg_id}') linter.open() linter.set_current_module('0123') linter.add_message('lowercase-l-suffix', line=1) linter.reporter.display_messages(Section()) self.assertEqual(output.getvalue().splitlines(), expected) @unittest.expectedFailure def test_html_reporter_type(self): # Integration test for issue #263 # https://bitbucket.org/logilab/pylint/issue/263/html-report-type-problems expected = '''<html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>type</th> <th>module</th> <th>object</th> <th>line</th> <th>col_offset</th> <th>message</th> </tr> <tr class="even"> <td>convention</td> <td>0123</td> <td> </td> <td>1</td> <td>0</td> <td>Exactly one space required before comparison a< 5: print "zero"</td> </tr> </table> </div> </div> </body> </html> ''' output = six.StringIO() with testutils.catch_warnings(): linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module('0123') linter.add_message('bad-whitespace', line=1, args=('Exactly one', 'required', 'before', 'comparison', 'a< 5: print "zero"')) linter.reporter.display_reports(Section()) self.assertMultiLineEqual(output.getvalue(), expected) def test_display_results_is_renamed(self): class CustomReporter(TextReporter): def _display(self, layout): return None reporter = CustomReporter() if __pkginfo__.numversion >= (2, 0): with self.assertRaises(AttributeError): reporter.display_results else: with testutils.catch_warnings() as cm: reporter.display_results(Section()) self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def test_message_help(self): msg = self.linter.get_message_help('F0001', checkerref=True) expected = ':F0001 (fatal):\n Used when an error occurred preventing the analysis of a module (unable to\n find it for instance). This message belongs to the master checker.' self.assertMultiLineEqual(msg, expected) self.assertRaises(UnknownMessage, self.linter.get_message_help, 'YB12') def test_enable_message(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertFalse(linter.is_message_enabled('C0121', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertTrue(linter.is_message_enabled('C0121', line=1)) def test_message_state_scope(self): linter = self.linter linter.open() linter.disable('C0121') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) def test_enable_message_block(self): linter = self.linter linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_astroid(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) orig_state = linter._module_msgs_state.copy() linter._module_msgs_state = {} linter._suppression_mapping = {} linter.collect_block_lines(astroid, orig_state) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) self.assertEqual(17, linter._suppression_mapping['W0613', 18]) self.assertEqual(30, linter._suppression_mapping['E1101', 33]) self.assert_(('E1101', 46) not in linter._suppression_mapping) self.assertEqual(1, linter._suppression_mapping['C0302', 18]) self.assertEqual(1, linter._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, linter._suppression_mapping['E1101', 108]) self.assertEqual(109, linter._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse(linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_list_messages(self): sys.stdout = StringIO() try: self.linter.list_messages() output = sys.stdout.getvalue() finally: sys.stdout = sys.__stdout__ # cursory examination of the output: we're mostly testing it completes self.assertTrue(':C0112 (empty-docstring): *Empty %s docstring*' in output) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True pylint_strio = 'pylint_%s.txt' % strio try: self.linter.check(strio) self.assertTrue(os.path.exists(pylint_strio)) self.assertTrue(os.path.exists('pylint_global.txt')) finally: try: os.remove(pylint_strio) os.remove('pylint_global.txt') except: pass def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0142') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0142') ) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_enable_checkers(self): self.linter.disable('design') self.assertFalse('design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue('design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'imports', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse('similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities', 'imports'): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages)
def test_multi_format_output(tmp_path): text = StringIO(newline=None) json = tmp_path / "somefile.json" source_file = tmp_path / "somemodule.py" source_file.write_text('NOT_EMPTY = "This module is not empty"\n') escaped_source_file = dumps(str(source_file)) nop_format = NopReporter.__module__ + "." + NopReporter.__name__ formats = ",".join(["json:" + str(json), "text", nop_format]) with redirect_stdout(text): linter = PyLinter() linter.load_default_plugins() linter.set_option("persistent", False) linter.set_option("reports", True) linter.set_option("score", True) linter.set_option("score", True) linter.set_option("output-format", formats) assert linter.reporter.linter is linter with pytest.raises(NotImplementedError): linter.reporter.out = text linter.open() linter.check_single_file_item( FileItem("somemodule", source_file, "somemodule")) linter.add_message("line-too-long", line=1, args=(1, 2)) linter.generate_reports() linter.reporter.writeln("direct output") # Ensure the output files are flushed and closed linter.reporter.close_output_files() del linter.reporter with open(json, encoding="utf-8") as f: assert (f.read() == "[\n" " {\n" ' "type": "convention",\n' ' "module": "somemodule",\n' ' "obj": "",\n' ' "line": 1,\n' ' "column": 0,\n' ' "endLine": null,\n' ' "endColumn": null,\n' f' "path": {escaped_source_file},\n' ' "symbol": "missing-module-docstring",\n' ' "message": "Missing module docstring",\n' ' "message-id": "C0114"\n' " },\n" " {\n" ' "type": "convention",\n' ' "module": "somemodule",\n' ' "obj": "",\n' ' "line": 1,\n' ' "column": 0,\n' ' "endLine": null,\n' ' "endColumn": null,\n' f' "path": {escaped_source_file},\n' ' "symbol": "line-too-long",\n' ' "message": "Line too long (1/2)",\n' ' "message-id": "C0301"\n' " }\n" "]\n" "direct output\n") assert ( text.getvalue() == "A NopReporter was initialized.\n" "************* Module somemodule\n" f"{source_file}:1:0: C0114: Missing module docstring (missing-module-docstring)\n" f"{source_file}:1:0: C0301: Line too long (1/2) (line-too-long)\n" "\n" "\n" "Report\n" "======\n" "1 statements analysed.\n" "\n" "Statistics by type\n" "------------------\n" "\n" "+---------+-------+-----------+-----------+------------+---------+\n" "|type |number |old number |difference |%documented |%badname |\n" "+=========+=======+===========+===========+============+=========+\n" "|module |1 |NC |NC |0.00 |0.00 |\n" "+---------+-------+-----------+-----------+------------+---------+\n" "|class |0 |NC |NC |0 |0 |\n" "+---------+-------+-----------+-----------+------------+---------+\n" "|method |0 |NC |NC |0 |0 |\n" "+---------+-------+-----------+-----------+------------+---------+\n" "|function |0 |NC |NC |0 |0 |\n" "+---------+-------+-----------+-----------+------------+---------+\n" "\n" "\n" "\n" "3 lines have been analyzed\n" "\n" "Raw metrics\n" "-----------\n" "\n" "+----------+-------+------+---------+-----------+\n" "|type |number |% |previous |difference |\n" "+==========+=======+======+=========+===========+\n" "|code |2 |66.67 |NC |NC |\n" "+----------+-------+------+---------+-----------+\n" "|docstring |0 |0.00 |NC |NC |\n" "+----------+-------+------+---------+-----------+\n" "|comment |0 |0.00 |NC |NC |\n" "+----------+-------+------+---------+-----------+\n" "|empty |1 |33.33 |NC |NC |\n" "+----------+-------+------+---------+-----------+\n" "\n" "\n" "\n" "Duplication\n" "-----------\n" "\n" "+-------------------------+------+---------+-----------+\n" "| |now |previous |difference |\n" "+=========================+======+=========+===========+\n" "|nb duplicated lines |0 |NC |NC |\n" "+-------------------------+------+---------+-----------+\n" "|percent duplicated lines |0.000 |NC |NC |\n" "+-------------------------+------+---------+-----------+\n" "\n" "\n" "\n" "Messages by category\n" "--------------------\n" "\n" "+-----------+-------+---------+-----------+\n" "|type |number |previous |difference |\n" "+===========+=======+=========+===========+\n" "|convention |2 |NC |NC |\n" "+-----------+-------+---------+-----------+\n" "|refactor |0 |NC |NC |\n" "+-----------+-------+---------+-----------+\n" "|warning |0 |NC |NC |\n" "+-----------+-------+---------+-----------+\n" "|error |0 |NC |NC |\n" "+-----------+-------+---------+-----------+\n" "\n" "\n" "\n" "Messages\n" "--------\n" "\n" "+-------------------------+------------+\n" "|message id |occurrences |\n" "+=========================+============+\n" "|missing-module-docstring |1 |\n" "+-------------------------+------------+\n" "|line-too-long |1 |\n" "+-------------------------+------------+\n" "\n" "\n" "\n" "\n" "-----------------------------------\n" "Your code has been rated at 0.00/10\n" "\n" "direct output\n")
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def init_linter(self): linter = self.linter linter.open() linter.set_current_module('toto') linter.file_state = FileState('toto') return linter def test_pylint_visit_method_taken_in_account(self): class CustomChecker(checkers.BaseChecker): __implements__ = interfaces.IAstroidChecker name = 'custom' msgs = {'W9999': ('', 'custom', '')} @check_messages('custom') def visit_class(self, _): pass self.linter.register_checker(CustomChecker(self.linter)) self.linter.open() out = six.moves.StringIO() self.linter.set_reporter(text.TextReporter(out)) self.linter.check('abc') def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) self.assertFalse(linter.is_message_enabled('C0202', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) self.assertTrue(linter.is_message_enabled('C0202', line=1)) def test_message_state_scope(self): class FakeConfig(object): confidence = ['HIGH'] linter = self.init_linter() linter.disable('C0202') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0202')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0202')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) linter.config = FakeConfig() self.assertEqual( MSG_STATE_CONFIDENCE, linter.get_message_state_scope('this-is-bad', confidence=interfaces.INFERENCE)) def test_enable_message_block(self): linter = self.init_linter() linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) fs = linter.file_state fs.collect_block_lines(linter.msgs_store, astroid) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) fs = linter.file_state self.assertEqual(17, fs._suppression_mapping['W0613', 18]) self.assertEqual(30, fs._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in fs._suppression_mapping) self.assertEqual(1, fs._suppression_mapping['C0302', 18]) self.assertEqual(1, fs._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, fs._suppression_mapping['E1101', 108]) self.assertEqual(109, fs._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse( linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0234') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0234')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('non-iterator-returned')) def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0234')) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0234')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('non-iterator-returned')) def test_enable_checkers(self): self.linter.disable('design') self.assertFalse( 'design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue( 'design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set( ('design', 'format', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse( 'similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities'): self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_addmessage_invalid(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') with self.assertRaises(InvalidMessageError) as cm: self.linter.add_message('line-too-long', args=(1, 2)) self.assertEqual(str(cm.exception), "Message C0301 must provide line, got None") with self.assertRaises(InvalidMessageError) as cm: self.linter.add_message('line-too-long', line=2, node='fake_node', args=(1, 2)) self.assertEqual( str(cm.exception), "Message C0301 must only provide line, got line=2, node=fake_node") with self.assertRaises(InvalidMessageError) as cm: self.linter.add_message('C0321') self.assertEqual(str(cm.exception), "Message C0321 must provide Node, got None") def test_init_hooks_called_before_load_plugins(self): self.assertRaises(RuntimeError, Run, [ '--load-plugins', 'unexistant', '--init-hook', 'raise RuntimeError' ]) self.assertRaises(RuntimeError, Run, [ '--init-hook', 'raise RuntimeError', '--load-plugins', 'unexistant' ]) def test_analyze_explicit_script(self): self.linter.set_reporter(TestReporter()) self.linter.check( os.path.join(os.path.dirname(__file__), 'data', 'ascript')) self.assertEqual(['C: 2: Line too long (175/100)'], self.linter.reporter.messages) def test_python3_checker_disabled(self): checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertNotIn('python3', checker_names) self.linter.set_option('enable', 'python3') checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertIn('python3', checker_names) def test_full_documentation(self): out = six.StringIO() self.linter.print_full_documentation(out) output = out.getvalue() # A few spot checks only for re_str in [ # autogenerated text "^Pylint global options and switches$", "Verbatim name of the checker is ``python3``", # messages "^:old-octal-literal \(E1608\):", # options "^:dummy-variables-rgx:", ]: regexp = re.compile(re_str, re.MULTILINE) self.assertRegexpMatches(output, regexp)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def _compare_messages(self, desc, msg, checkerref=False): # replace \r\n with \n, because # logilab.common.textutils.normalize_text # uses os.linesep, which will # not properly compare with triple # quoted multilines used in these tests self.assertMultiLineEqual(desc, msg.format_help(checkerref=checkerref) .replace('\r\n', '\n')) def test_check_message_id(self): self.assertIsInstance(self.linter.check_message_id('F0001'), MessageDefinition) self.assertRaises(UnknownMessage, self.linter.check_message_id, 'YB12') def test_message_help(self): msg = self.linter.check_message_id('F0001') self._compare_messages( ''':fatal (F0001): Used when an error occurred preventing the analysis of a module (unable to find it for instance). This message belongs to the master checker.''', msg, checkerref=True) self._compare_messages( ''':fatal (F0001): Used when an error occurred preventing the analysis of a module (unable to find it for instance).''', msg, checkerref=False) def test_message_help_minmax(self): # build the message manually to be python version independant msg = build_message_def(self.linter._checkers['typecheck'][0], 'E1122', checkers.typecheck.MSGS['E1122']) self._compare_messages( ''':duplicate-keyword-arg (E1122): *Duplicate keyword argument %r in function call* Used when a function call passes the same keyword argument multiple times. This message belongs to the typecheck checker. It can't be emitted when using Python >= 2.6.''', msg, checkerref=True) self._compare_messages( ''':duplicate-keyword-arg (E1122): *Duplicate keyword argument %r in function call* Used when a function call passes the same keyword argument multiple times. This message can't be emitted when using Python >= 2.6.''', msg, checkerref=False) def test_enable_message(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertFalse(linter.is_message_enabled('C0121', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertTrue(linter.is_message_enabled('C0121', line=1)) def test_message_state_scope(self): linter = self.linter linter.open() linter.disable('C0121') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) def test_enable_message_block(self): linter = self.linter linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) orig_state = linter._module_msgs_state.copy() linter._module_msgs_state = {} linter._suppression_mapping = {} linter.collect_block_lines(astroid, orig_state) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) self.assertEqual(17, linter._suppression_mapping['W0613', 18]) self.assertEqual(30, linter._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in linter._suppression_mapping) self.assertEqual(1, linter._suppression_mapping['C0302', 18]) self.assertEqual(1, linter._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, linter._suppression_mapping['E1101', 108]) self.assertEqual(109, linter._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse(linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_list_messages(self): sys.stdout = StringIO() try: self.linter.list_messages() output = sys.stdout.getvalue() finally: sys.stdout = sys.__stdout__ # cursory examination of the output: we're mostly testing it completes self.assertIn(':empty-docstring (C0112): *Empty %s docstring*', output) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True pylint_strio = 'pylint_%s.txt' % strio try: self.linter.check(strio) self.assertTrue(os.path.exists(pylint_strio)) self.assertTrue(os.path.exists('pylint_global.txt')) finally: try: os.remove(pylint_strio) os.remove('pylint_global.txt') except: pass def test_lint_should_analyze_file(self): self.linter.set_reporter(text.TextReporter()) self.linter.config.files_output = True self.linter.should_analyze_file = lambda *args: False self.linter.check('os') self.assertFalse(os.path.exists('pylint_os.txt')) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0142') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0142') ) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_enable_checkers(self): self.linter.disable('design') self.assertFalse('design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue('design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'imports', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse('similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities', 'imports'): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_add_renamed_message(self): self.linter.add_renamed_message('C9999', 'old-bad-name', 'invalid-name') self.assertEqual('invalid-name', self.linter.check_message_id('C9999').symbol) self.assertEqual('invalid-name', self.linter.check_message_id('old-bad-name').symbol) def test_renamed_message_register(self): class Checker(object): msgs = {'W1234': ('message', 'msg-symbol', 'msg-description', {'old_names': [('W0001', 'old-symbol')]})} self.linter.register_messages(Checker()) self.assertEqual('msg-symbol', self.linter.check_message_id('W0001').symbol) self.assertEqual('msg-symbol', self.linter.check_message_id('old-symbol').symbol)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def init_linter(self): linter = self.linter linter.open() linter.set_current_module('toto') linter.file_state = FileState('toto') return linter def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertFalse(linter.is_message_enabled('C0121', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertTrue(linter.is_message_enabled('C0121', line=1)) def test_message_state_scope(self): linter = self.init_linter() fs = linter.file_state linter.disable('C0121') self.assertEqual(MSG_STATE_SCOPE_CONFIG, fs._message_state_scope('C0121')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, fs._message_state_scope('C0121')) self.assertEqual(MSG_STATE_SCOPE_MODULE, fs._message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, fs._message_state_scope('W0102', 3)) def test_enable_message_block(self): linter = self.init_linter() linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) fs = linter.file_state fs.collect_block_lines(linter.msgs_store, astroid) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) fs = linter.file_state self.assertEqual(17, fs._suppression_mapping['W0613', 18]) self.assertEqual(30, fs._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in fs._suppression_mapping) self.assertEqual(1, fs._suppression_mapping['C0302', 18]) self.assertEqual(1, fs._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, fs._suppression_mapping['E1101', 108]) self.assertEqual(109, fs._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse( linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True pylint_strio = 'pylint_%s.txt' % strio try: self.linter.check(strio) self.assertTrue(os.path.exists(pylint_strio)) self.assertTrue(os.path.exists('pylint_global.txt')) finally: try: os.remove(pylint_strio) os.remove('pylint_global.txt') except: pass def test_lint_should_analyze_file(self): self.linter.set_reporter(text.TextReporter()) self.linter.config.files_output = True self.linter.should_analyze_file = lambda *args: False self.linter.check('logilab') self.assertTrue(os.path.exists('pylint_logilab.txt')) self.assertFalse(os.path.exists('pylint_logilab_common.txt')) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0142') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0142')) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_enable_checkers(self): self.linter.disable('design') self.assertFalse( 'design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue( 'design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'imports', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse( 'similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities', 'imports'): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_init_hooks_called_before_load_plugins(self): self.assertRaises(RuntimeError, Run, [ '--load-plugins', 'unexistant', '--init-hook', 'raise RuntimeError' ]) self.assertRaises(RuntimeError, Run, [ '--init-hook', 'raise RuntimeError', '--load-plugins', 'unexistant' ]) def test_analyze_explicit_script(self): self.linter.set_reporter(TestReporter()) self.linter.check(self.datapath('ascript')) self.assertEqual(['C: 2: Line too long (175/80)'], self.linter.reporter.messages)
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_add_message_is_deprecated(self): if __pkginfo__.numversion >= (1, 6, 0): with self.assertRaises(AttributeError): BaseReporter().add_message with warnings.catch_warnings(record=True) as cm: warnings.simplefilter("always") BaseReporter().add_message(None, None, None) self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning) msg = ('This method is deprecated, use handle_message ' 'instead. It will be removed in Pylint 1.6.') self.assertEqual(str(cm[0].message), msg) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_deprecated(self): with warnings.catch_warnings(record=True) as cm: warnings.simplefilter("always") ParseableTextReporter() self.assertEqual(len(cm), 1) self.assertIsInstance(cm[0].message, DeprecationWarning) def test_parseable_output_regression(self): output = six.StringIO() with warnings.catch_warnings(record=True): linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n') def test_html_reporter_msg_template(self): expected = ''' <html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>category</th> <th>msg_id</th> </tr> <tr class="even"> <td>warning</td> <td>W0332</td> </tr> </table> </div> </div> </body> </html>'''.strip().splitlines() output = six.StringIO() linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('msg-template', '{category}{msg_id}') linter.open() linter.set_current_module('0123') linter.add_message('lowercase-l-suffix', line=1) linter.reporter.display_results(Section()) self.assertEqual(output.getvalue().splitlines(), expected) @unittest.expectedFailure def test_html_reporter_type(self): # Integration test for issue #263 # https://bitbucket.org/logilab/pylint/issue/263/html-report-type-problems expected = '''<html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>type</th> <th>module</th> <th>object</th> <th>line</th> <th>col_offset</th> <th>message</th> </tr> <tr class="even"> <td>convention</td> <td>0123</td> <td> </td> <td>1</td> <td>0</td> <td>Exactly one space required before comparison a< 5: print "zero"</td> </tr> </table> </div> </div> </body> </html> ''' output = six.StringIO() linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module('0123') linter.add_message('bad-whitespace', line=1, args=('Exactly one', 'required', 'before', 'comparison', 'a< 5: print "zero"')) linter.reporter.display_results(Section()) self.assertMultiLineEqual(output.getvalue(), expected)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def test_message_help(self): msg = self.linter.get_message_help('F0001', checkerref=True) expected = ':F0001 (fatal):\n Used when an error occurred preventing the analysis of a module (unable to\n find it for instance). This message belongs to the master checker.' self.assertMultiLineEqual(msg, expected) self.assertRaises(UnknownMessage, self.linter.get_message_help, 'YB12') def test_enable_message(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertFalse(linter.is_message_enabled('C0121', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertTrue(linter.is_message_enabled('C0121', line=1)) def test_message_state_scope(self): linter = self.linter linter.open() linter.disable('C0121') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) def test_enable_message_block(self): linter = self.linter linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_astroid(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) orig_state = linter._module_msgs_state.copy() linter._module_msgs_state = {} linter._suppression_mapping = {} linter.collect_block_lines(astroid, orig_state) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) self.assertEqual(17, linter._suppression_mapping['W0613', 18]) self.assertEqual(30, linter._suppression_mapping['E1101', 33]) self.assert_(('E1101', 46) not in linter._suppression_mapping) self.assertEqual(1, linter._suppression_mapping['C0302', 18]) self.assertEqual(1, linter._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, linter._suppression_mapping['E1101', 108]) self.assertEqual(109, linter._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse( linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_list_messages(self): sys.stdout = StringIO() try: self.linter.list_messages() output = sys.stdout.getvalue() finally: sys.stdout = sys.__stdout__ # cursory examination of the output: we're mostly testing it completes self.assertTrue( ':C0112 (empty-docstring): *Empty %s docstring*' in output) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True pylint_strio = 'pylint_%s.txt' % strio try: self.linter.check(strio) self.assertTrue(os.path.exists(pylint_strio)) self.assertTrue(os.path.exists('pylint_global.txt')) finally: try: os.remove(pylint_strio) os.remove('pylint_global.txt') except: pass def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0142') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0142')) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_enable_checkers(self): self.linter.disable('design') self.assertFalse( 'design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue( 'design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'imports', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse( 'similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities', 'imports'): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def _compare_messages(self, desc, msg, checkerref=False): # replace \r\n with \n, because # logilab.common.textutils.normalize_text # uses os.linesep, which will # not properly compare with triple # quoted multilines used in these tests self.assertMultiLineEqual( desc, msg.format_help(checkerref=checkerref).replace('\r\n', '\n')) def test_check_message_id(self): self.assertIsInstance(self.linter.check_message_id('F0001'), MessageDefinition) self.assertRaises(UnknownMessage, self.linter.check_message_id, 'YB12') def test_message_help(self): msg = self.linter.check_message_id('F0001') self._compare_messages(''':fatal (F0001): Used when an error occurred preventing the analysis of a module (unable to find it for instance). This message belongs to the master checker.''', msg, checkerref=True) self._compare_messages(''':fatal (F0001): Used when an error occurred preventing the analysis of a module (unable to find it for instance).''', msg, checkerref=False) def test_message_help_minmax(self): # build the message manually to be python version independant msg = build_message_def(self.linter._checkers['typecheck'][0], 'E1122', checkers.typecheck.MSGS['E1122']) self._compare_messages( ''':duplicate-keyword-arg (E1122): *Duplicate keyword argument %r in function call* Used when a function call passes the same keyword argument multiple times. This message belongs to the typecheck checker. It can't be emitted when using Python >= 2.6.''', msg, checkerref=True) self._compare_messages( ''':duplicate-keyword-arg (E1122): *Duplicate keyword argument %r in function call* Used when a function call passes the same keyword argument multiple times. This message can't be emitted when using Python >= 2.6.''', msg, checkerref=False) def test_enable_message(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertFalse(linter.is_message_enabled('C0121', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertTrue(linter.is_message_enabled('C0121', line=1)) def test_message_state_scope(self): linter = self.linter linter.open() linter.disable('C0121') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0121')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) def test_enable_message_block(self): linter = self.linter linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) orig_state = linter._module_msgs_state.copy() linter._module_msgs_state = {} linter._suppression_mapping = {} linter.collect_block_lines(astroid, orig_state) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) self.assertEqual(17, linter._suppression_mapping['W0613', 18]) self.assertEqual(30, linter._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in linter._suppression_mapping) self.assertEqual(1, linter._suppression_mapping['C0302', 18]) self.assertEqual(1, linter._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, linter._suppression_mapping['E1101', 108]) self.assertEqual(109, linter._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.linter linter.open() linter.set_current_module('toto') self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse( linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_list_messages(self): sys.stdout = StringIO() try: self.linter.list_messages() output = sys.stdout.getvalue() finally: sys.stdout = sys.__stdout__ # cursory examination of the output: we're mostly testing it completes self.assertIn(':empty-docstring (C0112): *Empty %s docstring*', output) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True pylint_strio = 'pylint_%s.txt' % strio try: self.linter.check(strio) self.assertTrue(os.path.exists(pylint_strio)) self.assertTrue(os.path.exists('pylint_global.txt')) finally: try: os.remove(pylint_strio) os.remove('pylint_global.txt') except: pass def test_lint_should_analyze_file(self): self.linter.set_reporter(text.TextReporter()) self.linter.config.files_output = True self.linter.should_analyze_file = lambda *args: False self.linter.check('os') self.assertFalse(os.path.exists('pylint_os.txt')) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0142') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0142')) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_enable_checkers(self): self.linter.disable('design') self.assertFalse( 'design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue( 'design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'imports', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse( 'similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities', 'imports'): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_add_renamed_message(self): self.linter.add_renamed_message('C9999', 'old-bad-name', 'invalid-name') self.assertEqual('invalid-name', self.linter.check_message_id('C9999').symbol) self.assertEqual('invalid-name', self.linter.check_message_id('old-bad-name').symbol) def test_renamed_message_register(self): class Checker(object): msgs = { 'W1234': ('message', 'msg-symbol', 'msg-description', { 'old_names': [('W0001', 'old-symbol')] }) } self.linter.register_messages(Checker()) self.assertEqual('msg-symbol', self.linter.check_message_id('W0001').symbol) self.assertEqual('msg-symbol', self.linter.check_message_id('old-symbol').symbol)
class PyLinterTC(TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def init_linter(self): linter = self.linter linter.open() linter.set_current_module('toto') linter.file_state = FileState('toto') return linter def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertFalse(linter.is_message_enabled('C0121', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0121')) self.assertTrue(linter.is_message_enabled('C0121', line=1)) def test_message_state_scope(self): linter = self.init_linter() fs = linter.file_state linter.disable('C0121') self.assertEqual(MSG_STATE_SCOPE_CONFIG, fs._message_state_scope('C0121')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, fs._message_state_scope('C0121')) self.assertEqual(MSG_STATE_SCOPE_MODULE, fs._message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, fs._message_state_scope('W0102', 3)) def test_enable_message_block(self): linter = self.init_linter() linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) fs = linter.file_state fs.collect_block_lines(linter.msgs_store, astroid) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) fs = linter.file_state self.assertEqual(17, fs._suppression_mapping['W0613', 18]) self.assertEqual(30, fs._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in fs._suppression_mapping) self.assertEqual(1, fs._suppression_mapping['C0302', 18]) self.assertEqual(1, fs._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, fs._suppression_mapping['E1101', 108]) self.assertEqual(109, fs._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse(linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_lint_ext_module_with_file_output(self): self.linter.set_reporter(text.TextReporter()) if sys.version_info < (3, 0): strio = 'StringIO' else: strio = 'io' self.linter.config.files_output = True pylint_strio = 'pylint_%s.txt' % strio try: self.linter.check(strio) self.assertTrue(os.path.exists(pylint_strio)) self.assertTrue(os.path.exists('pylint_global.txt')) finally: try: os.remove(pylint_strio) os.remove('pylint_global.txt') except: pass def test_lint_should_analyze_file(self): self.linter.set_reporter(text.TextReporter()) self.linter.config.files_output = True self.linter.should_analyze_file = lambda *args: False self.linter.check('logilab') self.assertTrue(os.path.exists('pylint_logilab.txt')) self.assertFalse(os.path.exists('pylint_logilab_common.txt')) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_report_output_format_custom(self): this_module = sys.modules[__name__] class TestReporter(object): pass this_module.TestReporter = TestReporter class_name = ".".join((this_module.__name__, 'TestReporter')) self.linter.set_option('output-format', class_name) self.assertEqual(self.linter.reporter.__class__.__name__, 'TestReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0142') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0142') ) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0142')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('star-args')) # no name for W0113 def test_enable_checkers(self): self.linter.disable('design') self.assertFalse('design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue('design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'imports', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse('similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities', 'imports'): # as a Fatal message that should be ignored self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_init_hooks_called_before_load_plugins(self): self.assertRaises(RuntimeError, Run, ['--load-plugins', 'unexistant', '--init-hook', 'raise RuntimeError']) self.assertRaises(RuntimeError, Run, ['--init-hook', 'raise RuntimeError', '--load-plugins', 'unexistant']) def test_analyze_explicit_script(self): self.linter.set_reporter(TestReporter()) self.linter.check(self.datapath('ascript')) self.assertEqual( ['C: 2: Line too long (175/80)'], self.linter.reporter.messages)
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter() self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) self.linter.set_reporter(TestReporter()) def init_linter(self): linter = self.linter linter.open() linter.set_current_module('toto') linter.file_state = FileState('toto') return linter def test_pylint_visit_method_taken_in_account(self): class CustomChecker(checkers.BaseChecker): __implements__ = interfaces.IAstroidChecker name = 'custom' msgs = {'W9999': ('', 'custom', '')} @check_messages('custom') def visit_class(self, _): pass self.linter.register_checker(CustomChecker(self.linter)) self.linter.open() out = six.moves.StringIO() self.linter.set_reporter(text.TextReporter(out)) self.linter.check('abc') def test_enable_message(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.disable('W0101', scope='package') linter.disable('W0102', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('W0102', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102')) linter.enable('W0101', scope='package') linter.enable('W0102', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('W0102', 1)) def test_enable_message_category(self): linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) linter.disable('W', scope='package') linter.disable('C', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) self.assertFalse(linter.is_message_enabled('C0202', line=1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) linter.enable('W', scope='package') linter.enable('C', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('C0202')) self.assertTrue(linter.is_message_enabled('C0202', line=1)) def test_message_state_scope(self): class FakeConfig(object): confidence = ['HIGH'] linter = self.init_linter() linter.disable('C0202') self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0202')) linter.disable('W0101', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_CONFIG, linter.get_message_state_scope('C0202')) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0101', 3)) linter.enable('W0102', scope='module', line=3) self.assertEqual(MSG_STATE_SCOPE_MODULE, linter.get_message_state_scope('W0102', 3)) linter.config = FakeConfig() self.assertEqual( MSG_STATE_CONFIDENCE, linter.get_message_state_scope('this-is-bad', confidence=interfaces.INFERENCE)) def test_enable_message_block(self): linter = self.init_linter() linter.open() filepath = join(INPUTDIR, 'func_block_disable_msg.py') linter.set_current_module('func_block_disable_msg') astroid = linter.get_ast(filepath, 'func_block_disable_msg') linter.process_tokens(tokenize_module(astroid)) fs = linter.file_state fs.collect_block_lines(linter.msgs_store, astroid) # global (module level) self.assertTrue(linter.is_message_enabled('W0613')) self.assertTrue(linter.is_message_enabled('E1101')) # meth1 self.assertTrue(linter.is_message_enabled('W0613', 13)) # meth2 self.assertFalse(linter.is_message_enabled('W0613', 18)) # meth3 self.assertFalse(linter.is_message_enabled('E1101', 24)) self.assertTrue(linter.is_message_enabled('E1101', 26)) # meth4 self.assertFalse(linter.is_message_enabled('E1101', 32)) self.assertTrue(linter.is_message_enabled('E1101', 36)) # meth5 self.assertFalse(linter.is_message_enabled('E1101', 42)) self.assertFalse(linter.is_message_enabled('E1101', 43)) self.assertTrue(linter.is_message_enabled('E1101', 46)) self.assertFalse(linter.is_message_enabled('E1101', 49)) self.assertFalse(linter.is_message_enabled('E1101', 51)) # meth6 self.assertFalse(linter.is_message_enabled('E1101', 57)) self.assertTrue(linter.is_message_enabled('E1101', 61)) self.assertFalse(linter.is_message_enabled('E1101', 64)) self.assertFalse(linter.is_message_enabled('E1101', 66)) self.assertTrue(linter.is_message_enabled('E0602', 57)) self.assertTrue(linter.is_message_enabled('E0602', 61)) self.assertFalse(linter.is_message_enabled('E0602', 62)) self.assertTrue(linter.is_message_enabled('E0602', 64)) self.assertTrue(linter.is_message_enabled('E0602', 66)) # meth7 self.assertFalse(linter.is_message_enabled('E1101', 70)) self.assertTrue(linter.is_message_enabled('E1101', 72)) self.assertTrue(linter.is_message_enabled('E1101', 75)) self.assertTrue(linter.is_message_enabled('E1101', 77)) fs = linter.file_state self.assertEqual(17, fs._suppression_mapping['W0613', 18]) self.assertEqual(30, fs._suppression_mapping['E1101', 33]) self.assertTrue(('E1101', 46) not in fs._suppression_mapping) self.assertEqual(1, fs._suppression_mapping['C0302', 18]) self.assertEqual(1, fs._suppression_mapping['C0302', 50]) # This is tricky. While the disable in line 106 is disabling # both 108 and 110, this is usually not what the user wanted. # Therefore, we report the closest previous disable comment. self.assertEqual(106, fs._suppression_mapping['E1101', 108]) self.assertEqual(109, fs._suppression_mapping['E1101', 110]) def test_enable_by_symbol(self): """messages can be controlled by symbolic names. The state is consistent across symbols and numbers. """ linter = self.init_linter() self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.disable('unreachable', scope='package') linter.disable('dangerous-default-value', scope='module', line=1) self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertFalse(linter.is_message_enabled('W0102', 1)) self.assertFalse(linter.is_message_enabled('dangerous-default-value', 1)) linter.set_current_module('tutu') self.assertFalse(linter.is_message_enabled('W0101')) self.assertFalse(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102')) self.assertTrue(linter.is_message_enabled('dangerous-default-value')) linter.enable('unreachable', scope='package') linter.enable('dangerous-default-value', scope='module', line=1) self.assertTrue(linter.is_message_enabled('W0101')) self.assertTrue(linter.is_message_enabled('unreachable')) self.assertTrue(linter.is_message_enabled('W0102', 1)) self.assertTrue(linter.is_message_enabled('dangerous-default-value', 1)) def test_enable_report(self): self.assertEqual(self.linter.report_is_enabled('RP0001'), True) self.linter.disable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), False) self.linter.enable('RP0001') self.assertEqual(self.linter.report_is_enabled('RP0001'), True) def test_report_output_format_aliased(self): text.register(self.linter) self.linter.set_option('output-format', 'text') self.assertEqual(self.linter.reporter.__class__.__name__, 'TextReporter') def test_set_option_1(self): linter = self.linter linter.set_option('disable', 'C0111,W0234') self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0234')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('non-iterator-returned')) def test_set_option_2(self): linter = self.linter linter.set_option('disable', ('C0111', 'W0234') ) self.assertFalse(linter.is_message_enabled('C0111')) self.assertFalse(linter.is_message_enabled('W0234')) self.assertTrue(linter.is_message_enabled('W0113')) self.assertFalse(linter.is_message_enabled('missing-docstring')) self.assertFalse(linter.is_message_enabled('non-iterator-returned')) def test_enable_checkers(self): self.linter.disable('design') self.assertFalse('design' in [c.name for c in self.linter.prepare_checkers()]) self.linter.enable('design') self.assertTrue('design' in [c.name for c in self.linter.prepare_checkers()]) def test_errors_only(self): linter = self.linter self.linter.error_mode() checkers = self.linter.prepare_checkers() checker_names = set(c.name for c in checkers) should_not = set(('design', 'format', 'metrics', 'miscellaneous', 'similarities')) self.assertSetEqual(set(), should_not & checker_names) def test_disable_similar(self): self.linter.set_option('disable', 'RP0801') self.linter.set_option('disable', 'R0801') self.assertFalse('similarities' in [c.name for c in self.linter.prepare_checkers()]) def test_disable_alot(self): """check that we disabled a lot of checkers""" self.linter.set_option('reports', False) self.linter.set_option('disable', 'R,C,W') checker_names = [c.name for c in self.linter.prepare_checkers()] for cname in ('design', 'metrics', 'similarities'): self.assertFalse(cname in checker_names, cname) def test_addmessage(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertEqual( ['C: 1: Line too long (1/2)', 'C: 2: Line too long (3/4)'], self.linter.reporter.messages) def test_addmessage_invalid(self): self.linter.set_reporter(TestReporter()) self.linter.open() self.linter.set_current_module('0123') with self.assertRaises(InvalidMessageError) as cm: self.linter.add_message('line-too-long', args=(1,2)) self.assertEqual(str(cm.exception), "Message C0301 must provide line, got None") with self.assertRaises(InvalidMessageError) as cm: self.linter.add_message('line-too-long', line=2, node='fake_node', args=(1, 2)) self.assertEqual(str(cm.exception), "Message C0301 must only provide line, got line=2, node=fake_node") with self.assertRaises(InvalidMessageError) as cm: self.linter.add_message('C0321') self.assertEqual(str(cm.exception), "Message C0321 must provide Node, got None") def test_init_hooks_called_before_load_plugins(self): self.assertRaises(RuntimeError, Run, ['--load-plugins', 'unexistant', '--init-hook', 'raise RuntimeError']) self.assertRaises(RuntimeError, Run, ['--init-hook', 'raise RuntimeError', '--load-plugins', 'unexistant']) def test_analyze_explicit_script(self): self.linter.set_reporter(TestReporter()) self.linter.check(os.path.join(os.path.dirname(__file__), 'data', 'ascript')) self.assertEqual( ['C: 2: Line too long (175/100)'], self.linter.reporter.messages) def test_python3_checker_disabled(self): checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertNotIn('python3', checker_names) self.linter.set_option('enable', 'python3') checker_names = [c.name for c in self.linter.prepare_checkers()] self.assertIn('python3', checker_names) def test_full_documentation(self): out = six.StringIO() self.linter.print_full_documentation(out) output = out.getvalue() # A few spot checks only for re_str in [ # autogenerated text "^Pylint global options and switches$", "Verbatim name of the checker is ``python3``", # messages "^:old-octal-literal \(E1608\):", # options "^:dummy-variables-rgx:", ]: regexp = re.compile(re_str, re.MULTILINE) self.assertRegexpMatches(output, regexp)
class PyLinterTC(unittest.TestCase): def setUp(self): self.linter = PyLinter(reporter=TextReporter()) self.linter.disable('I') self.linter.config.persistent = 0 # register checkers checkers.initialize(self.linter) os.environ.pop('PYLINTRC', None) def test_template_option(self): output = six.StringIO() self.linter.reporter.set_output(output) self.linter.set_option('msg-template', '{msg_id}:{line:03d}') self.linter.open() self.linter.set_current_module('0123') self.linter.add_message('C0301', line=1, args=(1, 2)) self.linter.add_message('line-too-long', line=2, args=(3, 4)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' 'C0301:001\n' 'C0301:002\n') def test_parseable_output_regression(self): output = six.StringIO() linter = PyLinter(reporter=ParseableTextReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.set_option('output-format', 'parseable') linter.open() linter.set_current_module('0123') linter.add_message('line-too-long', line=1, args=(1, 2)) self.assertMultiLineEqual(output.getvalue(), '************* Module 0123\n' '0123:1: [C0301(line-too-long), ] ' 'Line too long (1/2)\n') @unittest.expectedFailure def test_html_reporter_type(self): # Integration test for issue #263 # https://bitbucket.org/logilab/pylint/issue/263/html-report-type-problems expected = '''<html> <body> <div> <div> <h2>Messages</h2> <table> <tr class="header"> <th>type</th> <th>module</th> <th>object</th> <th>line</th> <th>col_offset</th> <th>message</th> </tr> <tr class="even"> <td>convention</td> <td>0123</td> <td> </td> <td>1</td> <td>0</td> <td>Exactly one space required before comparison a< 5: print "zero"</td> </tr> </table> </div> </div> </body> </html> ''' output = six.StringIO() linter = PyLinter(reporter=HTMLReporter()) checkers.initialize(linter) linter.config.persistent = 0 linter.reporter.set_output(output) linter.open() linter.set_current_module('0123') linter.add_message('bad-whitespace', line=1, args=('Exactly one', 'required', 'before', 'comparison', 'a< 5: print "zero"')) linter.reporter.display_results(Section()) self.assertMultiLineEqual(output.getvalue(), expected)