def test_new_style_classes(): nsc = NewStyleClasses(PythonFile.from_statement(""" class OldStyle: pass class NewStyle(object): pass """)) nits = list(nsc.nits()) assert len(nits) == 1 assert nits[0]._line_number == 1 assert nits[0].code == 'T606' assert nits[0].severity == Nit.ERROR nsc = NewStyleClasses(PythonFile.from_statement(""" class NewStyle(OtherThing, ThatThing, WhatAmIDoing): pass """)) nits = list(nsc.nits()) assert len(nits) == 0 nsc = NewStyleClasses(PythonFile.from_statement(""" class OldStyle(): # unspecified mro pass """)) nits = list(nsc.nits()) assert len(nits) == 1 assert nits[0].code == 'T606'
def test_indentation(): ind = Indentation( PythonFile.from_statement(""" def foo(): pass """)) nits = list(ind.nits()) assert len(nits) == 1 assert nits[0].code == 'T100' assert nits[0].severity == Nit.ERROR ind = Indentation( PythonFile.from_statement(""" def foo(): pass """)) nits = list(ind.nits()) assert len(nits) == 0 ind = Indentation( PythonFile.from_statement(""" def foo(): baz = ( "this " "is " "ok") """)) nits = list(ind.nits()) assert len(nits) == 0
def test_indentation(): ind = Indentation(PythonFile.from_statement(""" def foo(): pass """)) nits = list(ind.nits()) assert len(nits) == 1 assert nits[0].code == 'T100' assert nits[0].severity == Nit.ERROR ind = Indentation(PythonFile.from_statement(""" def foo(): pass """)) nits = list(ind.nits()) assert len(nits) == 0 ind = Indentation(PythonFile.from_statement(""" def foo(): baz = ( "this " "is " "ok") """)) nits = list(ind.nits()) assert len(nits) == 0
def test_missing_contextmanager(): mcm = MissingContextManager( PythonFile.from_statement(""" with open("derp.txt"): pass with open("herp.txt") as fp: fp.read() """)) nits = list(mcm.nits()) assert len(nits) == 0 mcm = MissingContextManager( PythonFile.from_statement(""" foo = open("derp.txt") """)) nits = list(mcm.nits()) assert len(nits) == 1 assert nits[0].code == 'T802' assert nits[0].severity == Nit.WARNING # TODO(wickman) In these cases suggest using contextlib.closing mcm = MissingContextManager( PythonFile.from_statement(""" from urllib2 import urlopen the_googs = urlopen("http://www.google.com").read() """)) nits = list(mcm.nits()) assert len(nits) == 0
def test_missing_contextmanager(): mcm = MissingContextManager(PythonFile.from_statement(""" with open("derp.txt"): pass with open("herp.txt") as fp: fp.read() """)) nits = list(mcm.nits()) assert len(nits) == 0 mcm = MissingContextManager(PythonFile.from_statement(""" foo = open("derp.txt") """)) nits = list(mcm.nits()) assert len(nits) == 1 assert nits[0].code == 'T802' assert nits[0].severity == Nit.WARNING # TODO(wickman) In these cases suggest using contextlib.closing mcm = MissingContextManager(PythonFile.from_statement(""" from urllib2 import urlopen the_googs = urlopen("http://www.google.com").read() """)) nits = list(mcm.nits()) assert len(nits) == 0
def test_newlines(): for toplevel_def in ('def bar():', 'class Bar(object):'): for num_newlines in (0, 1, 3, 4): newlines = Newlines(PythonFile.from_statement(TOPLEVEL % ('\n' * num_newlines, toplevel_def))) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T302' assert nits[0].severity == Nit.ERROR newlines = Newlines(PythonFile.from_statement(TOPLEVEL % ('\n\n', toplevel_def))) assert len(list(newlines.nits())) == 0
def test_lower_snake_method_names(): p8 = PEP8VariableNames( PythonFile.from_statement(""" def totally_fine(): print("Not in a class body") class DhisRight(object): def clearlyNotThinking(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 5 assert nits[0].severity == Nit.ERROR p8 = PEP8VariableNames( PythonFile.from_statement(""" class DhisRight: def clearlyNotThinking(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 2 assert nits[0].severity == Nit.ERROR # Allow derivations from other modules to be ok. p8 = PEP8VariableNames( PythonFile.from_statement(""" class TestCase(unittest.TestCase): def setUp(self): pass """)) nits = list(p8.nits()) assert len(list(p8.nits())) == 0 p8 = PEP8VariableNames( PythonFile.from_statement(""" def clearlyNotThinking(): print("Not in a class body") class DhisRight(object): def totally_fine(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_newlines(): for toplevel_def in ('def bar():', 'class Bar(object):'): for num_newlines in (0, 1, 3, 4): newlines = Newlines( PythonFile.from_statement(TOPLEVEL % ('\n' * num_newlines, toplevel_def))) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T302' assert nits[0].severity == Nit.ERROR newlines = Newlines( PythonFile.from_statement(TOPLEVEL % ('\n\n', toplevel_def))) assert len(list(newlines.nits())) == 0
def test_lower_snake_method_names(): p8 = PEP8VariableNames(PythonFile.from_statement(""" def totally_fine(): print("Not in a class body") class DhisRight(object): def clearlyNotThinking(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 5 assert nits[0].severity == Nit.ERROR p8 = PEP8VariableNames(PythonFile.from_statement(""" class DhisRight: def clearlyNotThinking(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 2 assert nits[0].severity == Nit.ERROR # Allow derivations from other modules to be ok. p8 = PEP8VariableNames(PythonFile.from_statement(""" class TestCase(unittest.TestCase): def setUp(self): pass """)) nits = list(p8.nits()) assert len(list(p8.nits())) == 0 p8 = PEP8VariableNames(PythonFile.from_statement(""" def clearlyNotThinking(): print("Not in a class body") class DhisRight(object): def totally_fine(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T002' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def check_file(self, filename): """Process python file looking for indications of problems. :param filename: (str) Python source filename :return: (bool) flag indicating failure """ try: python_file = PythonFile.parse(filename) except SyntaxError as e: print('{filename}:SyntaxError: {error}'.format(filename=filename, error=e)) return True # If the user specifies an invalid severity use comment severity = Nit.SEVERITY.get(self.options.severity, Nit.COMMENT) should_fail = False fail_threshold = Nit.WARNING if self.options.strict else Nit.ERROR for i, nit in enumerate(self.get_nits(python_file)): if i == 0: print( ) # add an extra newline to clean up the output only if we have nits if nit.severity >= severity: print('{nit}\n'.format(nit=nit)) should_fail |= (nit.severity >= fail_threshold) return should_fail
def check_file(self, filename): """Process python file looking for indications of problems. :param filename: (str) Python source filename :return: (bool) flag indicating failure """ try: python_file = PythonFile.parse(filename) except SyntaxError as e: print('{filename}:SyntaxError: {error}'.format(filename=filename, error=e)) return True # If the user specifies an invalid severity use comment. severity = Nit.SEVERITY.get(self.options.severity, Nit.COMMENT) should_fail = False fail_threshold = Nit.WARNING if self.options.strict else Nit.ERROR for i, nit in enumerate(self.get_nits(python_file)): if i == 0: print() # Add an extra newline to clean up the output only if we have nits. if nit.severity >= severity: print('{nit}\n'.format(nit=nit)) should_fail |= (nit.severity >= fail_threshold) return should_fail
def test_import_lexical_order(): io = ImportOrder(PythonFile.from_statement(""" from twitter.common.dirutil import safe_rmtree, safe_mkdtemp """)) nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == 'T401' assert nits[0].severity == Nit.ERROR
def test_import_wildcard(): io = ImportOrder(PythonFile.from_statement(""" from twitter.common.dirutil import * """)) nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == 'T400' assert nits[0].severity == Nit.ERROR
def test_print_statement(): ps = PrintStatements(PythonFile.from_statement(""" print["I do what I want"] """)) nits = list(ps.nits()) assert len(nits) == 1 assert nits[0].code == 'T607' assert nits[0].severity == Nit.ERROR
def test_multiple_imports_error(): io = ImportOrder(PythonFile(stitch_chunks(0, ImportType.STDLIB, ImportType.TWITTER))) import_chunks = list(io.iter_import_chunks()) assert len(import_chunks) == 1 module_types, chunk_errors = io.classify_imports(import_chunks[0]) assert len(chunk_errors) == 1 assert chunk_errors[0].code == 'T405' assert chunk_errors[0].severity == Nit.ERROR assert set(module_types) == set([ImportType.STDLIB, ImportType.TWITTER]) io = ImportOrder(PythonFile('import io, pkg_resources')) import_chunks = list(io.iter_import_chunks()) assert len(import_chunks) == 1 module_types, chunk_errors = io.classify_imports(import_chunks[0]) assert len(chunk_errors) == 3 assert set(chunk_error.code for chunk_error in chunk_errors) == set(['T403', 'T405', 'T402']) assert set(module_types) == set([ImportType.STDLIB, ImportType.THIRD_PARTY])
def test_classify_import(): for import_type, chunk in IMPORT_CHUNKS.items(): io = ImportOrder(PythonFile(chunk)) import_chunks = list(io.iter_import_chunks()) assert len(import_chunks) == 1 module_types, chunk_errors = io.classify_imports(import_chunks[0]) assert len(module_types) == 1 assert module_types.pop() == import_type assert chunk_errors == []
def test_print_statement(): ps = PrintStatements( PythonFile.from_statement(""" print["I do what I want"] """)) nits = list(ps.nits()) assert len(nits) == 1 assert nits[0].code == 'T607' assert nits[0].severity == Nit.ERROR
def test_continuation_with_exception(): tw = TrailingWhitespace(PythonFile.from_statement(""" test_string_001 = (" " " ") """)) nits = list(tw.nits()) assert len(nits) == 1 assert nits[0].code == 'T200' assert nits[0].severity == Nit.ERROR
def test_class_names(): p8 = PEP8VariableNames(PythonFile.from_statement(""" class dhis_not_right(object): pass """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T000' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_print_override(): ps = PrintStatements(PythonFile.from_statement(""" from __future__ import print_function print("I do what I want") class Foo(object): def print(self): "I can do this because it's not a reserved word." """)) assert len(list(ps.nits())) == 0
def test_classdefs(): newlines = Newlines(PythonFile.from_statement(GOOD_CLASS_DEF_1)) assert len(list(newlines.nits())) == 0 newlines = Newlines(PythonFile.from_statement(GOOD_CLASS_DEF_2)) assert len(list(newlines.nits())) == 0 newlines = Newlines(PythonFile.from_statement(BAD_CLASS_DEF_1)) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T301' assert nits[0]._line_number == 4 assert nits[0].severity == Nit.ERROR newlines = Newlines(PythonFile.from_statement(BAD_CLASS_DEF_2)) nits = list(newlines.nits()) assert len(nits) == 1 assert nits[0].code == 'T301' assert nits[0]._line_number == 7 assert nits[0].severity == Nit.ERROR
def test_print_override(): ps = PrintStatements( PythonFile.from_statement(""" from __future__ import print_function print("I do what I want") class Foo(object): def print(self): "I can do this because it's not a reserved word." """)) assert len(list(ps.nits())) == 0
def test_class_names(): p8 = PEP8VariableNames( PythonFile.from_statement(""" class dhis_not_right(object): pass """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T000' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_class_globals(): p8 = PEP8VariableNames(PythonFile.from_statement(""" class DhisRight(object): RIGHT = 123 notRight = 321 """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T001' assert nits[0]._line_number == 3 assert nits[0].severity == Nit.ERROR
def test_class_globals(): p8 = PEP8VariableNames( PythonFile.from_statement(""" class DhisRight(object): RIGHT = 123 notRight = 321 """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T001' assert nits[0]._line_number == 3 assert nits[0].severity == Nit.ERROR
def test_import_lexical_order(): io = ImportOrder( PythonFile.from_statement( """ from twitter.common.dirutil import safe_rmtree, safe_mkdtemp """ ) ) nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == "T401" assert nits[0].severity == Nit.ERROR
def test_import_wildcard(): io = ImportOrder( PythonFile.from_statement( """ from twitter.common.dirutil import * """ ) ) nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == "T400" assert nits[0].severity == Nit.ERROR
def test_builtin_overrides(): p8 = PEP8VariableNames(PythonFile.from_statement(""" def range(): print("Not in a class body") class DhisRight(object): def any(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T801' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_trailing_slash(): tw = TrailingWhitespace(PythonFile.from_statement(""" foo = \\ 123 bar = \"\"\" bin/bash foo \\ bar \\ baz \"\"\" """)) nits = list(tw.nits()) assert len(nits) == 1 assert nits[0].code == 'T201' assert nits[0].severity == Nit.ERROR assert nits[0]._line_number == 1
def test_pairwise_classify(): for first, second in PAIRS: io = ImportOrder(PythonFile(stitch_chunks(1, first, second))) import_chunks = list(io.iter_import_chunks()) assert len(import_chunks) == 2 module_types, chunk_errors = io.classify_imports(import_chunks[0]) assert len(module_types) == 1 assert len(chunk_errors) == 0 assert module_types.pop() == first module_types, chunk_errors = io.classify_imports(import_chunks[1]) assert len(module_types) == 1 assert len(chunk_errors) == 0 assert module_types.pop() == second for second, first in PAIRS: io = ImportOrder(PythonFile(stitch_chunks(1, first, second))) import_chunks = list(io.iter_import_chunks()) assert len(import_chunks) == 2 nits = list(io.nits()) assert len(nits) == 1 assert nits[0].code == 'T406' assert nits[0].severity == Nit.ERROR
def test_style_error(self): """Test error with actual AST node. Verify that when we fetch a node form AST and create an error we get the same result as generating the error manually. """ plugin = MinimalCheckstylePlugin({}, PythonFile.from_statement(FILE_TEXT)) import_from = None for node in ast.walk(self._python_file_for_testing().tree): if isinstance(node, ast.ImportFrom): import_from = node ast_error = plugin.error('B380', "I don't like your from import!", import_from) error = plugin.error('B380', "I don't like your from import!", 2) self.assertEqual(str(ast_error), str(error))
def test_builtin_overrides(): p8 = PEP8VariableNames( PythonFile.from_statement(""" def range(): print("Not in a class body") class DhisRight(object): def any(self): print("In a class body") """)) nits = list(p8.nits()) assert len(nits) == 1 assert nits[0].code == 'T801' assert nits[0]._line_number == 1 assert nits[0].severity == Nit.ERROR
def test_exception_map(test_input, results): tw = TrailingWhitespace(PythonFile.from_statement(""" test_string_001 = "" test_string_002 = " " test_string_003 = \"\"\" foo \"\"\" test_string_006 = (" " " ") class Foo(object): pass # comment 010 test_string_011 = '' # comment 012 # comment 013 """)) assert len(list(tw.nits())) == 0 assert bool(tw.has_exception(*test_input)) == results
def test_python_file(): """Pytest Fixture to create a test python file from statement""" return PythonFile(test_statement(), 'keeper.py')
def get_import_chunk_types(import_type): chunks = list(ImportOrder(PythonFile(IMPORT_CHUNKS[import_type])).iter_import_chunks()) assert len(chunks) == 1 return tuple(map(type, chunks[0]))
def test_python_file_exceeds_index(test_statement): """Test that we get an Index error when we exceed the line number""" test_python_file = PythonFile(test_statement, 'keeper.py') with pytest.raises(IndexError): test_python_file[len(test_statement.splitlines()) + 1]
def test_print_function(): ps = PrintStatements( PythonFile.from_statement(""" print("I do what I want") """)) assert len(list(ps.nits())) == 0
def get_plugin(self, file_content, **options): python_file = PythonFile.from_statement(file_content) full_options = copy.copy(options) full_options['skip'] = False options_object = create_options({'foo': full_options}).for_scope('foo') return self.plugin_type(options_object, python_file)
def init_file(self, filename, lines, expected, line_offset): super(PantsReporter, self).init_file(filename, lines, expected, line_offset) self._python_file = PythonFile.parse(filename) self._twitter_errors = []
# coding=utf-8 # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import (absolute_import, division, generators, nested_scopes, print_function, unicode_literals, with_statement) from pants.backend.python.tasks.checkstyle.class_factoring import ClassFactoring from pants.backend.python.tasks.checkstyle.common import Nit, PythonFile BAD_CLASS = PythonFile.from_statement(""" class Distiller(object): CONSTANT = "foo" def foo(self, value): return os.path.join(Distiller.CONSTANT, value) """) def test_class_factoring(): plugin = ClassFactoring(BAD_CLASS) nits = list(plugin.nits()) assert len(nits) == 1 assert nits[0].code == 'T800' assert nits[0].severity == Nit.WARNING
def test_print_function(): ps = PrintStatements(PythonFile.from_statement(""" print("I do what I want") """)) assert len(list(ps.nits())) == 0
def nits_from(clause): return list(ExceptStatements(PythonFile.from_statement(EXCEPT_TEMPLATE % clause)).nits())
def _python_file_for_testing(self): """Pytest Fixture to create a test python file from statement.""" return PythonFile(self._statement_for_testing(), 'keeper.py')
def exemplar_fail(code, severity, statement): nits = list(FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 1 assert nits[0].code == code assert nits[0].severity == severity return nits[0]
def exemplar_pass(statement): nits = list(FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 0
# coding=utf-8 # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). # Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import (absolute_import, division, generators, nested_scopes, print_function, unicode_literals, with_statement) from pants.backend.python.tasks.checkstyle.common import Nit, PythonFile from pants.backend.python.tasks.checkstyle.future_compatibility import FutureCompatibility BAD_CLASS = PythonFile.from_statement(""" class Distiller(object): CONSTANT = "foo" def foo(self, value): return os.path.join(Distiller.CONSTANT, value) """) def exemplar_fail(code, severity, statement): nits = list(FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 1 assert nits[0].code == code assert nits[0].severity == severity return nits[0] def exemplar_pass(statement): nits = list(FutureCompatibility(PythonFile.from_statement(statement)).nits()) assert len(nits) == 0
def test_off_by_one_enumeration(test_statement): """Test that enumerate is offset by one""" python_file = PythonFile(test_statement, 'keeper.py') assert list(python_file.enumerate()) == list(enumerate(test_statement.splitlines(), 1))