from pylint.checkers import BaseChecker from pylint.interfaces import IAstroidChecker from astroid.exceptions import InferenceError def register(linter): linter.register_checker(PatchChecker(linter)) linter.register_checker(MocksUseSpecArg(linter)) class PatchChecker(BaseChecker): __implements__ = (IAstroidChecker,) name = 'patching-banned' msgs = { 'C9999': ('Use of mock.patch is not allowed', 'patch-call', 'Use of mock.patch not allowed') } patch_pytype = 'mock.mock._patch' def visit_call(self, node): try: for inferred_type in node.infer(): if inferred_type.pytype() == self.patch_pytype: self.add_message('patch-call', node=node) except InferenceError: # It's ok if we can't work out what type the function # call is. pass class MocksUseSpecArg(BaseChecker): __implements__ = (IAstroidChecker,) name = 'mocks-use-spec' msgs = { 'C9998': ('mock.Mock() must provide "spec=" argument', 'mock-missing-spec', 'mock.Mock() must provide "spec=" argument') } mock_pytype = 'mock.mock.Mock' required_kwarg = 'spec' def visit_call(self, node): try: for inferred_type in node.infer(): if inferred_type.pytype() == self.mock_pytype: self._verify_spec_arg_provided(node) except InferenceError: pass def _verify_spec_arg_provided(self, node): if not node.keywords: self.add_message('mock-missing-spec', node=node) return kwargs = [kwarg.arg for kwarg in node.keywords] if self.required_kwarg not in kwargs: self.add_message('mock-missing-spec', node=node)