Skip to content

Commit 7d5672d

Browse files
Give a reason for why a notation is bad and display the float (temporarily for easier primer reading)
1 parent 2886dc7 commit 7d5672d

File tree

5 files changed

+107
-80
lines changed

5 files changed

+107
-80
lines changed

pylint/checkers/format.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
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:
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bad-float-notation:3:33:3:38::float literal should be written as '1.23e6' instead:HIGH
2-
bad-float-notation:4:38:4:45::float literal should be written as '12.344999999999999e9' instead:HIGH
3-
bad-float-notation:5:35:5:43::float literal should be written as '10e6' instead:HIGH
4-
bad-float-notation:6:33:6:38::float literal should be written as '990.0' instead:HIGH
1+
bad-float-notation:3:33:3:38::'123e4' has an exponent '4' that is not a multiple of 3, and it should be written as '1.23e6' instead:HIGH
2+
bad-float-notation:4:38:4:45::'12345e6' has a base, '12345.0', that is not between 1 and 1000, and it should be written as '12.344999999999999e9' instead:HIGH
3+
bad-float-notation:5:35:5:43::'10000000' is bigger than 1e6, and it should be written as '10e6' instead:HIGH
4+
bad-float-notation:6:33:6:38::'9.9e2' has underscore or exponent, and it should be written as '990.0' instead:HIGH

0 commit comments

Comments
 (0)