1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
from __future__ import annotations
import contextlib
from collections.abc import Callable, Iterator
from typing import Any, Type
import astroid
from astroid import nodes
from astroid.context import InferenceContext
from astroid.manager import AstroidManager
from pylint.checkers import stdlib
from pylint.testutils import CheckerTestCase
_NodeNGT = Type[nodes.NodeNG]
@contextlib.contextmanager
def _add_transform(
manager: AstroidManager,
node: _NodeNGT,
transform: Callable[[_NodeNGT], _NodeNGT],
predicate: Any | None = None,
) -> Iterator[None]:
manager.register_transform(node, transform, predicate)
try:
yield
finally:
manager.unregister_transform(node, transform, predicate)
class TestStdlibChecker(CheckerTestCase):
CHECKER_CLASS = stdlib.StdlibChecker
def test_deprecated_no_qname_on_unexpected_nodes(self) -> None:
"""Test that we don't crash on nodes which don't have a qname method.
While this test might seem weird since it uses a transform, it's actually testing a crash
that happened in production, but there was no way to retrieve the code for which this
occurred (how an AssignAttr got to be the result of a function inference beats me...)
"""
def infer_func(
inner_node: nodes.Name,
context: InferenceContext | None = None, # pylint: disable=unused-argument
) -> Iterator[nodes.AssignAttr]:
new_node = nodes.AssignAttr(
attrname="alpha",
parent=inner_node,
lineno=0,
col_offset=0,
end_lineno=0,
end_col_offset=0,
)
yield new_node
manager = astroid.MANAGER
transform = astroid.inference_tip(infer_func)
with _add_transform(manager, nodes.Name, transform):
node = astroid.extract_node(
"""
call_something()
"""
)
with self.assertNoMessages():
self.checker.visit_call(node)
|