Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,26 @@ public static boolean match(@Nullable PyType expected,
}
}

// PY-85543: Treat typing.NewType instances as their underlying runtime type for assignability checks.
// NewType is only a static marker; at runtime it's the supertype, so unwrap it early.
if (actual instanceof PyTypingNewType typingNewType) {
if (expected instanceof PyTypingNewType && typingNewType.getAncestorTypes(context.context).contains(expected)) {
return Optional.of(true);
}

List<PyClassLikeType> superTypes = typingNewType.getSuperClassTypes(context.context);
if (!superTypes.isEmpty()) {
actual = superTypes.get(0);
}
else {
actual = new PyClassTypeImpl(typingNewType.getPyClass(), typingNewType.isDefinition());
}

if (Objects.equals(expected, actual)) {
return Optional.of(true);
}
}

if (expected instanceof PyClassType) {
Optional<Boolean> match = matchObject((PyClassType)expected, actual);
if (match.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import NewType, Dict, List

KeyValue = NewType('KeyValue', Dict[str, int])

def f(x: KeyValue):
pass

kv = KeyValue({'a': 1})

def g(x: Dict[str, str]):
pass

g(<error descr="Expected type 'dict[str, str]', got 'KeyValue' instead">kv</error>)
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,24 @@ def a_int_b_str(a: int, b: str) -> int:
res4 = twice(a_int_b_str, <warning descr="Expected type 'str', got 'int' instead">b=1</warning>, <warning descr="Expected type 'int', got 'str' instead">a="A"</warning>)""");
}

// PY-85543
public void testNewTypeAcceptedByIntCallInsideFString() {
doTestByText("""
from typing import NewType

MyInt = NewType("MyInt", int)

def test_():
number = MyInt(10)
q = f"{int(number)}"
""");
}

// PY-85543
public void testNewTypeWithGenerics() {
doTest();
}

// PY-50403
public void testFunctionNotEnoughArgumentsToMatchWithParamSpec() {
doTestByText("""
Expand Down