From c636077e2cb0652236bd26839603dc84bb72776a Mon Sep 17 00:00:00 2001 From: erichang-bcad <50524807+erichang-bcad@users.noreply.github.com> Date: Wed, 17 Feb 2021 04:35:35 +0800 Subject: [PATCH] make sure float infinity/NaN does not trigger B008 (#155) Co-authored-by: Eric Chang --- bugbear.py | 30 +++++++++++++++++++++++++++++- tests/b006_b008.py | 32 ++++++++++++++++++++++++++++++++ tests/test_bugbear.py | 2 ++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/bugbear.py b/bugbear.py index 7cb4d08..aeed4b3 100644 --- a/bugbear.py +++ b/bugbear.py @@ -3,6 +3,7 @@ import itertools import logging import re +import sys from collections import namedtuple from contextlib import suppress from functools import lru_cache, partial @@ -350,7 +351,34 @@ def check_for_b006(self, node): if call_path in B006.mutable_calls: self.errors.append(B006(default.lineno, default.col_offset)) elif call_path not in B008.immutable_calls: - self.errors.append(B008(default.lineno, default.col_offset)) + # Check if function call is actually a float infinity/NaN literal + if call_path == "float" and len(default.args) == 1: + float_arg = default.args[0] + if sys.version_info < (3, 8, 0): + # NOTE: pre-3.8, string literals are represented with ast.Str + if isinstance(float_arg, ast.Str): + str_val = float_arg.s + else: + str_val = "" + else: + # NOTE: post-3.8, string literals are represented with ast.Constant + if isinstance(float_arg, ast.Constant): + str_val = float_arg.value + if not isinstance(str_val, str): + str_val = "" + else: + str_val = "" + + # NOTE: regex derived from documentation at: + # https://docs.python.org/3/library/functions.html#float + inf_nan_regex = r"^[+-]?(inf|infinity|nan)$" + re_result = re.search(inf_nan_regex, str_val.lower()) + is_float_literal = re_result is not None + else: + is_float_literal = False + + if not is_float_literal: + self.errors.append(B008(default.lineno, default.col_offset)) def check_for_b007(self, node): targets = NameFinder() diff --git a/tests/b006_b008.py b/tests/b006_b008.py index 99a18dc..e60e968 100644 --- a/tests/b006_b008.py +++ b/tests/b006_b008.py @@ -66,3 +66,35 @@ def kwonlyargs_immutable(*, value=()): def kwonlyargs_mutable(*, value=[]): ... + + +def float_inf_okay(value=float("inf")): + pass + + +def float_infinity_okay(value=float("infinity")): + pass + + +def float_plus_infinity_okay(value=float("+infinity")): + pass + + +def float_minus_inf_okay(value=float("-inf")): + pass + + +def float_nan_okay(value=float("nan")): + pass + + +def float_minus_NaN_okay(value=float("-NaN")): + pass + + +def float_int_is_wrong(value=float(3)): + pass + + +def float_str_not_inf_or_nan_is_wrong(value=float("3.14")): + pass diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index e95299f..d08dc11 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -104,6 +104,8 @@ def test_b006_b008(self): B006(42, 31), B008(51, 38), B006(67, 32), + B008(95, 29), + B008(99, 44), ), )