1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5# Original (c) 2005 Divmod, Inc. See __init__.py file for details 6# 7# This module is based on pyflakes, but was modified to 8# be integrated into eric 9 10""" 11Module providing the class Message and its subclasses. 12""" 13 14 15class Message(): 16 """ 17 Class defining the base for all specific message classes. 18 """ 19 message_id = 'F00' 20 message = '' 21 message_args = () 22 23 def __init__(self, filename, loc): 24 """ 25 Constructor 26 27 @param filename name of the file 28 @type str 29 @param loc location of the issue 30 """ 31 self.filename = filename 32 self.lineno = loc.lineno 33 self.col = getattr(loc, 'col_offset', 0) 34 35 def __str__(self): 36 """ 37 Special method return a string representation of the instance object. 38 39 @return string representation of the object 40 @rtype str 41 """ 42 return '{0}:{1}:{2} {3}'.format( 43 self.filename, self.lineno, self.col + 1, 44 self.message % self.message_args) 45 46 def getMessageData(self): 47 """ 48 Public method to get the individual message data elements. 49 50 @return tuple containing file name, line number, column, message ID 51 and message arguments 52 @rtype tuple of (str, int, int, str, list) 53 """ 54 return (self.filename, self.lineno, self.col, self.message_id, 55 self.message_args) 56 57 58class UnusedImport(Message): 59 """ 60 Class defining the "Unused Import" message. 61 """ 62 message_id = 'F01' 63 message = '%r imported but unused' 64 65 def __init__(self, filename, loc, name): 66 """ 67 Constructor 68 69 @param filename name of the file (string) 70 @param loc location of the issue 71 @param name name of the unused import (string) 72 """ 73 Message.__init__(self, filename, loc) 74 self.message_args = (name,) 75 76 77class RedefinedWhileUnused(Message): 78 """ 79 Class defining the "Redefined While Unused" message. 80 """ 81 message_id = 'F02' 82 message = 'redefinition of unused %r from line %r' 83 84 def __init__(self, filename, loc, name, orig_loc): 85 """ 86 Constructor 87 88 @param filename name of the file (string) 89 @param loc location of the issue 90 @param name name of the redefined object (string) 91 @param orig_loc location of the original definition 92 """ 93 Message.__init__(self, filename, loc) 94 self.message_args = (name, orig_loc.lineno) 95 96 97class RedefinedInListComp(Message): 98 """ 99 Class defining the "Redefined In List Comprehension" message. 100 """ 101 message_id = 'F12' 102 message = 'list comprehension redefines %r from line %r' 103 104 def __init__(self, filename, loc, name, orig_loc): 105 """ 106 Constructor 107 108 @param filename name of the file (string) 109 @param loc location of the issue 110 @param name name of the redefined object (string) 111 @param orig_loc location of the original definition 112 """ 113 Message.__init__(self, filename, loc) 114 self.message_args = (name, orig_loc.lineno) 115 116 117class ImportShadowedByLoopVar(Message): 118 """ 119 Class defining the "Import Shadowed By Loop Var" message. 120 """ 121 message_id = 'F03' 122 message = 'import %r from line %r shadowed by loop variable' 123 124 def __init__(self, filename, loc, name, orig_loc): 125 """ 126 Constructor 127 128 @param filename name of the file (string) 129 @param loc location of the issue 130 @param name name of the shadowed import (string) 131 @param orig_loc location of the import 132 """ 133 Message.__init__(self, filename, loc) 134 self.message_args = (name, orig_loc.lineno) 135 136 137class ImportStarNotPermitted(Message): 138 """ 139 Class defining the "Import * not permitted" message. 140 """ 141 message_id = 'F16' 142 message = "'from %s import *' only allowed at module level" 143 144 def __init__(self, filename, loc, modname): 145 """ 146 Constructor 147 148 @param filename name of the file (string) 149 @param loc location of the issue 150 @param modname name of the module (string) 151 """ 152 Message.__init__(self, filename, loc) 153 self.message_args = (modname,) 154 155 156class ImportStarUsed(Message): 157 """ 158 Class defining the "Import Star Used" message. 159 """ 160 message_id = 'F04' 161 message = "'from %s import *' used; unable to detect undefined names" 162 163 def __init__(self, filename, loc, modname): 164 """ 165 Constructor 166 167 @param filename name of the file (string) 168 @param loc location of the issue 169 @param modname name of the module imported using star import (string) 170 """ 171 Message.__init__(self, filename, loc) 172 self.message_args = (modname,) 173 174 175class ImportStarUsage(Message): 176 """ 177 Class defining the "Import Star Usage" message. 178 """ 179 message_id = 'F17' 180 message = "%r may be undefined, or defined from star imports: %s" 181 182 def __init__(self, filename, loc, name, from_list): 183 """ 184 Constructor 185 186 @param filename name of the file (string) 187 @param loc location of the issue 188 @param name name of the variable (string) 189 @param from_list list of modules imported from with * (string) 190 """ 191 Message.__init__(self, filename, loc) 192 self.message_args = (name, from_list) 193 194 195class UndefinedName(Message): 196 """ 197 Class defining the "Undefined Name" message. 198 """ 199 message_id = 'F05' 200 message = 'undefined name %r' 201 202 def __init__(self, filename, loc, name): 203 """ 204 Constructor 205 206 @param filename name of the file (string) 207 @param loc location of the issue 208 @param name undefined name (string) 209 """ 210 Message.__init__(self, filename, loc) 211 self.message_args = (name,) 212 213 214class DoctestSyntaxError(Message): 215 """ 216 Class defining the "Doctest syntax Error" message. 217 """ 218 message_id = 'F13' 219 message = 'syntax error in doctest' 220 221 def __init__(self, filename, loc, position=None): 222 """ 223 Constructor 224 225 @param filename name of the file (string) 226 @param loc location of the issue 227 @param position position of the syntax error 228 """ 229 Message.__init__(self, filename, loc) 230 if position: 231 (self.lineno, self.col) = position 232 self.message_args = () 233 234 235class UndefinedExport(Message): 236 """ 237 Class defining the "Undefined Export" message. 238 """ 239 message_id = 'F06' 240 message = 'undefined name %r in __all__' 241 242 def __init__(self, filename, loc, name): 243 """ 244 Constructor 245 246 @param filename name of the file (string) 247 @param loc location of the issue 248 @param name undefined exported name (string) 249 """ 250 Message.__init__(self, filename, loc) 251 self.message_args = (name,) 252 253 254class UndefinedLocal(Message): 255 """ 256 Class defining the "Undefined Local Variable" message. 257 """ 258 message_id = 'F07' 259 message = 'local variable %r {0} referenced before assignment' 260 261 default = 'defined in enclosing scope on line %r' 262 builtin = 'defined as a builtin' 263 264 def __init__(self, filename, loc, name, orig_loc): 265 """ 266 Constructor 267 268 @param filename name of the file (string) 269 @param loc location of the issue 270 @param name name of the prematurely referenced variable (string) 271 @param orig_loc location of the variable definition 272 """ 273 Message.__init__(self, filename, loc) 274 if orig_loc is None: 275 self.message = self.message.format(self.builtin) 276 self.message_args = (name,) 277 self.message_id = 'F07B' 278 else: 279 self.message = self.message.format(self.default) 280 self.message_args = (name, orig_loc.lineno) 281 self.message_id = 'F07A' 282 283 284class DuplicateArgument(Message): 285 """ 286 Class defining the "Duplicate Argument" message. 287 """ 288 message_id = 'F08' 289 message = 'duplicate argument %r in function definition' 290 291 def __init__(self, filename, loc, name): 292 """ 293 Constructor 294 295 @param filename name of the file (string) 296 @param loc location of the issue 297 @param name name of the duplicate argument (string) 298 """ 299 Message.__init__(self, filename, loc) 300 self.message_args = (name,) 301 302 303class MultiValueRepeatedKeyLiteral(Message): 304 """ 305 Class defining the multiple used dictionary key message. 306 """ 307 message_id = 'F18' 308 message = 'dictionary key %r repeated with different values' 309 310 def __init__(self, filename, loc, key): 311 """ 312 Constructor 313 314 @param filename name of the file (string) 315 @param loc location of the issue 316 @param key dictionary key (string) 317 """ 318 Message.__init__(self, filename, loc) 319 self.message_args = (key,) 320 321 322class MultiValueRepeatedKeyVariable(Message): 323 """ 324 Class defining the multiple used dictionary key variable message. 325 """ 326 message_id = 'F19' 327 message = 'dictionary key variable %s repeated with different values' 328 329 def __init__(self, filename, loc, key): 330 """ 331 Constructor 332 333 @param filename name of the file (string) 334 @param loc location of the issue 335 @param key dictionary key variable (string) 336 """ 337 Message.__init__(self, filename, loc) 338 self.message_args = (key,) 339 340 341class LateFutureImport(Message): 342 """ 343 Class defining the "Late Future Import" message. 344 """ 345 message_id = 'F10' 346 message = 'from __future__ imports must occur at the beginning of the file' 347 348 def __init__(self, filename, loc, names): 349 """ 350 Constructor 351 352 @param filename name of the file (string) 353 @param loc location of the issue 354 @param names names of the imported futures (string) 355 """ 356 Message.__init__(self, filename, loc) 357 self.message_args = () 358 359 360class FutureFeatureNotDefined(Message): 361 """ 362 Class defining the undefined __future__ feature message. 363 """ 364 message_id = 'F20' 365 message = 'future feature %s is not defined' 366 367 def __init__(self, filename, loc, name): 368 """ 369 Constructor 370 371 @param filename name of the file (string) 372 @param loc location of the issue 373 @param name name of the imported undefined future feature (string) 374 """ 375 Message.__init__(self, filename, loc) 376 self.message_args = (name,) 377 378 379class UnusedVariable(Message): 380 """ 381 Class defining the "Unused Variable" message. 382 383 Indicates that a variable has been explicitly assigned to but not actually 384 used. 385 """ 386 message_id = 'F11' 387 message = 'local variable %r is assigned to but never used' 388 389 def __init__(self, filename, loc, names): 390 """ 391 Constructor 392 393 @param filename name of the file (string) 394 @param loc location of the issue 395 @param names names of unused variable (string) 396 """ 397 Message.__init__(self, filename, loc) 398 self.message_args = (names,) 399 400 401class ReturnWithArgsInsideGenerator(Message): 402 """ 403 Class defining the "Return values in generator" message. 404 405 Indicates a return statement with arguments inside a generator. 406 """ 407 message_id = 'F14' 408 message = '\'return\' with argument inside generator' 409 410 411class ReturnOutsideFunction(Message): 412 """ 413 Class defining the "Return outside function" message. 414 415 Indicates a return statement outside of a function/method. 416 """ 417 message_id = 'F15' 418 message = '\'return\' outside function' 419 420 421class YieldOutsideFunction(Message): 422 """ 423 Class defining the "Yield outside function" message. 424 425 Indicates a yield or yield from statement outside of a function/method. 426 """ 427 message_id = 'F21' 428 message = '\'yield\' outside function' 429 430 431# For whatever reason, Python gives different error messages for these two. We 432# match the Python error message exactly. 433class ContinueOutsideLoop(Message): 434 """ 435 Class defining the "Continue outside loop" message. 436 437 Indicates a continue statement outside of a while or for loop. 438 """ 439 message_id = 'F22' 440 message = '\'continue\' not properly in loop' 441 442 443class BreakOutsideLoop(Message): 444 """ 445 Class defining the "Break outside loop" message. 446 447 Indicates a break statement outside of a while or for loop. 448 """ 449 message_id = 'F23' 450 message = '\'break\' outside loop' 451 452 453class ContinueInFinally(Message): 454 """ 455 Class defining the "Continue in finally block" message. 456 457 Indicates a continue statement in a finally block in a while or for loop. 458 """ 459 message_id = 'F24' 460 message = '\'continue\' not supported inside \'finally\' clause' 461 462 463class DefaultExceptNotLast(Message): 464 """ 465 Class defining the "Default except not being the last" message. 466 467 Indicates an except: block as not the last exception handler. 468 """ 469 message_id = 'F25' 470 message = 'default \'except:\' must be last' 471 472 473class TwoStarredExpressions(Message): 474 """ 475 Class defining the "multiple starred expressions" message. 476 477 Two or more starred expressions in an assignment (a, *b, *c = d). 478 """ 479 message_id = 'F26' 480 message = 'two starred expressions in assignment' 481 482 483class TooManyExpressionsInStarredAssignment(Message): 484 """ 485 Class defining the "too many starred expressions" message. 486 487 Too many expressions in an assignment with star-unpacking 488 """ 489 message_id = 'F27' 490 message = 'too many expressions in star-unpacking assignment' 491 492 493class IfTuple(Message): 494 """ 495 Class defining the "non-empty tuple literal" message. 496 497 Conditional test is a non-empty tuple literal, which are always True. 498 """ 499 message_id = 'F49' 500 message = ( 501 '\'if tuple literal\' is always true, perhaps remove accidental comma?' 502 ) 503 504 505class AssertTuple(Message): 506 """ 507 Class defining the "tuple assertion" message. 508 509 Assertion test is a tuple, which are always True. 510 """ 511 message_id = 'F28' 512 message = 'assertion is always true, perhaps remove parentheses?' 513 514 515class ForwardAnnotationSyntaxError(Message): 516 """ 517 Class defining the "forward annotation syntax error" message. 518 519 Found a syntax error in forward annotation. 520 """ 521 message_id = 'F29' 522 message = 'syntax error in forward annotation %r' 523 524 def __init__(self, filename, loc, annotation): 525 """ 526 Constructor 527 528 @param filename name of the file (string) 529 @param loc location of the issue 530 @param annotation erroneous forward annotation (string) 531 """ 532 Message.__init__(self, filename, loc) 533 self.message_args = (annotation,) 534 535 536class CommentAnnotationSyntaxError(Message): 537 """ 538 Class defining the "Comment Annotation Syntax Error" message. 539 540 Indicates a syntax error in a type comment. 541 """ 542 message_id = 'F31' 543 message = 'syntax error in type comment %r' 544 545 def __init__(self, filename, loc, annotation): 546 """ 547 Constructor 548 549 @param filename name of the file (string) 550 @param loc location of the issue 551 @param annotation erroneous forward annotation (string) 552 """ 553 Message.__init__(self, filename, loc) 554 self.message_args = (annotation,) 555 556 557class RaiseNotImplemented(Message): 558 """ 559 Class defining the "raise not implemented" message. 560 561 Use NotImplementedError instead of NotImplemented. 562 """ 563 message_id = 'F30' 564 message = "'raise NotImplemented' should be 'raise NotImplementedError'" 565 566 567class InvalidPrintSyntax(Message): 568 """ 569 Class defining the "Invalid Print Syntax" message. 570 571 Indicates the use of >> with a print function. 572 """ 573 message_id = 'F32' 574 message = 'use of >> is invalid with print function' 575 576 577class IsLiteral(Message): 578 """ 579 Class defining the "Is Literal" message. 580 581 Indicates the use of "is" or "is not" against str, int and bytes. 582 """ 583 message_id = 'F33' 584 message = 'use ==/!= to compare str, bytes, and int literals' 585 586 587class FStringMissingPlaceholders(Message): 588 """ 589 Class defining the "Missing Placeholder" message. 590 591 Indicates that an f-string is missing some placeholders. 592 """ 593 message_id = 'F34' 594 message = 'f-string is missing placeholders' 595 596 597class StringDotFormatExtraPositionalArguments(Message): 598 """ 599 Class defining the "Unused Arguments" message. 600 601 Indicates that an f-string has unused arguments. 602 """ 603 message_id = 'F35' 604 message = "'...'.format(...) has unused arguments at position(s): %s" 605 606 def __init__(self, filename, loc, extra_positions): 607 """ 608 Constructor 609 610 @param filename name of the file (string) 611 @param loc location of the issue 612 @param extra_positions indexes of unused arguments 613 """ 614 Message.__init__(self, filename, loc) 615 self.message_args = (extra_positions,) 616 617 618class StringDotFormatExtraNamedArguments(Message): 619 """ 620 Class defining the "Unused Named Arguments" message. 621 622 Indicates that an f-string has unused named arguments. 623 """ 624 message_id = 'F36' 625 message = "'...'.format(...) has unused named argument(s): %s" 626 627 def __init__(self, filename, loc, extra_keywords): 628 """ 629 Constructor 630 631 @param filename name of the file (string) 632 @param loc location of the issue 633 @param extra_keywords index of unused named arguments 634 """ 635 Message.__init__(self, filename, loc) 636 self.message_args = (extra_keywords,) 637 638 639class StringDotFormatMissingArgument(Message): 640 """ 641 Class defining the "Missing Arguments" message. 642 643 Indicates that an f-string is missing some arguments. 644 """ 645 message_id = 'F37' 646 message = "'...'.format(...) is missing argument(s) for placeholder(s): %s" 647 648 def __init__(self, filename, loc, missing_arguments): 649 """ 650 Constructor 651 652 @param filename name of the file (string) 653 @param loc location of the issue 654 @param missing_arguments missing arguments 655 """ 656 Message.__init__(self, filename, loc) 657 self.message_args = (missing_arguments,) 658 659 660class StringDotFormatMixingAutomatic(Message): 661 """ 662 Class defining the "Mixing Automatic and Manual" message. 663 664 Indicates that an f-string mixes automatic and manual numbering. 665 """ 666 message_id = 'F38' 667 message = "'...'.format(...) mixes automatic and manual numbering" 668 669 670class StringDotFormatInvalidFormat(Message): 671 """ 672 Class defining the "Invalid Format String" message. 673 674 Indicates that an f-string contains an invalid format string. 675 """ 676 message_id = 'F39' 677 message = "'...'.format(...) has invalid format string: %s" 678 679 def __init__(self, filename, loc, error): 680 """ 681 Constructor 682 683 @param filename name of the file (string) 684 @param loc location of the issue 685 @param error error details 686 """ 687 Message.__init__(self, filename, loc) 688 if not isinstance(error, str): 689 error = str(error) 690 self.message_args = (error,) 691 692 693class PercentFormatInvalidFormat(Message): 694 """ 695 Class defining the "Invalid Percent Format String" message. 696 697 Indicates that a percent format has an invalid format string. 698 """ 699 message_id = 'F40' 700 message = "'...' %% ... has invalid format string: %s" 701 702 def __init__(self, filename, loc, error): 703 """ 704 Constructor 705 706 @param filename name of the file (string) 707 @param loc location of the issue 708 @param error error details 709 """ 710 Message.__init__(self, filename, loc) 711 self.message_args = (error,) 712 713 714class PercentFormatMixedPositionalAndNamed(Message): 715 """ 716 Class defining the "Mixed Positional and Named" message. 717 718 Indicates that a percent format has mixed positional and named 719 placeholders. 720 """ 721 message_id = 'F41' 722 message = "'...' %% ... has mixed positional and named placeholders" 723 724 725class PercentFormatUnsupportedFormatCharacter(Message): 726 """ 727 Class defining the "Unsupported Format Character" message. 728 729 Indicates that a percent format has an unsupported format character. 730 """ 731 message_id = 'F42' 732 message = "'...' %% ... has unsupported format character %r" 733 734 def __init__(self, filename, loc, c): 735 """ 736 Constructor 737 738 @param filename name of the file (string) 739 @param loc location of the issue 740 @param c unsupported format character 741 """ 742 Message.__init__(self, filename, loc) 743 self.message_args = (c,) 744 745 746class PercentFormatPositionalCountMismatch(Message): 747 """ 748 Class defining the "Placeholder Substitution Mismatch" message. 749 750 Indicates that a percent format has a mismatching number of placeholders 751 and substitutions. 752 """ 753 message_id = 'F43' 754 message = "'...' %% ... has %d placeholder(s) but %d substitution(s)" 755 756 def __init__(self, filename, loc, n_placeholders, n_substitutions): 757 """ 758 Constructor 759 760 @param filename name of the file (string) 761 @param loc location of the issue 762 @param n_placeholders number of placeholders (integer) 763 @param n_substitutions number of substitutions (integer) 764 """ 765 Message.__init__(self, filename, loc) 766 self.message_args = (n_placeholders, n_substitutions) 767 768 769class PercentFormatExtraNamedArguments(Message): 770 """ 771 Class defining the "Unused Named Arguments" message. 772 773 Indicates that a percent format has unused named arguments. 774 """ 775 message_id = 'F44' 776 message = "'...' %% ... has unused named argument(s): %s" 777 778 def __init__(self, filename, loc, extra_keywords): 779 """ 780 Constructor 781 782 @param filename name of the file (string) 783 @param loc location of the issue 784 @param extra_keywords index of unused named arguments 785 """ 786 Message.__init__(self, filename, loc) 787 self.message_args = (extra_keywords,) 788 789 790class PercentFormatMissingArgument(Message): 791 """ 792 Class defining the "Missing Arguments" message. 793 794 Indicates that a percent format is missing arguments for some placeholders. 795 """ 796 message_id = 'F45' 797 message = "'...' %% ... is missing argument(s) for placeholder(s): %s" 798 799 def __init__(self, filename, loc, missing_arguments): 800 """ 801 Constructor 802 803 @param filename name of the file (string) 804 @param loc location of the issue 805 @param missing_arguments missing arguments 806 """ 807 Message.__init__(self, filename, loc) 808 self.message_args = (missing_arguments,) 809 810 811class PercentFormatExpectedMapping(Message): 812 """ 813 Class defining the "Sequence instead of Mapping" message. 814 815 Indicates that a percent format expected a mapping but got a sequence. 816 """ 817 message_id = 'F46' 818 message = "'...' %% ... expected mapping but got sequence" 819 820 821class PercentFormatExpectedSequence(Message): 822 """ 823 Class defining the "Mapping instead of Sequence" message. 824 825 Indicates that a percent format expected a sequence but got a mapping. 826 """ 827 message_id = 'F47' 828 message = "'...' %% ... expected sequence but got mapping" 829 830 831class PercentFormatStarRequiresSequence(Message): 832 """ 833 Class defining the "'*' Requires Sequence" message. 834 835 Indicates that a percent format expected a sequence. 836 """ 837 message_id = 'F48' 838 message = "'...' %% ... `*` specifier requires sequence" 839