summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Sassoulas <pierre.sassoulas@gmail.com>2021-11-25 16:09:42 +0100
committerGitHub <noreply@github.com>2021-11-25 16:09:42 +0100
commite4a1935d8806657294433dc03c8491dbd45da215 (patch)
tree908546b41fc055f60478dc68e60d4808dbe30b1e
parent07a635cd2109bb4a44bd29078a0b5f9fc6f6bd5d (diff)
downloadpylint-git-e4a1935d8806657294433dc03c8491dbd45da215.tar.gz
Activate and fix existing use-set-for-membership checks (#5379)
* Activate and fix existing use-set-for-membership checks
-rw-r--r--pylint/checkers/base.py16
-rw-r--r--pylint/checkers/classes.py12
-rw-r--r--pylint/checkers/format.py8
-rw-r--r--pylint/checkers/imports.py2
-rw-r--r--pylint/checkers/refactoring/implicit_booleaness_checker.py2
-rw-r--r--pylint/checkers/refactoring/recommendation_checker.py2
-rw-r--r--pylint/checkers/refactoring/refactoring_checker.py12
-rw-r--r--pylint/checkers/similar.py12
-rw-r--r--pylint/checkers/stdlib.py2
-rw-r--r--pylint/checkers/strings.py10
-rw-r--r--pylint/checkers/typecheck.py10
-rw-r--r--pylint/checkers/utils.py6
-rw-r--r--pylint/checkers/variables.py2
-rw-r--r--pylint/config/option.py6
-rw-r--r--pylint/config/options_provider_mixin.py2
-rw-r--r--pylint/extensions/typing.py6
-rw-r--r--pylint/graph.py4
-rw-r--r--pylint/lint/pylinter.py6
-rw-r--r--pylint/utils/pragma_parser.py2
-rw-r--r--pylintrc1
20 files changed, 60 insertions, 63 deletions
diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py
index 36aaa4663..0206b1202 100644
--- a/pylint/checkers/base.py
+++ b/pylint/checkers/base.py
@@ -2251,7 +2251,7 @@ class DocStringChecker(_BasicChecker):
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"
@@ -2386,7 +2386,7 @@ class ComparisonChecker(_BasicChecker):
# 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 {}"
)
@@ -2440,7 +2440,7 @@ class ComparisonChecker(_BasicChecker):
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:
@@ -2540,16 +2540,16 @@ class ComparisonChecker(_BasicChecker):
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):
@@ -2567,7 +2567,7 @@ class ComparisonChecker(_BasicChecker):
):
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)
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py
index d80111db1..10df62448 100644
--- a/pylint/checkers/classes.py
+++ b/pylint/checkers/classes.py
@@ -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
@@ -1002,11 +1002,11 @@ a metaclass class method.",
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
@@ -1130,11 +1130,11 @@ a metaclass class method.",
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):
diff --git a/pylint/checkers/format.py b/pylint/checkers/format.py
index 3756d7d0e..cdbacd4cf 100644
--- a/pylint/checkers/format.py
+++ b/pylint/checkers/format.py
@@ -411,9 +411,9 @@ class FormatChecker(BaseTokenChecker):
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.
@@ -424,7 +424,7 @@ class FormatChecker(BaseTokenChecker):
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
)
@@ -439,7 +439,7 @@ class FormatChecker(BaseTokenChecker):
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.
diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py
index 174c8c8e3..9d05ebbb8 100644
--- a/pylint/checkers/imports.py
+++ b/pylint/checkers/imports.py
@@ -734,7 +734,7 @@ class ImportsChecker(DeprecatedMixin, BaseChecker):
)
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
diff --git a/pylint/checkers/refactoring/implicit_booleaness_checker.py b/pylint/checkers/refactoring/implicit_booleaness_checker.py
index fbcb29536..02e5d8257 100644
--- a/pylint/checkers/refactoring/implicit_booleaness_checker.py
+++ b/pylint/checkers/refactoring/implicit_booleaness_checker.py
@@ -177,7 +177,7 @@ class ImplicitBooleanessChecker(checkers.BaseChecker):
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 = "[]"
diff --git a/pylint/checkers/refactoring/recommendation_checker.py b/pylint/checkers/refactoring/recommendation_checker.py
index 3bccd5fcb..210513ddc 100644
--- a/pylint/checkers/refactoring/recommendation_checker.py
+++ b/pylint/checkers/refactoring/recommendation_checker.py
@@ -106,7 +106,7 @@ class RecommendationChecker(checkers.BaseChecker):
# 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
diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py
index 7929d77e0..7568f3eea 100644
--- a/pylint/checkers/refactoring/refactoring_checker.py
+++ b/pylint/checkers/refactoring/refactoring_checker.py
@@ -833,14 +833,14 @@ class RefactoringChecker(checkers.BaseTokenChecker):
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
)
@@ -963,7 +963,7 @@ class RefactoringChecker(checkers.BaseTokenChecker):
# 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,
@@ -1227,12 +1227,12 @@ class RefactoringChecker(checkers.BaseTokenChecker):
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:
@@ -1482,7 +1482,7 @@ class RefactoringChecker(checkers.BaseTokenChecker):
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":
diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py
index b609cd539..f9cb9edbc 100644
--- a/pylint/checkers/similar.py
+++ b/pylint/checkers/similar.py
@@ -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)
diff --git a/pylint/checkers/stdlib.py b/pylint/checkers/stdlib.py
index d1fc49eb7..f77f7a2b3 100644
--- a/pylint/checkers/stdlib.py
+++ b/pylint/checkers/stdlib.py
@@ -574,7 +574,7 @@ class StdlibChecker(DeprecatedMixin, BaseChecker):
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",
diff --git a/pylint/checkers/strings.py b/pylint/checkers/strings.py
index 3bdc8b196..eb43411de 100644
--- a/pylint/checkers/strings.py
+++ b/pylint/checkers/strings.py
@@ -429,9 +429,9 @@ class StringFormatChecker(BaseChecker):
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
@@ -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]
diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py
index 57c147836..c32b19b6d 100644
--- a/pylint/checkers/typecheck.py
+++ b/pylint/checkers/typecheck.py
@@ -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
@@ -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
@@ -1560,7 +1560,7 @@ accessed. Python regular expressions are accepted.",
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__")
@@ -1603,7 +1603,7 @@ accessed. Python regular expressions are accepted.",
# 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:
@@ -1805,7 +1805,7 @@ accessed. Python regular expressions are accepted.",
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(
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index 9d8e6f9bf..c7f2cec92 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -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)
)
@@ -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":
@@ -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}
)
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index a87f94c65..cfedb56dd 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -2131,7 +2131,7 @@ class VariablesChecker(BaseChecker):
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
diff --git a/pylint/config/option.py b/pylint/config/option.py
index 684c7e894..58547656c 100644
--- a/pylint/config/option.py
+++ b/pylint/config/option.py
@@ -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))
@@ -164,7 +164,7 @@ class Option(optparse.Option):
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
diff --git a/pylint/config/options_provider_mixin.py b/pylint/config/options_provider_mixin.py
index a8526095c..d3872135c 100644
--- a/pylint/config/options_provider_mixin.py
+++ b/pylint/config/options_provider_mixin.py
@@ -56,7 +56,7 @@ class OptionsProviderMixIn:
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)
diff --git a/pylint/extensions/typing.py b/pylint/extensions/typing.py
index 92282b983..01bfe1b28 100644
--- a/pylint/extensions/typing.py
+++ b/pylint/extensions/typing.py
@@ -194,11 +194,7 @@ class TypingChecker(BaseChecker):
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"
):
diff --git a/pylint/graph.py b/pylint/graph.py
index 038db7e4e..70a618678 100644
--- a/pylint/graph.py
+++ b/pylint/graph.py
@@ -64,11 +64,11 @@ class DotBackend:
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))
diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py
index b9bea1bb2..c95aa680e 100644
--- a/pylint/lint/pylinter.py
+++ b/pylint/lint/pylinter.py
@@ -766,7 +766,7 @@ class PyLinter(
def disable_noerror_messages(self):
for msgcat, msgids in self.msgs_store._msgs_by_category.items():
# enable only messages with 'error' severity and above ('fatal')
- if msgcat in ["E", "F"]:
+ if msgcat in {"E", "F"}:
for msgid in msgids:
self.enable(msgid)
else:
@@ -834,7 +834,7 @@ class PyLinter(
continue
try:
for pragma_repr in parse_pragma(match.group(2)):
- if pragma_repr.action in ("disable-all", "skip-file"):
+ if pragma_repr.action in {"disable-all", "skip-file"}:
if pragma_repr.action == "disable-all":
self.add_message(
"deprecated-pragma",
@@ -1597,7 +1597,7 @@ class PyLinter(
ignore_unknown: bool = False,
) -> None:
"""Do some tests and then iterate over message defintions to set state"""
- assert scope in ("package", "module")
+ assert scope in {"package", "module"}
if msgid == "all":
for _msgid in MSG_TYPES:
self._set_msg_status(_msgid, enable, scope, line, ignore_unknown)
diff --git a/pylint/utils/pragma_parser.py b/pylint/utils/pragma_parser.py
index 549519cf7..02ad25493 100644
--- a/pylint/utils/pragma_parser.py
+++ b/pylint/utils/pragma_parser.py
@@ -122,7 +122,7 @@ def parse_pragma(pylint_pragma: str) -> Generator[PragmaRepresenter, None, None]
action = value
messages = []
assignment_required = action in MESSAGE_KEYWORDS
- elif kind in ("MESSAGE_STRING", "MESSAGE_NUMBER"):
+ elif kind in {"MESSAGE_STRING", "MESSAGE_NUMBER"}:
messages.append(value)
assignment_required = False
else:
diff --git a/pylintrc b/pylintrc
index 299867086..3005cc676 100644
--- a/pylintrc
+++ b/pylintrc
@@ -20,6 +20,7 @@ load-plugins=
pylint.extensions.check_elif,
pylint.extensions.bad_builtin,
pylint.extensions.for_any_all,
+ pylint.extensions.set_membership,
pylint.extensions.code_style,
pylint.extensions.overlapping_exceptions,
pylint.extensions.typing,