Path 1: 10 calls (0.45)

Call (10)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)
            

Path 2: 5 calls (0.23)

Call (5)

AttributeInferenceError (5)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)
            

Path 3: 2 calls (0.09)

Call (2)

None (2)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)
            

Path 4: 2 calls (0.09)

Call (2)

None (2)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)
            

Path 5: 1 calls (0.05)

Call (1)

NoSuchArgumentError (1)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)
            

Path 6: 1 calls (0.05)

Call (1)

None (1)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)
            

Path 7: 1 calls (0.05)

Call (1)

AttributeInferenceError (1)

1def _check_reversed(self, node: nodes.Call) -> None:
2        """Check that the argument to `reversed` is a sequence."""
3        try:
4            argument = utils.safe_infer(utils.get_argument_from_call(node, position=0))
5        except utils.NoSuchArgumentError:
6            pass
7        else:
8            if argument is astroid.Uninferable:
9                return
10            if argument is None:
11                # Nothing was inferred.
12                # Try to see if we have iter().
13                if isinstance(node.args[0], nodes.Call):
14                    try:
15                        func = next(node.args[0].func.infer())
16                    except astroid.InferenceError:
17                        return
18                    if getattr(
19                        func, "name", None
20                    ) == "iter" and utils.is_builtin_object(func):
21                        self.add_message("bad-reversed-sequence", node=node)
22                return
23
24            if isinstance(argument, (nodes.List, nodes.Tuple)):
25                return
26
27            # dicts are reversible, but only from Python 3.8 onward. Prior to
28            # that, any class based on dict must explicitly provide a
29            # __reversed__ method
30            if not self._py38_plus and isinstance(argument, astroid.Instance):
31                if any(
32                    ancestor.name == "dict" and utils.is_builtin_object(ancestor)
33                    for ancestor in itertools.chain(
34                        (argument._proxied,), argument._proxied.ancestors()
35                    )
36                ):
37                    try:
38                        argument.locals[REVERSED_PROTOCOL_METHOD]
39                    except KeyError:
40                        self.add_message("bad-reversed-sequence", node=node)
41                    return
42
43            if hasattr(argument, "getattr"):
44                # everything else is not a proper sequence for reversed()
45                for methods in REVERSED_METHODS:
46                    for meth in methods:
47                        try:
48                            argument.getattr(meth)
49                        except astroid.NotFoundError:
50                            break
51                    else:
52                        break
53                else:
54                    self.add_message("bad-reversed-sequence", node=node)
55            else:
56                self.add_message("bad-reversed-sequence", node=node)