eric6/Plugins/CheckerPlugins/CodeStyleChecker/translations.py

changeset 8168
bdb0258faf42
parent 8166
bd5cd5858503
child 8169
139bd30c52c2
equal deleted inserted replaced
8167:cdc1b6692766 8168:bdb0258faf42
4 # 4 #
5 5
6 """ 6 """
7 Module implementing message translations for the code style plugin messages. 7 Module implementing message translations for the code style plugin messages.
8 """ 8 """
9
10 import re
9 11
10 from PyQt5.QtCore import QCoreApplication 12 from PyQt5.QtCore import QCoreApplication
11 13
12 from .Annotations.translations import ( 14 from .Annotations.translations import (
13 _annotationsMessages, _annotationsMessagesSampleArgs 15 _annotationsMessages, _annotationsMessagesSampleArgs
25 from .PathLib.translations import _pathlibMessages 27 from .PathLib.translations import _pathlibMessages
26 from .Security.translations import ( 28 from .Security.translations import (
27 _securityMessages, _securityMessagesSampleArgs 29 _securityMessages, _securityMessagesSampleArgs
28 ) 30 )
29 31
30 _messages = { 32 ##################################################################
31 ################################################################## 33 ## pycodestyle error messages
32 ## pycodestyle messages 34 ##################################################################
33 ################################################################## 35
36 _pycodestyleErrorMessages = {
34 "E101": QCoreApplication.translate( 37 "E101": QCoreApplication.translate(
35 "pycodestyle", 38 "pycodestyle",
36 "indentation contains mixed spaces and tabs"), 39 "indentation contains mixed spaces and tabs"),
37 "E111": QCoreApplication.translate( 40 "E111": QCoreApplication.translate(
38 "pycodestyle", 41 "pycodestyle",
87 "pycodestyle", 90 "pycodestyle",
88 "continuation line unaligned for hanging indent"), 91 "continuation line unaligned for hanging indent"),
89 "E133": QCoreApplication.translate( 92 "E133": QCoreApplication.translate(
90 "pycodestyle", 93 "pycodestyle",
91 "closing bracket is missing indentation"), 94 "closing bracket is missing indentation"),
92 "W191": QCoreApplication.translate(
93 "pycodestyle",
94 "indentation contains tabs"),
95 "E201": QCoreApplication.translate( 95 "E201": QCoreApplication.translate(
96 "pycodestyle", 96 "pycodestyle",
97 "whitespace after '{0}'"), 97 "whitespace after '{0}'"),
98 "E202": QCoreApplication.translate( 98 "E202": QCoreApplication.translate(
99 "pycodestyle", 99 "pycodestyle",
168 "pycodestyle", 168 "pycodestyle",
169 "tab before keyword"), 169 "tab before keyword"),
170 "E275": QCoreApplication.translate( 170 "E275": QCoreApplication.translate(
171 "pycodestyle", 171 "pycodestyle",
172 "missing whitespace after keyword"), 172 "missing whitespace after keyword"),
173 "W291": QCoreApplication.translate(
174 "pycodestyle",
175 "trailing whitespace"),
176 "W292": QCoreApplication.translate(
177 "pycodestyle",
178 "no newline at end of file"),
179 "W293": QCoreApplication.translate(
180 "pycodestyle",
181 "blank line contains whitespace"),
182 "E301": QCoreApplication.translate( 173 "E301": QCoreApplication.translate(
183 "pycodestyle", 174 "pycodestyle",
184 "expected {0} blank lines, found {1}"), 175 "expected {0} blank lines, found {1}"),
185 "E302": QCoreApplication.translate( 176 "E302": QCoreApplication.translate(
186 "pycodestyle", 177 "pycodestyle",
202 "pycodestyle", 193 "pycodestyle",
203 "too many blank lines ({0}) before a nested definition, expected {1}"), 194 "too many blank lines ({0}) before a nested definition, expected {1}"),
204 "E308": QCoreApplication.translate( 195 "E308": QCoreApplication.translate(
205 "pycodestyle", 196 "pycodestyle",
206 "too many blank lines ({0})"), 197 "too many blank lines ({0})"),
207 "W391": QCoreApplication.translate(
208 "pycodestyle",
209 "blank line at end of file"),
210 "E401": QCoreApplication.translate( 198 "E401": QCoreApplication.translate(
211 "pycodestyle", 199 "pycodestyle",
212 "multiple imports on one line"), 200 "multiple imports on one line"),
213 "E402": QCoreApplication.translate( 201 "E402": QCoreApplication.translate(
214 "pycodestyle", 202 "pycodestyle",
217 "pycodestyle", 205 "pycodestyle",
218 "line too long ({0} > {1} characters)"), 206 "line too long ({0} > {1} characters)"),
219 "E502": QCoreApplication.translate( 207 "E502": QCoreApplication.translate(
220 "pycodestyle", 208 "pycodestyle",
221 "the backslash is redundant between brackets"), 209 "the backslash is redundant between brackets"),
210 "E701": QCoreApplication.translate(
211 "pycodestyle",
212 "multiple statements on one line (colon)"),
213 "E702": QCoreApplication.translate(
214 "pycodestyle",
215 "multiple statements on one line (semicolon)"),
216 "E703": QCoreApplication.translate(
217 "pycodestyle",
218 "statement ends with a semicolon"),
219 "E704": QCoreApplication.translate(
220 "pycodestyle",
221 "multiple statements on one line (def)"),
222 "E711": QCoreApplication.translate(
223 "pycodestyle",
224 "comparison to {0} should be {1}"),
225 "E712": QCoreApplication.translate(
226 "pycodestyle",
227 "comparison to {0} should be {1}"),
228 "E713": QCoreApplication.translate(
229 "pycodestyle",
230 "test for membership should be 'not in'"),
231 "E714": QCoreApplication.translate(
232 "pycodestyle",
233 "test for object identity should be 'is not'"),
234 "E721": QCoreApplication.translate(
235 "pycodestyle",
236 "do not compare types, use 'isinstance()'"),
237 "E722": QCoreApplication.translate(
238 "pycodestyle",
239 "do not use bare except"),
240 "E731": QCoreApplication.translate(
241 "pycodestyle",
242 "do not assign a lambda expression, use a def"),
243 "E741": QCoreApplication.translate(
244 "pycodestyle",
245 "ambiguous variable name '{0}'"),
246 "E742": QCoreApplication.translate(
247 "pycodestyle",
248 "ambiguous class definition '{0}'"),
249 "E743": QCoreApplication.translate(
250 "pycodestyle",
251 "ambiguous function definition '{0}'"),
252 "E901": QCoreApplication.translate(
253 "pycodestyle",
254 "{0}: {1}"),
255 "E902": QCoreApplication.translate(
256 "pycodestyle",
257 "{0}"),
258 }
259
260 ##################################################################
261 ## pycodestyle warning messages
262 ##################################################################
263
264 _pycodestyleWarningMessages = {
265 "W191": QCoreApplication.translate(
266 "pycodestyle",
267 "indentation contains tabs"),
268 "W291": QCoreApplication.translate(
269 "pycodestyle",
270 "trailing whitespace"),
271 "W292": QCoreApplication.translate(
272 "pycodestyle",
273 "no newline at end of file"),
274 "W293": QCoreApplication.translate(
275 "pycodestyle",
276 "blank line contains whitespace"),
277 "W391": QCoreApplication.translate(
278 "pycodestyle",
279 "blank line at end of file"),
222 "W503": QCoreApplication.translate( 280 "W503": QCoreApplication.translate(
223 "pycodestyle", 281 "pycodestyle",
224 "line break before binary operator"), 282 "line break before binary operator"),
225 "W504": QCoreApplication.translate( 283 "W504": QCoreApplication.translate(
226 "pycodestyle", 284 "pycodestyle",
244 "pycodestyle", 302 "pycodestyle",
245 "invalid escape sequence '\\{0}'"), 303 "invalid escape sequence '\\{0}'"),
246 "W606": QCoreApplication.translate( 304 "W606": QCoreApplication.translate(
247 "pycodestyle", 305 "pycodestyle",
248 "'async' and 'await' are reserved keywords starting with Python 3.7"), 306 "'async' and 'await' are reserved keywords starting with Python 3.7"),
249 "E701": QCoreApplication.translate( 307 }
250 "pycodestyle", 308
251 "multiple statements on one line (colon)"), 309 ##################################################################
252 "E702": QCoreApplication.translate( 310 ## CodeStyleFixer messages
253 "pycodestyle", 311 ##################################################################
254 "multiple statements on one line (semicolon)"), 312
255 "E703": QCoreApplication.translate( 313 _fixMessages = {
256 "pycodestyle",
257 "statement ends with a semicolon"),
258 "E704": QCoreApplication.translate(
259 "pycodestyle",
260 "multiple statements on one line (def)"),
261 "E711": QCoreApplication.translate(
262 "pycodestyle",
263 "comparison to {0} should be {1}"),
264 "E712": QCoreApplication.translate(
265 "pycodestyle",
266 "comparison to {0} should be {1}"),
267 "E713": QCoreApplication.translate(
268 "pycodestyle",
269 "test for membership should be 'not in'"),
270 "E714": QCoreApplication.translate(
271 "pycodestyle",
272 "test for object identity should be 'is not'"),
273 "E721": QCoreApplication.translate(
274 "pycodestyle",
275 "do not compare types, use 'isinstance()'"),
276 "E722": QCoreApplication.translate(
277 "pycodestyle",
278 "do not use bare except"),
279 "E731": QCoreApplication.translate(
280 "pycodestyle",
281 "do not assign a lambda expression, use a def"),
282 "E741": QCoreApplication.translate(
283 "pycodestyle",
284 "ambiguous variable name '{0}'"),
285 "E742": QCoreApplication.translate(
286 "pycodestyle",
287 "ambiguous class definition '{0}'"),
288 "E743": QCoreApplication.translate(
289 "pycodestyle",
290 "ambiguous function definition '{0}'"),
291 "E901": QCoreApplication.translate(
292 "pycodestyle",
293 "{0}: {1}"),
294 "E902": QCoreApplication.translate(
295 "pycodestyle",
296 "{0}"),
297
298 ##################################################################
299 ## CodeStyleFixer messages
300 ##################################################################
301
302 "FIXD111": QCoreApplication.translate( 314 "FIXD111": QCoreApplication.translate(
303 'CodeStyleFixer', 315 'CodeStyleFixer',
304 "Triple single quotes converted to triple double quotes."), 316 "Triple single quotes converted to triple double quotes."),
305 'FIXD112': QCoreApplication.translate( 317 'FIXD112': QCoreApplication.translate(
306 'CodeStyleFixer', 318 'CodeStyleFixer',
446 "FIXWRITE_ERROR": QCoreApplication.translate( 458 "FIXWRITE_ERROR": QCoreApplication.translate(
447 'CodeStyleFixer', 459 'CodeStyleFixer',
448 "Could not save the file! Skipping it. Reason: {0}"), 460 "Could not save the file! Skipping it. Reason: {0}"),
449 } 461 }
450 462
451 _messages_sample_args = { 463 _pycodestyleErrorMessagesSampleArgs = {
452 "E201": ["([{"], 464 "E201": ["([{"],
453 "E202": ["}])"], 465 "E202": ["}])"],
454 "E203": [",;:"], 466 "E203": [",;:"],
455 "E211": ["(["], 467 "E211": ["(["],
456 "E231": [",;:"], 468 "E231": [",;:"],
462 "E305": [2, 1], 474 "E305": [2, 1],
463 "E306": [1, 0], 475 "E306": [1, 0],
464 "E307": [3, 1], 476 "E307": [3, 1],
465 "E308": [3], 477 "E308": [3],
466 "E501": [85, 79], 478 "E501": [85, 79],
467 "W505": [80, 72],
468 "E605": ["A"], 479 "E605": ["A"],
469 "E711": ["None", "'if cond is None:'"], 480 "E711": ["None", "'if cond is None:'"],
470 "E712": ["True", "'if cond is True:' or 'if cond:'"], 481 "E712": ["True", "'if cond is True:' or 'if cond:'"],
471 "E741": ["l"], 482 "E741": ["l"],
472 "E742": ["l"], 483 "E742": ["l"],
473 "E743": ["l"], 484 "E743": ["l"],
474 "E901": ["SyntaxError", "Invalid Syntax"], 485 "E901": ["SyntaxError", "Invalid Syntax"],
475 "E902": ["OSError"], 486 "E902": ["OSError"],
487 }
488
489 _pycodestyleWarningMessagesSampleArgs = {
490 "W505": [80, 72],
491 }
492
493 _fixMessagesSampleArgs = {
494 "FIXWRITE_ERROR": ["OSError"],
495 }
496
497 messageCatalogs = {
498 "A": _annotationsMessages,
499 "C": _complexityMessages,
500 "D": _docStyleMessages,
501 "E": _pycodestyleErrorMessages,
502 "M": _miscellaneousMessages,
503 "N": _namingStyleMessages,
504 "P": _pathlibMessages,
505 "S": _securityMessages,
506 "W": _pycodestyleWarningMessages,
476 507
477 "FIXWRITE_ERROR": ["OSError"], 508 "FIX": _fixMessages,
478 } 509 }
479 510
480 messageCatalogs = ( 511 messageSampleArgsCatalog = {
481 _messages, 512 "A": _annotationsMessagesSampleArgs,
482 _annotationsMessages, 513 "C": _complexityMessagesSampleArgs,
483 _complexityMessages, 514 "D": _docStyleMessagesSampleArgs,
484 _docStyleMessages, 515 "E": _pycodestyleErrorMessagesSampleArgs,
485 _miscellaneousMessages, 516 "M": _miscellaneousMessagesSampleArgs,
486 _namingStyleMessages, 517 "S": _securityMessagesSampleArgs,
487 _pathlibMessages, 518 "W": _pycodestyleWarningMessagesSampleArgs,
488 _securityMessages, 519
489 ) 520 "FIX": _fixMessagesSampleArgs,
490 521 }
491 messageSampleArgsCatalog = ( 522
492 _messages_sample_args, 523 messageCategoryRe = re.compile(r"([A-Z]{1,3}).+")
493 _annotationsMessagesSampleArgs, 524
494 _complexityMessagesSampleArgs,
495 _docStyleMessagesSampleArgs,
496 _miscellaneousMessagesSampleArgs,
497 _securityMessagesSampleArgs,
498 )
499
500
501 # TODO: change this to use the initial character (= class) of the message code
502 # to select the appropriate catalog (observe FIX as code category)
503 def getTranslatedMessage(messageCode, messageArgs, example=False): 525 def getTranslatedMessage(messageCode, messageArgs, example=False):
504 """ 526 """
505 Module function to get a translated and formatted message for a 527 Module function to get a translated and formatted message for a
506 given message ID. 528 given message ID.
507 529
514 data is requested (messageArgs is ignored if given) 536 data is requested (messageArgs is ignored if given)
515 @type bool 537 @type bool
516 @return translated and formatted message 538 @return translated and formatted message
517 @rtype str 539 @rtype str
518 """ 540 """
519 if example: 541 match = messageCategoryRe.match(messageCode)
520 for argsCatalog in messageSampleArgsCatalog: 542 if match:
521 if messageCode in argsCatalog: 543 # the message code is OK
522 args = argsCatalog[messageCode] 544 messageCategory = match.group(1)
523 break 545
546 if example:
547 try:
548 argsCatalog = messageSampleArgsCatalog[messageCategory]
549 try:
550 args = argsCatalog[messageCode]
551 except KeyError:
552 args = None
553 except KeyError:
554 args = None
524 else: 555 else:
525 args = None 556 args = messageArgs
526 else: 557
527 args = messageArgs 558 try:
528 559 catalog = messageCatalogs[messageCategory]
529 for catalog in messageCatalogs: 560 try:
530 if messageCode in catalog: 561 message = catalog[messageCode]
531 if args is None: 562 if args is None:
532 return catalog[messageCode] 563 return message
533 elif isinstance(args, int): 564 elif isinstance(args, int):
534 # Retranslate with correct plural form 565 # Retranslate with correct plural form
535 return catalog[messageCode](args) 566 return message(args)
536 else: 567 else:
537 return catalog[messageCode].format(*args) 568 return message.format(*args)
538 else: 569 except KeyError:
570 pass
571 except KeyError:
572 pass
573
539 if example: 574 if example:
540 return None 575 return None
541 else: 576 else:
542 return QCoreApplication.translate( 577 return QCoreApplication.translate(
543 "CodeStyleChecker", 578 "CodeStyleChecker",
551 586
552 @return list of known message codes 587 @return list of known message codes
553 @rtype set of str 588 @rtype set of str
554 """ 589 """
555 knownCodes = [] 590 knownCodes = []
556 for catalog in messageCatalogs: 591 for catalog in messageCatalogs.values():
557 knownCodes += list(catalog.keys()) 592 knownCodes += list(catalog.keys())
558 return {c.split(".", 1)[0] for c in knownCodes} 593 return {c.split(".", 1)[0] for c in knownCodes}
559 594
560 # 595 #
561 # eflag: noqa = M201 596 # eflag: noqa = M201

eric ide

mercurial