Skip to content

Commit 902096c

Browse files
[use-math-not-float] Add a check for float(inf) and float(nan)
Co-authored-by: Morwenn <[email protected]>
1 parent a85bf0c commit 902096c

File tree

8 files changed

+73
-2
lines changed

8 files changed

+73
-2
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
swag = float("inf") # [use-math-not-float]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import math
2+
3+
swag = math.inf
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[MAIN]
2+
load-plugins=pylint.extensions.code_style
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Add a ``use-math-not-float`` message. float("nan") and float("inf") are slower
2+
than their counterpart ``math.inf`` and ``math.nan`` by a factor of 4 and they
3+
are also not well typed when using mypy.
4+
5+
The :ref:`pylint.extensions.code_style` need to be activated for this check to work.
6+
7+
Refs #10621

pylint/extensions/code_style.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ class CodeStyleChecker(BaseChecker):
7474
"default_enabled": False,
7575
},
7676
),
77+
"R6106": (
78+
"%smath.%s is preferable to %s",
79+
"use-math-not-float",
80+
"Using math.inf or math.nan permits to benefit from typing "
81+
"and it is 4 time faster than a float call.\n"
82+
"Requires 'import math' in the file.",
83+
),
7784
}
7885
options = (
7986
(
@@ -101,14 +108,35 @@ def open(self) -> None:
101108
or self.linter.config.max_line_length
102109
)
103110

104-
@only_required_for_messages("prefer-typing-namedtuple")
111+
@only_required_for_messages("prefer-typing-namedtuple", "use-math-not-float")
105112
def visit_call(self, node: nodes.Call) -> None:
106113
if self._py36_plus:
107114
called = safe_infer(node.func)
108-
if called and called.qname() == "collections.namedtuple":
115+
if not called:
116+
return
117+
if called.qname() == "collections.namedtuple":
109118
self.add_message(
110119
"prefer-typing-namedtuple", node=node, confidence=INFERENCE
111120
)
121+
elif called.qname() == "builtins.float":
122+
if (
123+
node.args
124+
and isinstance(node.args[0], nodes.Const)
125+
and isinstance(node.args[0].value, str)
126+
and any(
127+
c.isalpha() and c.lower() != "e" for c in node.args[0].value
128+
)
129+
):
130+
is_nan = "nan" in node.args[0].value.lower()
131+
minus = (
132+
"-" if not is_nan and node.args[0].value.startswith("-") else ""
133+
)
134+
self.add_message(
135+
"use-math-not-float",
136+
node=node,
137+
args=(minus, "nan" if is_nan else "inf", node.as_string()),
138+
confidence=INFERENCE,
139+
)
112140

113141
@only_required_for_messages("consider-using-namedtuple-or-dataclass")
114142
def visit_dict(self, node: nodes.Dict) -> None:
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""Functional test for use-math-not-float."""
2+
3+
inf_float = float("inf") # [use-math-not-float]
4+
neg_inf_float = float('-inf') # [use-math-not-float]
5+
pos_inf_float = float("+inf") # [use-math-not-float]
6+
infinity_float = float("infinity") # [use-math-not-float]
7+
neg_infinity_float = float("-infinity") # [use-math-not-float]
8+
large_exp_float = float("1e1000")
9+
neg_large_exp_float = float("-1e1000")
10+
very_large_exp_float = float("2.5E9999")
11+
invalid_inf_float = float("in") # [use-math-not-float]
12+
invalid_float_call = float("in", base=10) # [use-math-not-float]
13+
nan_float = float("nan") # [use-math-not-float]
14+
neg_nan_float = float("-nan") # [use-math-not-float]
15+
pos_nan_float = float("+nan") # [use-math-not-float]
16+
upper_nan_float = float("NaN") # [use-math-not-float]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[MAIN]
2+
load-plugins=pylint.extensions.code_style
3+
enable=use-math-not-float
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use-math-not-float:3:12:3:24::math.inf is preferable to float('inf'):INFERENCE
2+
use-math-not-float:4:16:4:29::-math.inf is preferable to float('-inf'):INFERENCE
3+
use-math-not-float:5:16:5:29::math.inf is preferable to float('+inf'):INFERENCE
4+
use-math-not-float:6:17:6:34::math.inf is preferable to float('infinity'):INFERENCE
5+
use-math-not-float:7:21:7:39::-math.inf is preferable to float('-infinity'):INFERENCE
6+
use-math-not-float:11:20:11:31::math.inf is preferable to float('in'):INFERENCE
7+
use-math-not-float:12:21:12:41::math.inf is preferable to float('in', base=10):INFERENCE
8+
use-math-not-float:13:12:13:24::math.nan is preferable to float('nan'):INFERENCE
9+
use-math-not-float:14:16:14:29::math.nan is preferable to float('-nan'):INFERENCE
10+
use-math-not-float:15:16:15:29::math.nan is preferable to float('+nan'):INFERENCE
11+
use-math-not-float:16:18:16:30::math.nan is preferable to float('NaN'):INFERENCE

0 commit comments

Comments
 (0)