Skip to content

Commit

Permalink
Activate and fix existing use-set-for-membership checks (#5379)
Browse files Browse the repository at this point in the history
* Activate and fix existing use-set-for-membership checks
  • Loading branch information
Pierre-Sassoulas committed Nov 25, 2021
1 parent 07a635c commit e4a1935
Show file tree
Hide file tree
Showing 20 changed files with 60 additions and 63 deletions.
16 changes: 8 additions & 8 deletions pylint/checkers/base.py
Expand Up @@ -2251,7 +2251,7 @@ def _check_docstring(
func.bound, astroid.Instance
):
# Strings.
if func.bound.name in ("str", "unicode", "bytes"):
if func.bound.name in {"str", "unicode", "bytes"}:
return
if node_type == "module":
message = "missing-module-docstring"
Expand Down Expand Up @@ -2386,7 +2386,7 @@ def _is_singleton_const(node) -> bool:

# True/False singletons have a special-cased message in case the user is
# mistakenly using == or != to check for truthiness
if singleton in (True, False):
if singleton in {True, False}:
suggestion_template = (
"{} if checking for the singleton value {}, or {} if testing for {}"
)
Expand Down Expand Up @@ -2440,7 +2440,7 @@ def _is_float_nan(node):
def _is_numpy_nan(node):
if isinstance(node, nodes.Attribute) and node.attrname == "NaN":
if isinstance(node.expr, nodes.Name):
return node.expr.name in ("numpy", "nmp", "np")
return node.expr.name in {"numpy", "nmp", "np"}
return False

def _is_nan(node) -> bool:
Expand Down Expand Up @@ -2540,16 +2540,16 @@ def visit_compare(self, node: nodes.Compare) -> None:
left = node.left
operator, right = node.ops[0]

if operator in ("==", "!="):
if operator in {"==", "!="}:
self._check_singleton_comparison(
left, right, node, checking_for_absence=operator == "!="
)

if operator in ("==", "!=", "is", "is not"):
if operator in {"==", "!=", "is", "is not"}:
self._check_nan_comparison(
left, right, node, checking_for_absence=operator in ("!=", "is not")
left, right, node, checking_for_absence=operator in {"!=", "is not"}
)
if operator in ("is", "is not"):
if operator in {"is", "is not"}:
self._check_literal_comparison(right, node)

def _check_unidiomatic_typecheck(self, node):
Expand All @@ -2567,7 +2567,7 @@ def _check_type_x_is_y(self, node, left, operator, right):
):
return

if operator in ("is", "is not") and _is_one_arg_pos_call(right):
if operator in {"is", "is not"} and _is_one_arg_pos_call(right):
right_func = utils.safe_infer(right.func)
if (
isinstance(right_func, nodes.ClassDef)
Expand Down
12 changes: 6 additions & 6 deletions pylint/checkers/classes.py
Expand Up @@ -178,7 +178,7 @@ def _definition_equivalent_to_call(definition, call):

def _positional_parameters(method):
positional = method.args.args
if method.type in ("classmethod", "method"):
if method.type in {"classmethod", "method"}:
positional = positional[1:]
return positional

Expand Down Expand Up @@ -1002,11 +1002,11 @@ def _check_unused_private_attributes(self, node: nodes.ClassDef) -> None:

if (
assign_attr.expr.name
in [
in {
"cls",
node.name,
]
and attribute.expr.name in ["cls", "self", node.name]
}
and attribute.expr.name in {"cls", "self", node.name}
):
# If assigned to cls or class name, can be accessed by cls/self/class name
break
Expand Down Expand Up @@ -1130,11 +1130,11 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None:

if node.decorators:
for decorator in node.decorators.nodes:
if isinstance(decorator, nodes.Attribute) and decorator.attrname in (
if isinstance(decorator, nodes.Attribute) and decorator.attrname in {
"getter",
"setter",
"deleter",
):
}:
# attribute affectation will call this method, not hiding it
return
if isinstance(decorator, nodes.Name):
Expand Down
8 changes: 4 additions & 4 deletions pylint/checkers/format.py
Expand Up @@ -411,9 +411,9 @@ def _check_keyword_parentheses(
contains_double_parens -= 1
continue
# ')' can't happen after if (foo), since it would be a syntax error.
if tokens[i + 1].string in (":", ")", "]", "}", "in") or tokens[
if tokens[i + 1].string in {":", ")", "]", "}", "in"} or tokens[
i + 1
].type in (tokenize.NEWLINE, tokenize.ENDMARKER, tokenize.COMMENT):
].type in {tokenize.NEWLINE, tokenize.ENDMARKER, tokenize.COMMENT}:
if contains_walrus_operator and walrus_operator_depth - 1 == depth:
return
# The empty tuple () is always accepted.
Expand All @@ -424,7 +424,7 @@ def _check_keyword_parentheses(
self.add_message(
"superfluous-parens", line=line_num, args=keyword_token
)
elif keyword_token in ("return", "yield"):
elif keyword_token in {"return", "yield"}:
self.add_message(
"superfluous-parens", line=line_num, args=keyword_token
)
Expand All @@ -439,7 +439,7 @@ def _check_keyword_parentheses(
return
# 'and' and 'or' are the only boolean operators with lower precedence
# than 'not', so parens are only required when they are found.
if token[1] in ("and", "or"):
if token[1] in {"and", "or"}:
found_and_or = True
# A yield inside an expression must always be in parentheses,
# quit early without error.
Expand Down
2 changes: 1 addition & 1 deletion pylint/checkers/imports.py
Expand Up @@ -734,7 +734,7 @@ def _check_imports_order(self, _module_node):
)
import_category = isort_driver.place_module(package)
node_and_package_import = (node, package)
if import_category in ("FUTURE", "STDLIB"):
if import_category in {"FUTURE", "STDLIB"}:
std_imports.append(node_and_package_import)
wrong_import = (
third_party_not_ignored
Expand Down
2 changes: 1 addition & 1 deletion pylint/checkers/refactoring/implicit_booleaness_checker.py
Expand Up @@ -177,7 +177,7 @@ def _check_use_implicit_booleaness_not_comparison(
continue

# No need to check for operator when visiting compare node
if operator in ("==", "!=", ">=", ">", "<=", "<"):
if operator in {"==", "!=", ">=", ">", "<=", "<"}:
collection_literal = "{}"
if isinstance(literal_node, nodes.List):
collection_literal = "[]"
Expand Down
2 changes: 1 addition & 1 deletion pylint/checkers/refactoring/recommendation_checker.py
Expand Up @@ -106,7 +106,7 @@ def _check_use_maxsplit_arg(self, node: nodes.Call) -> None:
# Check if call is split() or rsplit()
if not (
isinstance(node.func, nodes.Attribute)
and node.func.attrname in ("split", "rsplit")
and node.func.attrname in {"split", "rsplit"}
and isinstance(utils.safe_infer(node.func), astroid.BoundMethod)
):
return
Expand Down
12 changes: 6 additions & 6 deletions pylint/checkers/refactoring/refactoring_checker.py
Expand Up @@ -833,14 +833,14 @@ def _check_consider_using_min_max_builtin(self, node: nodes.If):
if right_statement_value != body_value:
return

if operator in ("<", "<="):
if operator in {"<", "<="}:
reduced_to = "{target} = max({target}, {item})".format(
target=target_assignation, item=body_value
)
self.add_message(
"consider-using-max-builtin", node=node, args=(reduced_to,)
)
elif operator in (">", ">="):
elif operator in {">", ">="}:
reduced_to = "{target} = min({target}, {item})".format(
target=target_assignation, item=body_value
)
Expand Down Expand Up @@ -963,7 +963,7 @@ def _check_consider_using_generator(self, node):
# remove square brackets '[]'
inside_comp = node.args[0].as_string()[1:-1]
call_name = node.func.name
if call_name in ["any", "all"]:
if call_name in {"any", "all"}:
self.add_message(
"use-a-generator",
node=node,
Expand Down Expand Up @@ -1227,12 +1227,12 @@ def _find_lower_upper_bounds(comparison_node, uses):
if value is None:
continue

if operator in ("<", "<="):
if operator in {"<", "<="}:
if operand is left_operand:
uses[value]["lower_bound"].add(comparison_node)
elif operand is right_operand:
uses[value]["upper_bound"].add(comparison_node)
elif operator in (">", ">="):
elif operator in {">", ">="}:
if operand is left_operand:
uses[value]["upper_bound"].add(comparison_node)
elif operand is right_operand:
Expand Down Expand Up @@ -1482,7 +1482,7 @@ def _check_consider_using_with(self, node: nodes.Call):

def _check_use_list_or_dict_literal(self, node: nodes.Call) -> None:
"""Check if empty list or dict is created by using the literal [] or {}"""
if node.as_string() in ("list()", "dict()"):
if node.as_string() in {"list()", "dict()"}:
inferred = utils.safe_infer(node.func)
if isinstance(inferred, nodes.ClassDef) and not node.args:
if inferred.qname() == "builtins.list":
Expand Down
12 changes: 6 additions & 6 deletions pylint/checkers/similar.py
Expand Up @@ -916,17 +916,17 @@ def Run(argv=None):
ignore_signatures = False
opts, args = getopt(argv, s_opts, l_opts)
for opt, val in opts:
if opt in ("-d", "--duplicates"):
if opt in {"-d", "--duplicates"}:
min_lines = int(val)
elif opt in ("-h", "--help"):
elif opt in {"-h", "--help"}:
usage()
elif opt in ("-i", "--ignore-comments"):
elif opt in {"-i", "--ignore-comments"}:
ignore_comments = True
elif opt in ("--ignore-docstrings",):
elif opt in {"--ignore-docstrings"}:
ignore_docstrings = True
elif opt in ("--ignore-imports",):
elif opt in {"--ignore-imports"}:
ignore_imports = True
elif opt in ("--ignore-signatures",):
elif opt in {"--ignore-signatures"}:
ignore_signatures = True
if not args:
usage(1)
Expand Down
2 changes: 1 addition & 1 deletion pylint/checkers/stdlib.py
Expand Up @@ -574,7 +574,7 @@ def _check_redundant_assert(self, node, infer):
isinstance(infer, astroid.BoundMethod)
and node.args
and isinstance(node.args[0], nodes.Const)
and infer.name in ["assertTrue", "assertFalse"]
and infer.name in {"assertTrue", "assertFalse"}
):
self.add_message(
"redundant-unittest-assert",
Expand Down
10 changes: 5 additions & 5 deletions pylint/checkers/strings.py
Expand Up @@ -429,9 +429,9 @@ def visit_call(self, node: nodes.Call) -> None:
if (
isinstance(func, astroid.BoundMethod)
and isinstance(func.bound, astroid.Instance)
and func.bound.name in ("str", "unicode", "bytes")
and func.bound.name in {"str", "unicode", "bytes"}
):
if func.name in ("strip", "lstrip", "rstrip") and node.args:
if func.name in {"strip", "lstrip", "rstrip"} and node.args:
arg = utils.safe_infer(node.args[0])
if not isinstance(arg, nodes.Const) or not isinstance(arg.value, str):
return
Expand Down Expand Up @@ -942,11 +942,11 @@ def str_eval(token):
We have to support all string literal notations:
https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
"""
if token[0:2].lower() in ("fr", "rf"):
if token[0:2].lower() in {"fr", "rf"}:
token = token[2:]
elif token[0].lower() in ("r", "u", "f"):
elif token[0].lower() in {"r", "u", "f"}:
token = token[1:]
if token[0:3] in ('"""', "'''"):
if token[0:3] in {'"""', "'''"}:
return token[3:-3]
return token[1:-1]

Expand Down
10 changes: 5 additions & 5 deletions pylint/checkers/typecheck.py
Expand Up @@ -486,7 +486,7 @@ def _emit_no_member(
return False
if metaclass:
# Renamed in Python 3.10 to `EnumType`
return metaclass.qname() in ("enum.EnumMeta", "enum.EnumType")
return metaclass.qname() in {"enum.EnumMeta", "enum.EnumType"}
return False
if not has_known_bases(owner):
return False
Expand Down Expand Up @@ -525,7 +525,7 @@ def _emit_no_member(
and isinstance(owner.parent, nodes.ClassDef)
and owner.parent.name == "EnumMeta"
and owner_name == "__members__"
and node.attrname in ["items", "values", "keys"]
and node.attrname in {"items", "values", "keys"}
):
# Avoid false positive on Enum.__members__.{items(), values, keys}
# See https://github.com/PyCQA/pylint/issues/4123
Expand Down Expand Up @@ -1560,7 +1560,7 @@ def _check_invalid_sequence_index(self, subscript: nodes.Subscript):
return None
# Instance values must be int, slice, or have an __index__ method
elif isinstance(index_type, astroid.Instance):
if index_type.pytype() in ("builtins.int", "builtins.slice"):
if index_type.pytype() in {"builtins.int", "builtins.slice"}:
return None
try:
index_type.getattr("__index__")
Expand Down Expand Up @@ -1603,7 +1603,7 @@ def _check_invalid_slice_index(self, node: nodes.Slice) -> None:
# Instance values must be of type int, None or an object
# with __index__
elif isinstance(index_type, astroid.Instance):
if index_type.pytype() in ("builtins.int", "builtins.NoneType"):
if index_type.pytype() in {"builtins.int", "builtins.NoneType"}:
continue

try:
Expand Down Expand Up @@ -1805,7 +1805,7 @@ def visit_compare(self, node: nodes.Compare) -> None:
return

op, right = node.ops[0]
if op in ["in", "not in"]:
if op in {"in", "not in"}:
self._check_membership_test(right)

@check_messages(
Expand Down
6 changes: 3 additions & 3 deletions pylint/checkers/utils.py
Expand Up @@ -730,7 +730,7 @@ def inherit_from_std_ex(node: nodes.NodeNG) -> bool:
"""
ancestors = node.ancestors() if hasattr(node, "ancestors") else []
return any(
ancestor.name in ("Exception", "BaseException")
ancestor.name in {"Exception", "BaseException"}
and ancestor.root().name == EXCEPTIONS_MODULE
for ancestor in itertools.chain([node], ancestors)
)
Expand Down Expand Up @@ -802,7 +802,7 @@ def is_property_setter_or_deleter(node: nodes.FunctionDef) -> bool:
def _is_property_decorator(decorator: nodes.Name) -> bool:
for inferred in decorator.infer():
if isinstance(inferred, nodes.ClassDef):
if inferred.qname() in ("builtins.property", "functools.cached_property"):
if inferred.qname() in {"builtins.property", "functools.cached_property"}:
return True
for ancestor in inferred.ancestors():
if ancestor.name == "property" and ancestor.root().name == "builtins":
Expand Down Expand Up @@ -1688,5 +1688,5 @@ def returns_bool(node: nodes.NodeNG) -> bool:
return (
isinstance(node, nodes.Return)
and isinstance(node.value, nodes.Const)
and node.value.value in (True, False)
and node.value.value in {True, False}
)
2 changes: 1 addition & 1 deletion pylint/checkers/variables.py
Expand Up @@ -2131,7 +2131,7 @@ def _check_all(self, node: nodes.Module, not_consumed):
assigned = next(node.igetattr("__all__"))
if assigned is astroid.Uninferable:
return
if not assigned.pytype() in ["builtins.list", "builtins.tuple"]:
if not assigned.pytype() in {"builtins.list", "builtins.tuple"}:
line, col = assigned.tolineno, assigned.col_offset
self.add_message("invalid-all-format", line=line, col_offset=col, node=node)
return
Expand Down
6 changes: 3 additions & 3 deletions pylint/config/option.py
Expand Up @@ -52,9 +52,9 @@ def _yn_validator(opt, _, value):
return bool(value)
if isinstance(value, str):
value = value.lower()
if value in ("y", "yes", "true"):
if value in {"y", "yes", "true"}:
return True
if value in ("n", "no", "false"):
if value in {"n", "no", "false"}:
return False
msg = "option %s: invalid yn value %r, should be in (y, yes, true, n, no, false)"
raise optparse.OptionValueError(msg % (opt, value))
Expand Down Expand Up @@ -164,7 +164,7 @@ def __init__(self, *opts, **attrs):
self.help = optparse.SUPPRESS_HELP

def _check_choice(self):
if self.type in ("choice", "multiple_choice"):
if self.type in {"choice", "multiple_choice"}:
if self.choices is None:
raise optparse.OptionError(
"must supply a list of choices for type 'choice'", self
Expand Down
2 changes: 1 addition & 1 deletion pylint/config/options_provider_mixin.py
Expand Up @@ -56,7 +56,7 @@ def set_option(self, optname, value, action=None, optdict=None):
action = optdict.get("action", "store")
if action == "store":
setattr(self.config, self.option_attrname(optname, optdict), value)
elif action in ("store_true", "count"):
elif action in {"store_true", "count"}:
setattr(self.config, self.option_attrname(optname, optdict), 0)
elif action == "store_false":
setattr(self.config, self.option_attrname(optname, optdict), 1)
Expand Down
6 changes: 1 addition & 5 deletions pylint/extensions/typing.py
Expand Up @@ -194,11 +194,7 @@ def _check_for_alternative_union_syntax(
inferred = safe_infer(node)
if not (
isinstance(inferred, nodes.FunctionDef)
and inferred.qname()
in (
"typing.Optional",
"typing.Union",
)
and inferred.qname() in {"typing.Optional", "typing.Union"}
or isinstance(inferred, astroid.bases.Instance)
and inferred.qname() == "typing._SpecialForm"
):
Expand Down
4 changes: 2 additions & 2 deletions pylint/graph.py
Expand Up @@ -64,11 +64,11 @@ def __init__(
if size:
self.emit(f'size="{size}"')
if charset:
assert charset.lower() in (
assert charset.lower() in {
"utf-8",
"iso-8859-1",
"latin1",
), f"unsupported charset {charset}"
}, f"unsupported charset {charset}"
self.emit(f'charset="{charset}"')
for param in additional_param.items():
self.emit("=".join(param))
Expand Down

0 comments on commit e4a1935

Please sign in to comment.