Skip to content

Commit dd80a68

Browse files
Prevent creating Instance that proxies another Instance when inferring __new__(cls) (#1682)
1 parent 3621e2e commit dd80a68

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ Release date: TBA
109109

110110
Closes PyCQA/pylint#7092
111111

112+
* Prevent creating ``Instance`` objects that proxy other ``Instance``s when there is
113+
ambiguity (or user error) in calling ``__new__(cls)``.
114+
115+
Refs PyCQA/pylint#7109
116+
112117

113118
What's New in astroid 2.11.6?
114119
=============================

astroid/bases.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ class Instance(BaseInstance):
293293
# pylint: disable=unnecessary-lambda
294294
special_attributes = lazy_descriptor(lambda: objectmodel.InstanceModel())
295295

296+
def __init__(self, proxied: nodes.ClassDef) -> None:
297+
super().__init__(proxied)
298+
296299
def __repr__(self):
297300
return "<Instance of {}.{} at 0x{}>".format(
298301
self._proxied.root().name, self._proxied.name, id(self)
@@ -434,9 +437,12 @@ def _infer_builtin_new(
434437
return
435438

436439
node_context = context.extra_context.get(caller.args[0])
437-
infer = caller.args[0].infer(context=node_context)
438-
439-
yield from (Instance(x) if x is not Uninferable else x for x in infer) # type: ignore[misc,arg-type]
440+
for inferred in caller.args[0].infer(context=node_context):
441+
if inferred is Uninferable:
442+
yield inferred
443+
if isinstance(inferred, nodes.ClassDef):
444+
yield Instance(inferred)
445+
raise InferenceError
440446

441447
def bool_value(self, context=None):
442448
return True

tests/unittest_inference.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3799,6 +3799,15 @@ def test_builtin_new() -> None:
37993799
with pytest.raises(InferenceError):
38003800
next(ast_node4.infer())
38013801

3802+
ast_node5 = extract_node(
3803+
"""
3804+
class A: pass
3805+
A.__new__(A()) #@
3806+
"""
3807+
)
3808+
with pytest.raises(InferenceError):
3809+
next(ast_node5.infer())
3810+
38023811
@pytest.mark.xfail(reason="Does not support function metaclasses")
38033812
def test_function_metaclasses(self):
38043813
# These are not supported right now, although

0 commit comments

Comments
 (0)