Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" py.test plugin for checking files with pylama. """ 

2from __future__ import absolute_import 

3 

4from os import path as op 

5 

6import py # noqa 

7import pytest 

8 

9 

10HISTKEY = "pylama/mtimes" 

11 

12 

13def pytest_load_initial_conftests(early_config, parser, args): 

14 # Marks have to be registered before usage 

15 # to not fail with --strict command line argument 

16 early_config.addinivalue_line( 

17 'markers', 

18 'pycodestyle: Mark test as using pylama code audit tool.') 

19 

20 

21def pytest_addoption(parser): 

22 group = parser.getgroup("general") 

23 group.addoption( 

24 '--pylama', action='store_true', 

25 help="perform some pylama code checks on .py files") 

26 

27 

28def pytest_sessionstart(session): 

29 config = session.config 

30 if config.option.pylama and getattr(config, 'cache', None): 

31 config._pylamamtimes = config.cache.get(HISTKEY, {}) 

32 

33 

34def pytest_sessionfinish(session): 

35 config = session.config 

36 if hasattr(config, "_pylamamtimes"): 

37 config.cache.set(HISTKEY, config._pylamamtimes) 

38 

39 

40def pytest_collect_file(path, parent): 

41 config = parent.config 

42 if config.option.pylama and path.ext == '.py': 

43 return PylamaItem(path, parent) 

44 

45 

46class PylamaError(Exception): 

47 """ indicates an error during pylama checks. """ 

48 

49 

50class PylamaItem(pytest.Item, pytest.File): 

51 

52 def __init__(self, path, parent): 

53 super(PylamaItem, self).__init__(path, parent) 

54 self.add_marker("pycodestyle") 

55 self.cache = None 

56 self._pylamamtimes = None 

57 

58 def setup(self): 

59 if not getattr(self.config, 'cache', None): 

60 return False 

61 

62 self.cache = True 

63 self._pylamamtimes = self.fspath.mtime() 

64 pylamamtimes = self.config._pylamamtimes 

65 old = pylamamtimes.get(str(self.fspath), 0) 

66 if old == self._pylamamtimes: 

67 pytest.skip("file(s) previously passed Pylama checks") 

68 

69 def runtest(self): 

70 errors = check_file(self.fspath) 

71 if errors: 

72 pattern = "%(filename)s:%(lnum)s:%(col)s: %(text)s" 

73 out = "\n".join([pattern % e._info for e in errors]) 

74 raise PylamaError(out) 

75 

76 # update mtime only if test passed 

77 # otherwise failures would not be re-run next time 

78 if self.cache: 

79 self.config._pylamamtimes[str(self.fspath)] = self._pylamamtimes 

80 

81 def repr_failure(self, excinfo): 

82 if excinfo.errisinstance(PylamaError): 

83 return excinfo.value.args[0] 

84 return super(PylamaItem, self).repr_failure(excinfo) 

85 

86 

87def check_file(path): 

88 from pylama.main import parse_options, process_paths 

89 from pylama.config import CURDIR 

90 

91 options = parse_options() 

92 path = op.relpath(str(path), CURDIR) 

93 return process_paths(options, candidates=[path], error=False) 

94 

95# pylama:ignore=D,E1002,W0212,F0001