PY-35190 Fix resolving the register method of ABCMeta

The root cause was introduced in PY-23540 (see cb598c94c5).
Namely, abs.ABCMeta was explicitly filtered out from the list of metaclasses in
`PyClassImpl.getMostDerivedClassType` because for some reason in Typeshed stubs for
Python 2 `basestring`, and hence `str`, uses `ABCMeta` as its metaclass,
which is not true at runtime. It caused a metaclass conflict when inheriting `str`
with another user-defined metaclass (`ABCMeta` and a user metaclass didn't extend
each other), so we didn't detect any metaclass in a class as a result.

I've updated Typeshed stubs for Python 2 manually to process ABCMeta normally.
We don't update these stubs anyway, so these changes won't be lost on a future
Typeshed sync.

GitOrigin-RevId: 680e9fa890d00ea63987f3cf73e636e430685f34
This commit is contained in:
Mikhail Golubev
2024-05-27 19:55:43 -07:00
committed by intellij-monorepo-bot
parent c7d9b3c73e
commit d99a86efeb
4 changed files with 14 additions and 3 deletions

View File

@@ -269,7 +269,7 @@ class complex:
def __hash__(self) -> int: ...
def __nonzero__(self) -> bool: ...
class basestring(metaclass=ABCMeta): ...
class basestring: ...
class unicode(basestring, Sequence[unicode]):
@overload

View File

@@ -269,7 +269,7 @@ class complex:
def __hash__(self) -> int: ...
def __nonzero__(self) -> bool: ...
class basestring(metaclass=ABCMeta): ...
class basestring: ...
class unicode(basestring, Sequence[unicode]):
@overload

View File

@@ -1515,7 +1515,6 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
try {
return classTypes
.stream()
.filter(t -> !PyNames.ABC_META.equals(t.getClassQName()))
.max(
(t1, t2) -> {
if (Objects.equals(t1, t2)) {

View File

@@ -319,4 +319,16 @@ public class Py3UnresolvedReferencesInspectionTest extends PyInspectionTestCase
public void testNoWarningForTypeGetItem() {
doTestByText("expr: type[str]");
}
// PY-35190
public void testABCMetaRegisterMethod() {
doTestByText("""
from abc import ABCMeta
class MyABC(metaclass=ABCMeta):
pass
MyABC.register(str)
""");
}
}