default.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """Default formatting class for Flake8."""
  2. from typing import Optional
  3. from typing import Set
  4. from flake8.formatting import base
  5. from flake8.violation import Violation
  6. COLORS = {
  7. "bold": "\033[1m",
  8. "black": "\033[30m",
  9. "red": "\033[31m",
  10. "green": "\033[32m",
  11. "yellow": "\033[33m",
  12. "blue": "\033[34m",
  13. "magenta": "\033[35m",
  14. "cyan": "\033[36m",
  15. "white": "\033[37m",
  16. "reset": "\033[m",
  17. }
  18. COLORS_OFF = {k: "" for k in COLORS}
  19. class SimpleFormatter(base.BaseFormatter):
  20. """Simple abstraction for Default and Pylint formatter commonality.
  21. Sub-classes of this need to define an ``error_format`` attribute in order
  22. to succeed. The ``format`` method relies on that attribute and expects the
  23. ``error_format`` string to use the old-style formatting strings with named
  24. parameters:
  25. * code
  26. * text
  27. * path
  28. * row
  29. * col
  30. """
  31. error_format: str
  32. def format(self, error: "Violation") -> Optional[str]:
  33. """Format and write error out.
  34. If an output filename is specified, write formatted errors to that
  35. file. Otherwise, print the formatted error to standard out.
  36. """
  37. return self.error_format % {
  38. "code": error.code,
  39. "text": error.text,
  40. "path": error.filename,
  41. "row": error.line_number,
  42. "col": error.column_number,
  43. **(COLORS if self.color else COLORS_OFF),
  44. }
  45. class Default(SimpleFormatter):
  46. """Default formatter for Flake8.
  47. This also handles backwards compatibility for people specifying a custom
  48. format string.
  49. """
  50. error_format = (
  51. "%(bold)s%(path)s%(reset)s"
  52. "%(cyan)s:%(reset)s%(row)d%(cyan)s:%(reset)s%(col)d%(cyan)s:%(reset)s "
  53. "%(bold)s%(red)s%(code)s%(reset)s %(text)s"
  54. )
  55. def after_init(self) -> None:
  56. """Check for a custom format string."""
  57. if self.options.format.lower() != "default":
  58. self.error_format = self.options.format
  59. class Pylint(SimpleFormatter):
  60. """Pylint formatter for Flake8."""
  61. error_format = "%(path)s:%(row)d: [%(code)s] %(text)s"
  62. class FilenameOnly(SimpleFormatter):
  63. """Only print filenames, e.g., flake8 -q."""
  64. error_format = "%(path)s"
  65. def after_init(self) -> None:
  66. """Initialize our set of filenames."""
  67. self.filenames_already_printed: Set[str] = set()
  68. def show_source(self, error: "Violation") -> Optional[str]:
  69. """Do not include the source code."""
  70. def format(self, error: "Violation") -> Optional[str]:
  71. """Ensure we only print each error once."""
  72. if error.filename not in self.filenames_already_printed:
  73. self.filenames_already_printed.add(error.filename)
  74. return super().format(error)
  75. else:
  76. return None
  77. class Nothing(base.BaseFormatter):
  78. """Print absolutely nothing."""
  79. def format(self, error: "Violation") -> Optional[str]:
  80. """Do nothing."""
  81. def show_source(self, error: "Violation") -> Optional[str]:
  82. """Do not print the source."""