broad_try_clause.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # Copyright (c) 2019-2020 Claudiu Popa <pcmanticore@gmail.com>
  2. # Copyright (c) 2019-2020 Tyler Thieding <tyler@thieding.com>
  3. # Copyright (c) 2020 hippo91 <guillaume.peillex@gmail.com>
  4. # Copyright (c) 2020 Anthony Sottile <asottile@umich.edu>
  5. # Copyright (c) 2021 Pierre Sassoulas <pierre.sassoulas@gmail.com>
  6. # Copyright (c) 2021 Daniël van Noord <13665637+DanielNoord@users.noreply.github.com>
  7. # Copyright (c) 2021 Marc Mueller <30130371+cdce8p@users.noreply.github.com>
  8. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  9. # For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
  10. """Looks for try/except statements with too much code in the try clause."""
  11. from astroid import nodes
  12. from pylint import checkers, interfaces
  13. class BroadTryClauseChecker(checkers.BaseChecker):
  14. """Checks for try clauses with too many lines.
  15. According to PEP 8, ``try`` clauses shall contain the absolute minimum
  16. amount of code. This checker enforces a maximum number of statements within
  17. ``try`` clauses.
  18. """
  19. __implements__ = interfaces.IAstroidChecker
  20. # configuration section name
  21. name = "broad_try_clause"
  22. msgs = {
  23. "W0717": (
  24. "%s",
  25. "too-many-try-statements",
  26. "Try clause contains too many statements.",
  27. )
  28. }
  29. priority = -2
  30. options = (
  31. (
  32. "max-try-statements",
  33. {
  34. "default": 1,
  35. "type": "int",
  36. "metavar": "<int>",
  37. "help": "Maximum number of statements allowed in a try clause",
  38. },
  39. ),
  40. )
  41. def _count_statements(self, try_node):
  42. statement_count = len(try_node.body)
  43. for body_node in try_node.body:
  44. if isinstance(body_node, (nodes.For, nodes.If, nodes.While, nodes.With)):
  45. statement_count += self._count_statements(body_node)
  46. return statement_count
  47. def visit_tryexcept(self, node: nodes.TryExcept) -> None:
  48. try_clause_statements = self._count_statements(node)
  49. if try_clause_statements > self.config.max_try_statements:
  50. msg = f"try clause contains {try_clause_statements} statements, expected at most {self.config.max_try_statements}"
  51. self.add_message(
  52. "too-many-try-statements", node.lineno, node=node, args=msg
  53. )
  54. def visit_tryfinally(self, node: nodes.TryFinally) -> None:
  55. self.visit_tryexcept(node)
  56. def register(linter):
  57. """Required method to auto register this checker."""
  58. linter.register_checker(BroadTryClauseChecker(linter))