Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

text.py 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. # Copyright (c) 2006-2007, 2010-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  2. # Copyright (c) 2012-2014 Google, Inc.
  3. # Copyright (c) 2014 Brett Cannon <brett@python.org>
  4. # Copyright (c) 2014 Arun Persaud <arun@nubati.net>
  5. # Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com>
  6. # Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
  7. # Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
  8. # Copyright (c) 2016 y2kbugger <y2kbugger@users.noreply.github.com>
  9. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  10. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  11. """Plain text reporters:
  12. :text: the default one grouping messages by module
  13. :colorized: an ANSI colorized text reporter
  14. """
  15. from __future__ import print_function
  16. import os
  17. import warnings
  18. import sys
  19. import six
  20. from pylint.interfaces import IReporter
  21. from pylint.reporters import BaseReporter
  22. from pylint import utils
  23. from pylint.reporters.ureports.text_writer import TextWriter
  24. TITLE_UNDERLINES = ['', '=', '-', '.']
  25. ANSI_PREFIX = '\033['
  26. ANSI_END = 'm'
  27. ANSI_RESET = '\033[0m'
  28. ANSI_STYLES = {
  29. 'reset': "0",
  30. 'bold': "1",
  31. 'italic': "3",
  32. 'underline': "4",
  33. 'blink': "5",
  34. 'inverse': "7",
  35. 'strike': "9",
  36. }
  37. ANSI_COLORS = {
  38. 'reset': "0",
  39. 'black': "30",
  40. 'red': "31",
  41. 'green': "32",
  42. 'yellow': "33",
  43. 'blue': "34",
  44. 'magenta': "35",
  45. 'cyan': "36",
  46. 'white': "37",
  47. }
  48. def _get_ansi_code(color=None, style=None):
  49. """return ansi escape code corresponding to color and style
  50. :type color: str or None
  51. :param color:
  52. the color name (see `ANSI_COLORS` for available values)
  53. or the color number when 256 colors are available
  54. :type style: str or None
  55. :param style:
  56. style string (see `ANSI_COLORS` for available values). To get
  57. several style effects at the same time, use a coma as separator.
  58. :raise KeyError: if an unexistent color or style identifier is given
  59. :rtype: str
  60. :return: the built escape code
  61. """
  62. ansi_code = []
  63. if style:
  64. style_attrs = utils._splitstrip(style)
  65. for effect in style_attrs:
  66. ansi_code.append(ANSI_STYLES[effect])
  67. if color:
  68. if color.isdigit():
  69. ansi_code.extend(['38', '5'])
  70. ansi_code.append(color)
  71. else:
  72. ansi_code.append(ANSI_COLORS[color])
  73. if ansi_code:
  74. return ANSI_PREFIX + ';'.join(ansi_code) + ANSI_END
  75. return ''
  76. def colorize_ansi(msg, color=None, style=None):
  77. """colorize message by wrapping it with ansi escape codes
  78. :type msg: str or unicode
  79. :param msg: the message string to colorize
  80. :type color: str or None
  81. :param color:
  82. the color identifier (see `ANSI_COLORS` for available values)
  83. :type style: str or None
  84. :param style:
  85. style string (see `ANSI_COLORS` for available values). To get
  86. several style effects at the same time, use a coma as separator.
  87. :raise KeyError: if an unexistent color or style identifier is given
  88. :rtype: str or unicode
  89. :return: the ansi escaped string
  90. """
  91. # If both color and style are not defined, then leave the text as is
  92. if color is None and style is None:
  93. return msg
  94. escape_code = _get_ansi_code(color, style)
  95. # If invalid (or unknown) color, don't wrap msg with ansi codes
  96. if escape_code:
  97. return '%s%s%s' % (escape_code, msg, ANSI_RESET)
  98. return msg
  99. class TextReporter(BaseReporter):
  100. """reports messages and layouts in plain text"""
  101. __implements__ = IReporter
  102. name = 'text'
  103. extension = 'txt'
  104. line_format = '{C}:{line:3d},{column:2d}: {msg} ({symbol})'
  105. def __init__(self, output=None):
  106. BaseReporter.__init__(self, output)
  107. self._modules = set()
  108. self._template = None
  109. def on_set_current_module(self, module, filepath):
  110. self._template = six.text_type(self.linter.config.msg_template or self.line_format)
  111. def write_message(self, msg):
  112. """Convenience method to write a formated message with class default template"""
  113. self.writeln(msg.format(self._template))
  114. def handle_message(self, msg):
  115. """manage message of different type and in the context of path"""
  116. if msg.module not in self._modules:
  117. if msg.module:
  118. self.writeln('************* Module %s' % msg.module)
  119. self._modules.add(msg.module)
  120. else:
  121. self.writeln('************* ')
  122. self.write_message(msg)
  123. def _display(self, layout):
  124. """launch layouts display"""
  125. print(file=self.out)
  126. TextWriter().format(layout, self.out)
  127. class ParseableTextReporter(TextReporter):
  128. """a reporter very similar to TextReporter, but display messages in a form
  129. recognized by most text editors :
  130. <filename>:<linenum>:<msg>
  131. """
  132. name = 'parseable'
  133. line_format = '{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}'
  134. def __init__(self, output=None):
  135. warnings.warn('%s output format is deprecated. This is equivalent '
  136. 'to --msg-template=%s' % (self.name, self.line_format),
  137. DeprecationWarning)
  138. TextReporter.__init__(self, output)
  139. class VSTextReporter(ParseableTextReporter):
  140. """Visual studio text reporter"""
  141. name = 'msvs'
  142. line_format = '{path}({line}): [{msg_id}({symbol}){obj}] {msg}'
  143. class ColorizedTextReporter(TextReporter):
  144. """Simple TextReporter that colorizes text output"""
  145. name = 'colorized'
  146. COLOR_MAPPING = {
  147. "I" : ("green", None),
  148. 'C' : (None, "bold"),
  149. 'R' : ("magenta", "bold, italic"),
  150. 'W' : ("blue", None),
  151. 'E' : ("red", "bold"),
  152. 'F' : ("red", "bold, underline"),
  153. 'S' : ("yellow", "inverse"), # S stands for module Separator
  154. }
  155. def __init__(self, output=None, color_mapping=None):
  156. TextReporter.__init__(self, output)
  157. self.color_mapping = color_mapping or \
  158. dict(ColorizedTextReporter.COLOR_MAPPING)
  159. ansi_terms = ['xterm-16color', 'xterm-256color']
  160. if os.environ.get('TERM') not in ansi_terms:
  161. if sys.platform == 'win32':
  162. import colorama
  163. self.out = colorama.AnsiToWin32(self.out)
  164. def _get_decoration(self, msg_id):
  165. """Returns the tuple color, style associated with msg_id as defined
  166. in self.color_mapping
  167. """
  168. try:
  169. return self.color_mapping[msg_id[0]]
  170. except KeyError:
  171. return None, None
  172. def handle_message(self, msg):
  173. """manage message of different types, and colorize output
  174. using ansi escape codes
  175. """
  176. if msg.module not in self._modules:
  177. color, style = self._get_decoration('S')
  178. if msg.module:
  179. modsep = colorize_ansi('************* Module %s' % msg.module,
  180. color, style)
  181. else:
  182. modsep = colorize_ansi('************* %s' % msg.module,
  183. color, style)
  184. self.writeln(modsep)
  185. self._modules.add(msg.module)
  186. color, style = self._get_decoration(msg.C)
  187. msg = msg._replace(
  188. **{attr: colorize_ansi(getattr(msg, attr), color, style)
  189. for attr in ('msg', 'symbol', 'category', 'C')})
  190. self.write_message(msg)
  191. def register(linter):
  192. """Register the reporter classes with the linter."""
  193. linter.register_reporter(TextReporter)
  194. linter.register_reporter(ParseableTextReporter)
  195. linter.register_reporter(VSTextReporter)
  196. linter.register_reporter(ColorizedTextReporter)