From d2a3bdffa2a73eefc83a3bf894f6e3d997213955 Mon Sep 17 00:00:00 2001
From: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Date: Wed, 22 May 2024 22:07:46 -0700
Subject: [PATCH 1/5] Proposed clarification of spec for int/float/complex
 promotion

---
 .../results/mypy/specialtypes_promotions.toml |  3 ++-
 conformance/results/mypy/version.toml         |  2 +-
 .../results/pyre/specialtypes_promotions.toml |  3 ++-
 conformance/results/pyre/version.toml         |  2 +-
 .../pyright/specialtypes_promotions.toml      |  4 +++-
 conformance/results/pyright/version.toml      |  2 +-
 .../pytype/specialtypes_promotions.toml       |  3 ++-
 conformance/results/pytype/version.toml       |  2 +-
 conformance/results/results.html              |  8 +++----
 conformance/tests/specialtypes_promotions.py  | 21 +++++++++++++---
 docs/spec/special-types.rst                   | 24 +++++++++++++++----
 11 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/conformance/results/mypy/specialtypes_promotions.toml b/conformance/results/mypy/specialtypes_promotions.toml
index 864bc73e..2b3f69bf 100644
--- a/conformance/results/mypy/specialtypes_promotions.toml
+++ b/conformance/results/mypy/specialtypes_promotions.toml
@@ -1,6 +1,7 @@
 conformant = "Pass"
 output = """
-specialtypes_promotions.py:13: error: "float" has no attribute "numerator"  [attr-defined]
+specialtypes_promotions.py:15: error: "float" has no attribute "numerator"  [attr-defined]
+specialtypes_promotions.py:27: error: Incompatible return value type (got "complex", expected "float")  [return-value]
 """
 conformance_automated = "Pass"
 errors_diff = """
diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml
index 268bd31a..1ecd16dc 100644
--- a/conformance/results/mypy/version.toml
+++ b/conformance/results/mypy/version.toml
@@ -1,2 +1,2 @@
 version = "mypy 1.10.0"
-test_duration = 1.4
+test_duration = 1.2
diff --git a/conformance/results/pyre/specialtypes_promotions.toml b/conformance/results/pyre/specialtypes_promotions.toml
index fb9055fb..5763c8b2 100644
--- a/conformance/results/pyre/specialtypes_promotions.toml
+++ b/conformance/results/pyre/specialtypes_promotions.toml
@@ -3,8 +3,9 @@ notes = """
 Does not reject use of attribute that is compatible only with float.
 """
 output = """
+specialtypes_promotions.py:27:8 Incompatible return type [7]: Expected `float` but got `complex`.
 """
 conformance_automated = "Fail"
 errors_diff = """
-Line 13: Expected 1 errors
+Line 15: Expected 1 errors
 """
diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml
index 57ed5696..8156a667 100644
--- a/conformance/results/pyre/version.toml
+++ b/conformance/results/pyre/version.toml
@@ -1,2 +1,2 @@
 version = "pyre 0.9.21"
-test_duration = 3.4
+test_duration = 1.7
diff --git a/conformance/results/pyright/specialtypes_promotions.toml b/conformance/results/pyright/specialtypes_promotions.toml
index 20daf3a3..5d5f8239 100644
--- a/conformance/results/pyright/specialtypes_promotions.toml
+++ b/conformance/results/pyright/specialtypes_promotions.toml
@@ -1,7 +1,9 @@
 conformant = "Pass"
 output = """
-specialtypes_promotions.py:13:7 - error: Cannot access attribute "numerator" for class "float"
+specialtypes_promotions.py:15:7 - error: Cannot access attribute "numerator" for class "float"
   Attribute "numerator" is unknown (reportAttributeAccessIssue)
+specialtypes_promotions.py:27:16 - error: Expression of type "complex" is incompatible with return type "float"
+  "complex" is incompatible with "float" (reportReturnType)
 """
 conformance_automated = "Pass"
 errors_diff = """
diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml
index 6302edbf..e52cbce9 100644
--- a/conformance/results/pyright/version.toml
+++ b/conformance/results/pyright/version.toml
@@ -1,2 +1,2 @@
 version = "pyright 1.1.364"
-test_duration = 1.4
+test_duration = 1.3
diff --git a/conformance/results/pytype/specialtypes_promotions.toml b/conformance/results/pytype/specialtypes_promotions.toml
index dc20943f..2d7fe2a9 100644
--- a/conformance/results/pytype/specialtypes_promotions.toml
+++ b/conformance/results/pytype/specialtypes_promotions.toml
@@ -1,6 +1,7 @@
 conformant = "Pass"
 output = """
-File "specialtypes_promotions.py", line 13, in func1: No attribute 'numerator' on float [attribute-error]
+File "specialtypes_promotions.py", line 15, in func1: No attribute 'numerator' on float [attribute-error]
+File "specialtypes_promotions.py", line 27, in func2: bad return type [bad-return-type]
 """
 conformance_automated = "Pass"
 errors_diff = """
diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml
index 68b8ac60..4dcc8424 100644
--- a/conformance/results/pytype/version.toml
+++ b/conformance/results/pytype/version.toml
@@ -1,2 +1,2 @@
 version = "pytype 2024.04.11"
-test_duration = 30.1
+test_duration = 27.6
diff --git a/conformance/results/results.html b/conformance/results/results.html
index 9693b2e8..003ac143 100644
--- a/conformance/results/results.html
+++ b/conformance/results/results.html
@@ -159,16 +159,16 @@ <h3>Python Type System Conformance Test Results</h3>
         <div class="table_container"><table><tbody>
 <tr><th class="col1">&nbsp;</th>
 <th class='tc-header'><div class='tc-name'>mypy 1.10.0</div>
-<div class='tc-time'>1.4sec</div>
+<div class='tc-time'>1.2sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyright 1.1.364</div>
-<div class='tc-time'>1.4sec</div>
+<div class='tc-time'>1.3sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyre 0.9.21</div>
-<div class='tc-time'>3.4sec</div>
+<div class='tc-time'>1.7sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pytype 2024.04.11</div>
-<div class='tc-time'>30.1sec</div>
+<div class='tc-time'>27.6sec</div>
 </th>
 </tr>
 <tr><th class="column" colspan="5">
diff --git a/conformance/tests/specialtypes_promotions.py b/conformance/tests/specialtypes_promotions.py
index fc51e133..277a05c1 100644
--- a/conformance/tests/specialtypes_promotions.py
+++ b/conformance/tests/specialtypes_promotions.py
@@ -2,6 +2,8 @@
 Tests "type promotions" for float and complex when they appear in annotations.
 """
 
+from typing import assert_type
+
 # Specification: https://typing.readthedocs.io/en/latest/spec/special-types.html#special-cases-for-float-and-complex
 
 v1: float = 1
@@ -10,7 +12,20 @@
 
 
 def func1(f: float):
-    f.numerator  # E
+    f.numerator  # E: attribute exists on int but not float
+
+    if isinstance(f, float):
+        assert_type(f, float)
+    else:
+        assert_type(f, int)
+
 
-    if not isinstance(f, float):
-        f.numerator  # OK
+def func2(x: int) -> float:
+    if x == 0:
+        return 1
+    elif x == 1:
+        return 1j  # E
+    elif x > 10:
+        return x
+    else:
+        return 1.0
diff --git a/docs/spec/special-types.rst b/docs/spec/special-types.rst
index b94222e6..819ffbb5 100644
--- a/docs/spec/special-types.rst
+++ b/docs/spec/special-types.rst
@@ -113,11 +113,25 @@ Special cases for ``float`` and ``complex``
 
 Python's numeric types ``complex``, ``float`` and ``int`` are not
 subtypes of each other, but to support common use cases, the type
-system contains a straightforward shortcut:
-when an argument is annotated as having
-type ``float``, an argument of type ``int`` is acceptable; similar,
-for an argument annotated as having type ``complex``, arguments of
-type ``float`` or ``int`` are acceptable.
+system contains a special case.
+
+When a reference to the built-in type ``float`` appears in a :term:`type expression`,
+it is interpreted as if it were a union of the built-in types ``float`` and ``int``.
+Similarly, when a reference to the type ``complex`` appears, it is interpreted as
+a union of the builtin-types ``complex``, ``float`` and ``int``.
+These implicit unions behave exactly like the corresponding explicit union types,
+but type checkers may choose to display them differently in user-visible output
+for clarity.
+
+Type checkers should support narrowing the type of a variable to exactly ``float``
+or ``int``, without the implicit union, through a call to ``isinstance()``::
+
+  def f(x: float) -> None:
+      reveal_type(x)  # float | int, but type checkers may display just "float"
+      if isinstance(x, float):
+          reveal_type(x)  # float
+      else:
+          reveal_type(x)  # int
 
 .. _`type-brackets`:
 

From cfefa40231f49b7e36ecf4828050eb7c869cf0eb Mon Sep 17 00:00:00 2001
From: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Date: Wed, 22 May 2024 22:09:52 -0700
Subject: [PATCH 2/5] typo

---
 docs/spec/special-types.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/spec/special-types.rst b/docs/spec/special-types.rst
index 819ffbb5..b0339ae0 100644
--- a/docs/spec/special-types.rst
+++ b/docs/spec/special-types.rst
@@ -118,7 +118,7 @@ system contains a special case.
 When a reference to the built-in type ``float`` appears in a :term:`type expression`,
 it is interpreted as if it were a union of the built-in types ``float`` and ``int``.
 Similarly, when a reference to the type ``complex`` appears, it is interpreted as
-a union of the builtin-types ``complex``, ``float`` and ``int``.
+a union of the built-in types ``complex``, ``float`` and ``int``.
 These implicit unions behave exactly like the corresponding explicit union types,
 but type checkers may choose to display them differently in user-visible output
 for clarity.

From cf3486fef90e730e2dc3a364c378677da794e086 Mon Sep 17 00:00:00 2001
From: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Date: Wed, 22 May 2024 22:33:19 -0700
Subject: [PATCH 3/5] remove incorrect case

---
 conformance/results/pyre/version.toml        | 2 +-
 conformance/results/pytype/version.toml      | 2 +-
 conformance/results/results.html             | 4 ++--
 conformance/tests/specialtypes_promotions.py | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml
index 8156a667..8b31620f 100644
--- a/conformance/results/pyre/version.toml
+++ b/conformance/results/pyre/version.toml
@@ -1,2 +1,2 @@
 version = "pyre 0.9.21"
-test_duration = 1.7
+test_duration = 2.3
diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml
index 4dcc8424..2d05bc7f 100644
--- a/conformance/results/pytype/version.toml
+++ b/conformance/results/pytype/version.toml
@@ -1,2 +1,2 @@
 version = "pytype 2024.04.11"
-test_duration = 27.6
+test_duration = 27.3
diff --git a/conformance/results/results.html b/conformance/results/results.html
index 003ac143..9e7655c7 100644
--- a/conformance/results/results.html
+++ b/conformance/results/results.html
@@ -165,10 +165,10 @@ <h3>Python Type System Conformance Test Results</h3>
 <div class='tc-time'>1.3sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyre 0.9.21</div>
-<div class='tc-time'>1.7sec</div>
+<div class='tc-time'>2.3sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pytype 2024.04.11</div>
-<div class='tc-time'>27.6sec</div>
+<div class='tc-time'>27.3sec</div>
 </th>
 </tr>
 <tr><th class="column" colspan="5">
diff --git a/conformance/tests/specialtypes_promotions.py b/conformance/tests/specialtypes_promotions.py
index 277a05c1..410ff4e6 100644
--- a/conformance/tests/specialtypes_promotions.py
+++ b/conformance/tests/specialtypes_promotions.py
@@ -15,7 +15,7 @@ def func1(f: float):
     f.numerator  # E: attribute exists on int but not float
 
     if isinstance(f, float):
-        assert_type(f, float)
+        f.hex()  # OK (attribute exists on float but not int)
     else:
         assert_type(f, int)
 

From 6155dbdc1a4553a31a0340c096309f27e7e7ad90 Mon Sep 17 00:00:00 2001
From: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Date: Thu, 23 May 2024 07:05:59 -0700
Subject: [PATCH 4/5] Extend test

---
 conformance/results/mypy/specialtypes_promotions.toml    | 4 ++--
 conformance/results/mypy/version.toml                    | 2 +-
 conformance/results/pyre/specialtypes_promotions.toml    | 4 ++--
 conformance/results/pyre/version.toml                    | 2 +-
 conformance/results/pyright/specialtypes_promotions.toml | 4 ++--
 conformance/results/pyright/version.toml                 | 2 +-
 conformance/results/pytype/specialtypes_promotions.toml  | 4 ++--
 conformance/results/pytype/version.toml                  | 2 +-
 conformance/results/results.html                         | 8 ++++----
 conformance/tests/specialtypes_promotions.py             | 8 +++++---
 10 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/conformance/results/mypy/specialtypes_promotions.toml b/conformance/results/mypy/specialtypes_promotions.toml
index 2b3f69bf..f1a46655 100644
--- a/conformance/results/mypy/specialtypes_promotions.toml
+++ b/conformance/results/mypy/specialtypes_promotions.toml
@@ -1,7 +1,7 @@
 conformant = "Pass"
 output = """
-specialtypes_promotions.py:15: error: "float" has no attribute "numerator"  [attr-defined]
-specialtypes_promotions.py:27: error: Incompatible return value type (got "complex", expected "float")  [return-value]
+specialtypes_promotions.py:17: error: "float" has no attribute "numerator"  [attr-defined]
+specialtypes_promotions.py:29: error: Incompatible return value type (got "complex", expected "float")  [return-value]
 """
 conformance_automated = "Pass"
 errors_diff = """
diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml
index 1ecd16dc..9c6b57d3 100644
--- a/conformance/results/mypy/version.toml
+++ b/conformance/results/mypy/version.toml
@@ -1,2 +1,2 @@
 version = "mypy 1.10.0"
-test_duration = 1.2
+test_duration = 6.2
diff --git a/conformance/results/pyre/specialtypes_promotions.toml b/conformance/results/pyre/specialtypes_promotions.toml
index 5763c8b2..4d57e8ce 100644
--- a/conformance/results/pyre/specialtypes_promotions.toml
+++ b/conformance/results/pyre/specialtypes_promotions.toml
@@ -3,9 +3,9 @@ notes = """
 Does not reject use of attribute that is compatible only with float.
 """
 output = """
-specialtypes_promotions.py:27:8 Incompatible return type [7]: Expected `float` but got `complex`.
+specialtypes_promotions.py:29:8 Incompatible return type [7]: Expected `float` but got `complex`.
 """
 conformance_automated = "Fail"
 errors_diff = """
-Line 15: Expected 1 errors
+Line 17: Expected 1 errors
 """
diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml
index 8b31620f..47c7ebcc 100644
--- a/conformance/results/pyre/version.toml
+++ b/conformance/results/pyre/version.toml
@@ -1,2 +1,2 @@
 version = "pyre 0.9.21"
-test_duration = 2.3
+test_duration = 2.6
diff --git a/conformance/results/pyright/specialtypes_promotions.toml b/conformance/results/pyright/specialtypes_promotions.toml
index 5d5f8239..da01e5ad 100644
--- a/conformance/results/pyright/specialtypes_promotions.toml
+++ b/conformance/results/pyright/specialtypes_promotions.toml
@@ -1,8 +1,8 @@
 conformant = "Pass"
 output = """
-specialtypes_promotions.py:15:7 - error: Cannot access attribute "numerator" for class "float"
+specialtypes_promotions.py:17:7 - error: Cannot access attribute "numerator" for class "float"
   Attribute "numerator" is unknown (reportAttributeAccessIssue)
-specialtypes_promotions.py:27:16 - error: Expression of type "complex" is incompatible with return type "float"
+specialtypes_promotions.py:29:16 - error: Expression of type "complex" is incompatible with return type "float"
   "complex" is incompatible with "float" (reportReturnType)
 """
 conformance_automated = "Pass"
diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml
index e52cbce9..f2385b55 100644
--- a/conformance/results/pyright/version.toml
+++ b/conformance/results/pyright/version.toml
@@ -1,2 +1,2 @@
 version = "pyright 1.1.364"
-test_duration = 1.3
+test_duration = 1.8
diff --git a/conformance/results/pytype/specialtypes_promotions.toml b/conformance/results/pytype/specialtypes_promotions.toml
index 2d7fe2a9..89270b31 100644
--- a/conformance/results/pytype/specialtypes_promotions.toml
+++ b/conformance/results/pytype/specialtypes_promotions.toml
@@ -1,7 +1,7 @@
 conformant = "Pass"
 output = """
-File "specialtypes_promotions.py", line 15, in func1: No attribute 'numerator' on float [attribute-error]
-File "specialtypes_promotions.py", line 27, in func2: bad return type [bad-return-type]
+File "specialtypes_promotions.py", line 17, in func1: No attribute 'numerator' on float [attribute-error]
+File "specialtypes_promotions.py", line 29, in func2: bad return type [bad-return-type]
 """
 conformance_automated = "Pass"
 errors_diff = """
diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml
index 2d05bc7f..4c23eb4b 100644
--- a/conformance/results/pytype/version.toml
+++ b/conformance/results/pytype/version.toml
@@ -1,2 +1,2 @@
 version = "pytype 2024.04.11"
-test_duration = 27.3
+test_duration = 54.5
diff --git a/conformance/results/results.html b/conformance/results/results.html
index 9e7655c7..e0a66c34 100644
--- a/conformance/results/results.html
+++ b/conformance/results/results.html
@@ -159,16 +159,16 @@ <h3>Python Type System Conformance Test Results</h3>
         <div class="table_container"><table><tbody>
 <tr><th class="col1">&nbsp;</th>
 <th class='tc-header'><div class='tc-name'>mypy 1.10.0</div>
-<div class='tc-time'>1.2sec</div>
+<div class='tc-time'>6.2sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyright 1.1.364</div>
-<div class='tc-time'>1.3sec</div>
+<div class='tc-time'>1.8sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyre 0.9.21</div>
-<div class='tc-time'>2.3sec</div>
+<div class='tc-time'>2.6sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pytype 2024.04.11</div>
-<div class='tc-time'>27.3sec</div>
+<div class='tc-time'>54.5sec</div>
 </th>
 </tr>
 <tr><th class="column" colspan="5">
diff --git a/conformance/tests/specialtypes_promotions.py b/conformance/tests/specialtypes_promotions.py
index 410ff4e6..64e728cf 100644
--- a/conformance/tests/specialtypes_promotions.py
+++ b/conformance/tests/specialtypes_promotions.py
@@ -6,9 +6,11 @@
 
 # Specification: https://typing.readthedocs.io/en/latest/spec/special-types.html#special-cases-for-float-and-complex
 
-v1: float = 1
-v2: complex = 1.2
-v2 = 1
+v1: int = 1
+v2: float = 1
+v3: float = v1
+v4: complex = 1.2
+v4 = 1
 
 
 def func1(f: float):

From a442bfe0353973966b39eb8d2232bebeab38a9a7 Mon Sep 17 00:00:00 2001
From: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Date: Thu, 23 May 2024 07:39:15 -0700
Subject: [PATCH 5/5] Guard against unreachability

---
 conformance/results/mypy/specialtypes_promotions.toml  | 10 +++++++---
 conformance/results/mypy/version.toml                  |  2 +-
 conformance/results/pyre/specialtypes_promotions.toml  |  4 +++-
 conformance/results/pyre/version.toml                  |  2 +-
 .../results/pyright/specialtypes_promotions.toml       |  4 +++-
 conformance/results/pyright/version.toml               |  2 +-
 .../results/pytype/specialtypes_promotions.toml        | 10 +++++++---
 conformance/results/pytype/version.toml                |  2 +-
 conformance/results/results.html                       |  8 ++++----
 conformance/tests/specialtypes_promotions.py           |  6 +++++-
 10 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/conformance/results/mypy/specialtypes_promotions.toml b/conformance/results/mypy/specialtypes_promotions.toml
index f1a46655..04499e86 100644
--- a/conformance/results/mypy/specialtypes_promotions.toml
+++ b/conformance/results/mypy/specialtypes_promotions.toml
@@ -1,8 +1,12 @@
-conformant = "Pass"
+conformant = "Partial"
+notes = """
+Does not narrow from float to int after isinstance() check
+"""
 output = """
 specialtypes_promotions.py:17: error: "float" has no attribute "numerator"  [attr-defined]
-specialtypes_promotions.py:29: error: Incompatible return value type (got "complex", expected "float")  [return-value]
+specialtypes_promotions.py:33: error: Incompatible return value type (got "complex", expected "float")  [return-value]
 """
-conformance_automated = "Pass"
+conformance_automated = "Fail"
 errors_diff = """
+Line 26: Expected 1 errors
 """
diff --git a/conformance/results/mypy/version.toml b/conformance/results/mypy/version.toml
index 9c6b57d3..dc9b55ed 100644
--- a/conformance/results/mypy/version.toml
+++ b/conformance/results/mypy/version.toml
@@ -1,2 +1,2 @@
 version = "mypy 1.10.0"
-test_duration = 6.2
+test_duration = 1.5
diff --git a/conformance/results/pyre/specialtypes_promotions.toml b/conformance/results/pyre/specialtypes_promotions.toml
index 4d57e8ce..f17ad77f 100644
--- a/conformance/results/pyre/specialtypes_promotions.toml
+++ b/conformance/results/pyre/specialtypes_promotions.toml
@@ -1,11 +1,13 @@
 conformant = "Partial"
 notes = """
 Does not reject use of attribute that is compatible only with float.
+Does not narrow from float to int after isinstance() check
 """
 output = """
-specialtypes_promotions.py:29:8 Incompatible return type [7]: Expected `float` but got `complex`.
+specialtypes_promotions.py:33:8 Incompatible return type [7]: Expected `float` but got `complex`.
 """
 conformance_automated = "Fail"
 errors_diff = """
 Line 17: Expected 1 errors
+Line 26: Expected 1 errors
 """
diff --git a/conformance/results/pyre/version.toml b/conformance/results/pyre/version.toml
index 47c7ebcc..1fec89de 100644
--- a/conformance/results/pyre/version.toml
+++ b/conformance/results/pyre/version.toml
@@ -1,2 +1,2 @@
 version = "pyre 0.9.21"
-test_duration = 2.6
+test_duration = 2.9
diff --git a/conformance/results/pyright/specialtypes_promotions.toml b/conformance/results/pyright/specialtypes_promotions.toml
index da01e5ad..560cb119 100644
--- a/conformance/results/pyright/specialtypes_promotions.toml
+++ b/conformance/results/pyright/specialtypes_promotions.toml
@@ -2,7 +2,9 @@ conformant = "Pass"
 output = """
 specialtypes_promotions.py:17:7 - error: Cannot access attribute "numerator" for class "float"
   Attribute "numerator" is unknown (reportAttributeAccessIssue)
-specialtypes_promotions.py:29:16 - error: Expression of type "complex" is incompatible with return type "float"
+specialtypes_promotions.py:26:16 - error: Expression of type "Literal['x']" is incompatible with return type "int"
+  "Literal['x']" is incompatible with "int" (reportReturnType)
+specialtypes_promotions.py:33:16 - error: Expression of type "complex" is incompatible with return type "float"
   "complex" is incompatible with "float" (reportReturnType)
 """
 conformance_automated = "Pass"
diff --git a/conformance/results/pyright/version.toml b/conformance/results/pyright/version.toml
index f2385b55..789c07a2 100644
--- a/conformance/results/pyright/version.toml
+++ b/conformance/results/pyright/version.toml
@@ -1,2 +1,2 @@
 version = "pyright 1.1.364"
-test_duration = 1.8
+test_duration = 1.6
diff --git a/conformance/results/pytype/specialtypes_promotions.toml b/conformance/results/pytype/specialtypes_promotions.toml
index 89270b31..3d6ee073 100644
--- a/conformance/results/pytype/specialtypes_promotions.toml
+++ b/conformance/results/pytype/specialtypes_promotions.toml
@@ -1,8 +1,12 @@
-conformant = "Pass"
+conformant = "Partial"
+notes = """
+Does not narrow from float to int after isinstance() check
+"""
 output = """
 File "specialtypes_promotions.py", line 17, in func1: No attribute 'numerator' on float [attribute-error]
-File "specialtypes_promotions.py", line 29, in func2: bad return type [bad-return-type]
+File "specialtypes_promotions.py", line 33, in func2: bad return type [bad-return-type]
 """
-conformance_automated = "Pass"
+conformance_automated = "Fail"
 errors_diff = """
+Line 26: Expected 1 errors
 """
diff --git a/conformance/results/pytype/version.toml b/conformance/results/pytype/version.toml
index 4c23eb4b..bbfb29cd 100644
--- a/conformance/results/pytype/version.toml
+++ b/conformance/results/pytype/version.toml
@@ -1,2 +1,2 @@
 version = "pytype 2024.04.11"
-test_duration = 54.5
+test_duration = 49.8
diff --git a/conformance/results/results.html b/conformance/results/results.html
index e0a66c34..bc90bed9 100644
--- a/conformance/results/results.html
+++ b/conformance/results/results.html
@@ -159,16 +159,16 @@ <h3>Python Type System Conformance Test Results</h3>
         <div class="table_container"><table><tbody>
 <tr><th class="col1">&nbsp;</th>
 <th class='tc-header'><div class='tc-name'>mypy 1.10.0</div>
-<div class='tc-time'>6.2sec</div>
+<div class='tc-time'>1.5sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyright 1.1.364</div>
-<div class='tc-time'>1.8sec</div>
+<div class='tc-time'>1.6sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pyre 0.9.21</div>
-<div class='tc-time'>2.6sec</div>
+<div class='tc-time'>2.9sec</div>
 </th>
 <th class='tc-header'><div class='tc-name'>pytype 2024.04.11</div>
-<div class='tc-time'>54.5sec</div>
+<div class='tc-time'>49.8sec</div>
 </th>
 </tr>
 <tr><th class="column" colspan="5">
diff --git a/conformance/tests/specialtypes_promotions.py b/conformance/tests/specialtypes_promotions.py
index 64e728cf..0216337d 100644
--- a/conformance/tests/specialtypes_promotions.py
+++ b/conformance/tests/specialtypes_promotions.py
@@ -13,13 +13,17 @@
 v4 = 1
 
 
-def func1(f: float):
+def func1(f: float) -> int:
     f.numerator  # E: attribute exists on int but not float
 
     if isinstance(f, float):
         f.hex()  # OK (attribute exists on float but not int)
+        return 1
     else:
         assert_type(f, int)
+        # Make sure type checkers don't treat this branch as unreachable
+        # and skip checking it.
+        return "x"  # E
 
 
 def func2(x: int) -> float: