114114 "Used when there is different newline than expected." ,
115115 ),
116116 "C0329" : (
117- "float literal should be written as '%s' instead" ,
117+ "'%s' %s, and it should be written as '%s' instead" ,
118118 "bad-float-notation" ,
119119 "Emitted when a number is written in a non-standard notation. The three "
120120 "allowed notation above the threshold are the scientific notation, the "
@@ -516,10 +516,9 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
516516 if tok_type == tokenize .NUMBER :
517517 if (
518518 self .linter .is_message_enabled ("bad-float-notation" )
519- and
520519 # You don't deserve a linter if you mix non-decimal notation and
521520 # exponential or underscore,
522- "x" not in string # not a hexadecimal
521+ and "x" not in string # not a hexadecimal
523522 and "o" not in string # not an octal
524523 and "j" not in string # not a complex
525524 and "b" not in string # not a binary
@@ -653,7 +652,7 @@ def _check_bad_float_notation( # pylint: disable=too-many-locals
653652 or self .linter .config .strict_underscore_notation
654653 )
655654
656- def raise_bad_float_notation () -> None :
655+ def raise_bad_float_notation (reason : str ) -> None :
657656 suggested = set ()
658657 if scientific :
659658 suggested .add (self .to_standard_scientific_notation (value ))
@@ -663,7 +662,7 @@ def raise_bad_float_notation() -> None:
663662 suggested .add (self .to_standard_underscore_grouping (value ))
664663 return self .add_message (
665664 "bad-float-notation" ,
666- args = ("' or '" .join (sorted (suggested ))),
665+ args = (string , reason , "' or '" .join (sorted (suggested ))),
667666 line = line_num ,
668667 end_lineno = line_num ,
669668 col_offset = start [1 ],
@@ -682,11 +681,12 @@ def raise_bad_float_notation() -> None:
682681 # If the value does not deserve a complex notation then write it in a simple way.
683682 # The threshold is guaranteed to be higher than those value.
684683 # When 1 <= value < 10 the engineering notation is equivalent to the scientific notation
685- return raise_bad_float_notation ()
684+ return raise_bad_float_notation ("has underscore or exponent" )
686685
687686 abs_value = abs (value )
687+ under_threshold = abs_value < self .linter .config .float_notation_threshold
688688 should_not_be_checked_because_of_threshold = (
689- abs_value < self . linter . config . float_notation_threshold # under threshold
689+ under_threshold # under threshold
690690 and ( # use scientific or engineering notation and under 1/threshold
691691 self .linter .config .strict_underscore_notation
692692 or (
@@ -700,11 +700,22 @@ def raise_bad_float_notation() -> None:
700700 # This number is free style, we do not have to check it, unless it's
701701 # written complexly, then it could be badly written
702702 return None
703- return raise_bad_float_notation ()
703+ threshold = self .linter .config .float_notation_threshold
704+ close_to_zero_threshold = self .to_standard_scientific_notation (
705+ 1 / threshold
706+ )
707+ threshold = self .to_standard_scientific_notation (threshold )
708+ return raise_bad_float_notation (
709+ f"is smaller than { close_to_zero_threshold } "
710+ if under_threshold
711+ else f"is bigger than { threshold } "
712+ )
704713 if has_exponent :
705714 if self .linter .config .strict_underscore_notation or has_underscore :
706715 # If we have exponent it means it's not proper underscore
707- return raise_bad_float_notation ()
716+ return raise_bad_float_notation (
717+ "has exponent and underscore at the same time"
718+ )
708719 base_as_str , exponent_as_str = string .lower ().split ("e" )
709720 base = float (base_as_str )
710721 # print("\tBase:", base, "Exponent:", exponent_as_str)
@@ -713,29 +724,45 @@ def raise_bad_float_notation() -> None:
713724 self .linter .config .strict_scientific_notation
714725 and wrong_scientific_notation
715726 ):
716- return raise_bad_float_notation ()
727+ return raise_bad_float_notation (
728+ f"has a base, '{ base } ', that is not strictly inferior to 10"
729+ if base == 10
730+ else f"has a base, '{ base } ', that is not between 1 and 10"
731+ )
717732 wrong_engineering_notation = not (
718733 1 <= base < 1000 and int (exponent_as_str ) % 3 == 0
719734 )
720735 if (
721736 self .linter .config .strict_engineering_notation
722737 and wrong_engineering_notation
723738 ) or (wrong_scientific_notation and wrong_engineering_notation ):
724- return raise_bad_float_notation ()
739+ return raise_bad_float_notation (
740+ f"has an exponent '{ exponent_as_str } ' that is not a multiple of 3"
741+ if 1 <= base < 1000
742+ else (
743+ f"has a base, '{ base } ', that is not strictly inferior to 1000"
744+ if base == 1000
745+ else f"has a base, '{ base } ', that is not between 1 and 1000"
746+ )
747+ )
725748 elif has_underscore :
726749 # If we have underscore and exponent, we suggest exponent by default
727750 if (
728751 self .linter .config .strict_scientific_notation
729752 or self .linter .config .strict_engineering_notation
730753 ):
731- return raise_bad_float_notation ()
754+ return raise_bad_float_notation (
755+ "use underscore instead of exponents" + ""
756+ if self .linter .config .strict_scientific_notation
757+ else " that are multiple of 3"
758+ )
732759 wrong_underscore_notation = not re .match (
733760 r"^\d{0,3}(_\d{3})*\.?\d*([eE]-?\d{0,3}(_\d{3})*)?$" , string
734761 )
735762 if pep515 and wrong_underscore_notation :
736- return raise_bad_float_notation ()
737- else :
738- return raise_bad_float_notation ( )
763+ return raise_bad_float_notation (
764+ "has underscores that are not delimiting packs of three digits"
765+ )
739766 return None
740767
741768 def _check_line_ending (self , line_ending : str , line_num : int ) -> None :
0 commit comments