Skip to content

Instantly share code, notes, and snippets.

@jirikuncar
Last active September 28, 2016 21:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jirikuncar/bbebbe1dcc9f3093caad2af7681433c1 to your computer and use it in GitHub Desktop.
Save jirikuncar/bbebbe1dcc9f3093caad2af7681433c1 to your computer and use it in GitHub Desktop.
PyLint checker for number of calls inside try blocks.

Download try_calls.py and install pylint :

$ pip install pylint

Run pylint with an additional plugin on a bad.py file :

$ pylint --load-plugins=try_calls bad.py

In case you try_calls.py is not recognized add it to PYTHONPATH.

# fail
try:
int("5")
int("a")
except ValueError:
pass
# fail
x = 0
try:
x = int("1")
x += int("2")
finally: # check no except block
x += 1
# pass ?
try:
range(
int('5'),
int('9')
) # multi-line expression with mulptiple functions
except:
pass
"""Checker for number of calls inside try block."""
import six
import astroid
from pylint.checkers import BaseChecker, utils
from pylint.interfaces import IAstroidChecker
def register(linter):
"""Register checkers."""
linter.register_checker(TryCallsChecker(linter))
class TryCallsChecker(BaseChecker):
"""Check number of calls in try blocks.
The message id is `try-calls`.
"""
__implements__ = (IAstroidChecker,)
name = 'try-calls'
MESSAGE_ID = 'try-calls'
msgs = {
'E9999': (
'Too many function calls (%s) inside try block',
MESSAGE_ID,
'Too many function calls inside try block',
),
}
def _visit_try(self, node):
"""Called for every try block in the source code."""
if not self.linter.is_message_enabled(self.MESSAGE_ID, line=node.fromlineno):
return
def has_call(node):
if isinstance(node, astroid.Call):
return node.func.name
for child in node.get_children():
first_call = has_call(child)
if first_call:
return first_call
def get_calls():
for tree in node.body:
call = has_call(tree)
if call is not None:
yield call
calls = list(get_calls())
if len(calls) > 1:
self.add_message(self.MESSAGE_ID, args=(', '.join(calls), ), node=node)
@utils.check_messages(MESSAGE_ID)
def visit_tryexcept(self, node):
"""Check try/except block."""
self._visit_try(node)
@utils.check_messages(MESSAGE_ID)
def visit_tryfinally(self, node):
"""Check try/finally block."""
self._visit_try(node)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment