Skip to content

Commit

Permalink
Added conformance tests for new "Exceptions" chapter. (#1724)
Browse files Browse the repository at this point in the history
* Added conformance tests for new "Exceptions" chapter.

* Incorporated Jelle's PR review feedback.
  • Loading branch information
erictraut committed Apr 23, 2024
1 parent 2535760 commit f7f5723
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 8 deletions.
5 changes: 5 additions & 0 deletions conformance/results/mypy/exceptions_context_managers.toml
@@ -0,0 +1,5 @@
conformant = "Pass"
errors_diff = """
"""
output = """
"""
2 changes: 1 addition & 1 deletion conformance/results/mypy/version.toml
@@ -1,2 +1,2 @@
version = "mypy 1.9.0"
test_duration = 1.5
test_duration = 2.0
6 changes: 6 additions & 0 deletions conformance/results/pyre/exceptions_context_managers.toml
@@ -0,0 +1,6 @@
conformant = "Pass"
conformance_automated = "Pass"
errors_diff = """
"""
output = """
"""
2 changes: 1 addition & 1 deletion conformance/results/pyre/version.toml
@@ -1,2 +1,2 @@
version = "pyre 0.9.19"
test_duration = 3.2
test_duration = 4.1
5 changes: 5 additions & 0 deletions conformance/results/pyright/exceptions_context_managers.toml
@@ -0,0 +1,5 @@
conformant = "Pass"
errors_diff = """
"""
output = """
"""
2 changes: 1 addition & 1 deletion conformance/results/pyright/version.toml
@@ -1,2 +1,2 @@
version = "pyright 1.1.359"
test_duration = 1.5
test_duration = 1.6
13 changes: 13 additions & 0 deletions conformance/results/pytype/exceptions_context_managers.toml
@@ -0,0 +1,13 @@
conformant = "Unsupported"
notes = """
Does not support code flow analysis.
"""
conformance_automated = "Fail"
errors_diff = """
Line 50: Unexpected errors ['File "exceptions_context_managers.py", line 50, in suppress1: str [assert-type]']
Line 57: Unexpected errors ['File "exceptions_context_managers.py", line 57, in suppress2: str [assert-type]']
"""
output = """
File "exceptions_context_managers.py", line 50, in suppress1: str [assert-type]
File "exceptions_context_managers.py", line 57, in suppress2: str [assert-type]
"""
2 changes: 1 addition & 1 deletion conformance/results/pytype/version.toml
@@ -1,2 +1,2 @@
version = "pytype 2024.04.11"
test_duration = 35.1
test_duration = 35.0
17 changes: 13 additions & 4 deletions conformance/results/results.html
Expand Up @@ -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.9.0</div>
<div class='tc-time'>1.5sec</div>
<div class='tc-time'>2.0sec</div>
</th>
<th class='tc-header'><div class='tc-name'>pyright 1.1.359</div>
<div class='tc-time'>1.5sec</div>
<div class='tc-time'>1.6sec</div>
</th>
<th class='tc-header'><div class='tc-name'>pyre 0.9.19</div>
<div class='tc-time'>3.2sec</div>
<div class='tc-time'>4.1sec</div>
</th>
<th class='tc-header'><div class='tc-name'>pytype 2024.04.11</div>
<div class='tc-time'>35.1sec</div>
<div class='tc-time'>35.0sec</div>
</th>
</tr>
<tr><th class="column" colspan="5">
Expand Down Expand Up @@ -667,6 +667,15 @@ <h3>Python Type System Conformance Test Results</h3>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not reject a function with a single @overload signature.</p><p>Does not reject a function with @overload signature but no implementation.</p></span></div></th>
</tr>
<tr><th class="column" colspan="5">
<a class="test_group" href="https://typing.readthedocs.io/en/latest/spec/exceptions.html">Exceptions</a>
</th></tr>
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceptions_context_managers</th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 not-conformant"><div class="hover-text">Unsupported<span class="tooltip-text" id="bottom"><p>Does not support code flow analysis.</p></span></div></th>
<th class="column col2 not-conformant"><div class="hover-text">Unsupported<span class="tooltip-text" id="bottom"><p>Does not support code flow analysis.</p></span></div></th>
</tr>
<tr><th class="column" colspan="5">
<a class="test_group" href="https://typing.readthedocs.io/en/latest/spec/dataclasses.html">Dataclasses</a>
</th></tr>
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dataclasses_descriptors</th>
Expand Down
4 changes: 4 additions & 0 deletions conformance/src/test_groups.toml
Expand Up @@ -47,6 +47,10 @@ href = "https://typing.readthedocs.io/en/latest/spec/constructors.html"
name = "Overloads"
href = "https://typing.readthedocs.io/en/latest/spec/overload.html"

[exceptions]
name = "Exceptions"
href = "https://typing.readthedocs.io/en/latest/spec/exceptions.html"

[dataclasses]
name = "Dataclasses"
href = "https://typing.readthedocs.io/en/latest/spec/dataclasses.html"
Expand Down
85 changes: 85 additions & 0 deletions conformance/tests/exceptions_context_managers.py
@@ -0,0 +1,85 @@
"""
Tests the handling of __exit__ return types for context managers.
"""

# Specification: https://typing.readthedocs.io/en/latest/spec/exceptions.html


from typing import Any, Literal, assert_type


class CMBase:
def __enter__(self) -> None:
pass


class Suppress1(CMBase):
def __exit__(self, exc_type, exc_value, traceback) -> bool:
return True


class Suppress2(CMBase):
def __exit__(self, exc_type, exc_value, traceback) -> Literal[True]:
return True


class NoSuppress1(CMBase):
def __exit__(self, exc_type, exc_value, traceback) -> None:
return None


class NoSuppress2(CMBase):
def __exit__(self, exc_type, exc_value, traceback) -> Literal[False]:
return False


class NoSuppress3(CMBase):
def __exit__(self, exc_type, exc_value, traceback) -> Any:
return False


class NoSuppress4(CMBase):
def __exit__(self, exc_type, exc_value, traceback) -> None | bool:
return None


def suppress1(x: int | str) -> None:
if isinstance(x, int):
with Suppress1():
raise ValueError
assert_type(x, int | str)


def suppress2(x: int | str) -> None:
if isinstance(x, int):
with Suppress2():
raise ValueError
assert_type(x, int | str)


def no_suppress1(x: int | str) -> None:
if isinstance(x, int):
with NoSuppress1():
raise ValueError
assert_type(x, str)


def no_suppress2(x: int | str) -> None:
if isinstance(x, int):
with NoSuppress2():
raise ValueError
assert_type(x, str)


def no_suppress3(x: int | str) -> None:
if isinstance(x, int):
with NoSuppress3():
raise ValueError
assert_type(x, str)


def no_suppress4(x: int | str) -> None:
if isinstance(x, int):
with NoSuppress4():
raise ValueError
assert_type(x, str)

0 comments on commit f7f5723

Please sign in to comment.