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