diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
index 5ac746146a46..e181ce5cb582 100644
--- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
+++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
@@ -296,6 +296,16 @@ public class PyTypeChecker {
}
}
+ final PyType originalProtocolGenericType = StreamEx
+ .of(Extensions.getExtensions(PyTypeProvider.EP_NAME))
+ .map(provider -> provider.getGenericType(superClass, context.context))
+ .findFirst(Objects::nonNull)
+ .orElse(null);
+
+ // actual was matched against protocol definition above
+ // and here protocol usage is matched against its definition to update substitutions
+ match(expected, originalProtocolGenericType, context);
+
return Optional.of(true);
}
diff --git a/python/testData/inspections/PyTypeCheckerInspection/BuiltinsPy3.py b/python/testData/inspections/PyTypeCheckerInspection/BuiltinsPy3.py
index 61a4a848f026..bb96bf914289 100644
--- a/python/testData/inspections/PyTypeCheckerInspection/BuiltinsPy3.py
+++ b/python/testData/inspections/PyTypeCheckerInspection/BuiltinsPy3.py
@@ -13,4 +13,4 @@ def test_numerics():
divmod(False, False)
divmod(b'foo', 'bar')
pow(False, True)
- round(False, 'foo')
+ round(False, 'foo')
diff --git a/python/testSrc/com/jetbrains/python/Py3TypeTest.java b/python/testSrc/com/jetbrains/python/Py3TypeTest.java
index 67361ae53ea8..e36f164224bb 100644
--- a/python/testSrc/com/jetbrains/python/Py3TypeTest.java
+++ b/python/testSrc/com/jetbrains/python/Py3TypeTest.java
@@ -974,6 +974,18 @@ public class Py3TypeTest extends PyTestCase {
);
}
+ // PY-13750
+ public void testBuiltinRound() {
+ doTest("int", "expr = round(1)");
+ doTest("Union[float, int]", "expr = round(1, 1)");
+
+ doTest("int", "expr = round(1.1)");
+ doTest("Union[float, int]", "expr = round(1.1, 1)");
+
+ doTest("int", "expr = round(True)");
+ doTest("Union[float, int]", "expr = round(True, 1)");
+ }
+
private void doTest(final String expectedType, final String text) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class);
diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java
index 13c0670b6f72..36775cc5492b 100644
--- a/python/testSrc/com/jetbrains/python/PyTypeTest.java
+++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java
@@ -3218,6 +3218,18 @@ public class PyTypeTest extends PyTestCase {
);
}
+ // PY-13750
+ public void testBuiltinRound() {
+ doTest("float", "expr = round(1)");
+ doTest("float", "expr = round(1, 1)");
+
+ doTest("float", "expr = round(1.1)");
+ doTest("float", "expr = round(1.1, 1)");
+
+ doTest("float", "expr = round(True)");
+ doTest("float", "expr = round(True, 1)");
+ }
+
private static List getTypeEvalContexts(@NotNull PyExpression element) {
return ImmutableList.of(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).withTracing(),
TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing());