messages.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. """
  2. Provide the class Message and its subclasses.
  3. """
  4. class Message:
  5. message = ''
  6. message_args = ()
  7. def __init__(self, filename, loc):
  8. self.filename = filename
  9. self.lineno = loc.lineno
  10. self.col = loc.col_offset
  11. def __str__(self):
  12. return '{}:{}:{}: {}'.format(self.filename, self.lineno, self.col+1,
  13. self.message % self.message_args)
  14. class UnusedImport(Message):
  15. message = '%r imported but unused'
  16. def __init__(self, filename, loc, name):
  17. Message.__init__(self, filename, loc)
  18. self.message_args = (name,)
  19. class RedefinedWhileUnused(Message):
  20. message = 'redefinition of unused %r from line %r'
  21. def __init__(self, filename, loc, name, orig_loc):
  22. Message.__init__(self, filename, loc)
  23. self.message_args = (name, orig_loc.lineno)
  24. class ImportShadowedByLoopVar(Message):
  25. message = 'import %r from line %r shadowed by loop variable'
  26. def __init__(self, filename, loc, name, orig_loc):
  27. Message.__init__(self, filename, loc)
  28. self.message_args = (name, orig_loc.lineno)
  29. class ImportStarNotPermitted(Message):
  30. message = "'from %s import *' only allowed at module level"
  31. def __init__(self, filename, loc, modname):
  32. Message.__init__(self, filename, loc)
  33. self.message_args = (modname,)
  34. class ImportStarUsed(Message):
  35. message = "'from %s import *' used; unable to detect undefined names"
  36. def __init__(self, filename, loc, modname):
  37. Message.__init__(self, filename, loc)
  38. self.message_args = (modname,)
  39. class ImportStarUsage(Message):
  40. message = "%r may be undefined, or defined from star imports: %s"
  41. def __init__(self, filename, loc, name, from_list):
  42. Message.__init__(self, filename, loc)
  43. self.message_args = (name, from_list)
  44. class UndefinedName(Message):
  45. message = 'undefined name %r'
  46. def __init__(self, filename, loc, name):
  47. Message.__init__(self, filename, loc)
  48. self.message_args = (name,)
  49. class DoctestSyntaxError(Message):
  50. message = 'syntax error in doctest'
  51. def __init__(self, filename, loc, position=None):
  52. Message.__init__(self, filename, loc)
  53. if position:
  54. (self.lineno, self.col) = position
  55. self.message_args = ()
  56. class UndefinedExport(Message):
  57. message = 'undefined name %r in __all__'
  58. def __init__(self, filename, loc, name):
  59. Message.__init__(self, filename, loc)
  60. self.message_args = (name,)
  61. class UndefinedLocal(Message):
  62. message = 'local variable %r {0} referenced before assignment'
  63. default = 'defined in enclosing scope on line %r'
  64. builtin = 'defined as a builtin'
  65. def __init__(self, filename, loc, name, orig_loc):
  66. Message.__init__(self, filename, loc)
  67. if orig_loc is None:
  68. self.message = self.message.format(self.builtin)
  69. self.message_args = name
  70. else:
  71. self.message = self.message.format(self.default)
  72. self.message_args = (name, orig_loc.lineno)
  73. class DuplicateArgument(Message):
  74. message = 'duplicate argument %r in function definition'
  75. def __init__(self, filename, loc, name):
  76. Message.__init__(self, filename, loc)
  77. self.message_args = (name,)
  78. class MultiValueRepeatedKeyLiteral(Message):
  79. message = 'dictionary key %r repeated with different values'
  80. def __init__(self, filename, loc, key):
  81. Message.__init__(self, filename, loc)
  82. self.message_args = (key,)
  83. class MultiValueRepeatedKeyVariable(Message):
  84. message = 'dictionary key variable %s repeated with different values'
  85. def __init__(self, filename, loc, key):
  86. Message.__init__(self, filename, loc)
  87. self.message_args = (key,)
  88. class LateFutureImport(Message):
  89. message = 'from __future__ imports must occur at the beginning of the file'
  90. def __init__(self, filename, loc):
  91. Message.__init__(self, filename, loc)
  92. self.message_args = ()
  93. class FutureFeatureNotDefined(Message):
  94. """An undefined __future__ feature name was imported."""
  95. message = 'future feature %s is not defined'
  96. def __init__(self, filename, loc, name):
  97. Message.__init__(self, filename, loc)
  98. self.message_args = (name,)
  99. class UnusedVariable(Message):
  100. """
  101. Indicates that a variable has been explicitly assigned to but not actually
  102. used.
  103. """
  104. message = 'local variable %r is assigned to but never used'
  105. def __init__(self, filename, loc, names):
  106. Message.__init__(self, filename, loc)
  107. self.message_args = (names,)
  108. class ReturnOutsideFunction(Message):
  109. """
  110. Indicates a return statement outside of a function/method.
  111. """
  112. message = '\'return\' outside function'
  113. class YieldOutsideFunction(Message):
  114. """
  115. Indicates a yield or yield from statement outside of a function/method.
  116. """
  117. message = '\'yield\' outside function'
  118. # For whatever reason, Python gives different error messages for these two. We
  119. # match the Python error message exactly.
  120. class ContinueOutsideLoop(Message):
  121. """
  122. Indicates a continue statement outside of a while or for loop.
  123. """
  124. message = '\'continue\' not properly in loop'
  125. class BreakOutsideLoop(Message):
  126. """
  127. Indicates a break statement outside of a while or for loop.
  128. """
  129. message = '\'break\' outside loop'
  130. class ContinueInFinally(Message):
  131. """
  132. Indicates a continue statement in a finally block in a while or for loop.
  133. """
  134. message = '\'continue\' not supported inside \'finally\' clause'
  135. class DefaultExceptNotLast(Message):
  136. """
  137. Indicates an except: block as not the last exception handler.
  138. """
  139. message = 'default \'except:\' must be last'
  140. class TwoStarredExpressions(Message):
  141. """
  142. Two or more starred expressions in an assignment (a, *b, *c = d).
  143. """
  144. message = 'two starred expressions in assignment'
  145. class TooManyExpressionsInStarredAssignment(Message):
  146. """
  147. Too many expressions in an assignment with star-unpacking
  148. """
  149. message = 'too many expressions in star-unpacking assignment'
  150. class IfTuple(Message):
  151. """
  152. Conditional test is a non-empty tuple literal, which are always True.
  153. """
  154. message = '\'if tuple literal\' is always true, perhaps remove accidental comma?'
  155. class AssertTuple(Message):
  156. """
  157. Assertion test is a non-empty tuple literal, which are always True.
  158. """
  159. message = 'assertion is always true, perhaps remove parentheses?'
  160. class ForwardAnnotationSyntaxError(Message):
  161. message = 'syntax error in forward annotation %r'
  162. def __init__(self, filename, loc, annotation):
  163. Message.__init__(self, filename, loc)
  164. self.message_args = (annotation,)
  165. class CommentAnnotationSyntaxError(Message):
  166. message = 'syntax error in type comment %r'
  167. def __init__(self, filename, loc, annotation):
  168. Message.__init__(self, filename, loc)
  169. self.message_args = (annotation,)
  170. class RaiseNotImplemented(Message):
  171. message = "'raise NotImplemented' should be 'raise NotImplementedError'"
  172. class InvalidPrintSyntax(Message):
  173. message = 'use of >> is invalid with print function'
  174. class IsLiteral(Message):
  175. message = 'use ==/!= to compare constant literals (str, bytes, int, float, tuple)'
  176. class FStringMissingPlaceholders(Message):
  177. message = 'f-string is missing placeholders'
  178. class StringDotFormatExtraPositionalArguments(Message):
  179. message = "'...'.format(...) has unused arguments at position(s): %s"
  180. def __init__(self, filename, loc, extra_positions):
  181. Message.__init__(self, filename, loc)
  182. self.message_args = (extra_positions,)
  183. class StringDotFormatExtraNamedArguments(Message):
  184. message = "'...'.format(...) has unused named argument(s): %s"
  185. def __init__(self, filename, loc, extra_keywords):
  186. Message.__init__(self, filename, loc)
  187. self.message_args = (extra_keywords,)
  188. class StringDotFormatMissingArgument(Message):
  189. message = "'...'.format(...) is missing argument(s) for placeholder(s): %s"
  190. def __init__(self, filename, loc, missing_arguments):
  191. Message.__init__(self, filename, loc)
  192. self.message_args = (missing_arguments,)
  193. class StringDotFormatMixingAutomatic(Message):
  194. message = "'...'.format(...) mixes automatic and manual numbering"
  195. class StringDotFormatInvalidFormat(Message):
  196. message = "'...'.format(...) has invalid format string: %s"
  197. def __init__(self, filename, loc, error):
  198. Message.__init__(self, filename, loc)
  199. self.message_args = (error,)
  200. class PercentFormatInvalidFormat(Message):
  201. message = "'...' %% ... has invalid format string: %s"
  202. def __init__(self, filename, loc, error):
  203. Message.__init__(self, filename, loc)
  204. self.message_args = (error,)
  205. class PercentFormatMixedPositionalAndNamed(Message):
  206. message = "'...' %% ... has mixed positional and named placeholders"
  207. class PercentFormatUnsupportedFormatCharacter(Message):
  208. message = "'...' %% ... has unsupported format character %r"
  209. def __init__(self, filename, loc, c):
  210. Message.__init__(self, filename, loc)
  211. self.message_args = (c,)
  212. class PercentFormatPositionalCountMismatch(Message):
  213. message = "'...' %% ... has %d placeholder(s) but %d substitution(s)"
  214. def __init__(self, filename, loc, n_placeholders, n_substitutions):
  215. Message.__init__(self, filename, loc)
  216. self.message_args = (n_placeholders, n_substitutions)
  217. class PercentFormatExtraNamedArguments(Message):
  218. message = "'...' %% ... has unused named argument(s): %s"
  219. def __init__(self, filename, loc, extra_keywords):
  220. Message.__init__(self, filename, loc)
  221. self.message_args = (extra_keywords,)
  222. class PercentFormatMissingArgument(Message):
  223. message = "'...' %% ... is missing argument(s) for placeholder(s): %s"
  224. def __init__(self, filename, loc, missing_arguments):
  225. Message.__init__(self, filename, loc)
  226. self.message_args = (missing_arguments,)
  227. class PercentFormatExpectedMapping(Message):
  228. message = "'...' %% ... expected mapping but got sequence"
  229. class PercentFormatExpectedSequence(Message):
  230. message = "'...' %% ... expected sequence but got mapping"
  231. class PercentFormatStarRequiresSequence(Message):
  232. message = "'...' %% ... `*` specifier requires sequence"