Skip to content

Commit 0b5e15e

Browse files
Support contextlib.suppress
ghstack-source-id: e9f3f07 Pull Request resolved: #147990
1 parent 2c76d5a commit 0b5e15e

11 files changed

+75
-18
lines changed

test/dynamo/test_ctx_manager.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,17 +2637,15 @@ def f(x):
26372637
self.assertEqual(expected, out)
26382638
self.assertEqual(len(eager.graphs), 2)
26392639

2640-
@parametrize("name", ("suppress", "stdout", "stderr"))
2640+
@parametrize("name", ("stdout", "stderr"))
26412641
def test_contextlib_suppress(self, name):
26422642
counters.clear()
26432643
eager = EagerAndRecordGraphs()
26442644

26452645
def fn(t):
26462646
y = t.sin()
26472647
# ensure we graph break on the suppress call below
2648-
if name == "suppress":
2649-
ctx = contextlib.suppress(ValueError)
2650-
elif name == "stdout":
2648+
if name == "stdout":
26512649
ctx = contextlib.redirect_stdout(sys.stderr)
26522650
else:
26532651
ctx = contextlib.redirect_stderr(sys.stdout)

test/dynamo/test_exitstack.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
import traceback
55
import unittest
6-
from contextlib import contextmanager, ExitStack
6+
from contextlib import contextmanager, ExitStack, suppress
77

88
import torch
99
import torch._dynamo.test_case
@@ -602,6 +602,63 @@ class CPythonTestExitStack(
602602
]
603603

604604

605+
class CPythonTestSuppress(torch._dynamo.test_case.CPythonTestCase):
606+
# Tests taken from CPython source code in cpython/Lib/test/test_contextlib.py
607+
# https://github.com/python/cpython/blob/v3.13.1/Lib/test/test_contextlib.py
608+
@make_dynamo_test
609+
def test_no_result_from_enter(self):
610+
with suppress(ValueError) as enter_result:
611+
self.assertIsNone(enter_result)
612+
613+
@make_dynamo_test
614+
def test_no_exception(self):
615+
with suppress(ValueError):
616+
self.assertEqual(pow(2, 5), 32)
617+
618+
@make_dynamo_test
619+
def test_exact_exception(self):
620+
with suppress(TypeError):
621+
raise TypeError
622+
623+
@make_dynamo_test
624+
def test_exception_hierarchy(self):
625+
with suppress(LookupError):
626+
"Hello"[50]
627+
628+
@make_dynamo_test
629+
def test_other_exception(self):
630+
with self.assertRaises(ZeroDivisionError):
631+
with suppress(TypeError):
632+
raise ZeroDivisionError
633+
634+
@make_dynamo_test
635+
def test_no_args(self):
636+
with self.assertRaises(ZeroDivisionError):
637+
with suppress(): # noqa: B022
638+
raise ZeroDivisionError
639+
640+
@make_dynamo_test
641+
def test_multiple_exception_args(self):
642+
with suppress(ZeroDivisionError, TypeError):
643+
raise ZeroDivisionError
644+
with suppress(ZeroDivisionError, TypeError):
645+
raise TypeError
646+
647+
@make_dynamo_test
648+
def test_cm_is_reentrant(self):
649+
ignore_exceptions = suppress(Exception)
650+
with ignore_exceptions:
651+
pass
652+
with ignore_exceptions:
653+
raise TypeError
654+
with ignore_exceptions:
655+
with ignore_exceptions: # Check nested usage
656+
raise ValueError
657+
outer_continued = True
658+
{}[1]
659+
self.assertTrue(outer_continued)
660+
661+
605662
if __name__ == "__main__":
606663
from torch._dynamo.test_case import run_tests
607664

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_cm_is_reentrant

Whitespace-only changes.

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_exception_hierarchy

Whitespace-only changes.

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_instance_docs

Whitespace-only changes.

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_no_args

Whitespace-only changes.

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_no_exception

Whitespace-only changes.

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_no_result_from_enter

Whitespace-only changes.

test/dynamo_expected_failures/CPython313-test_contextlib-TestSuppress.test_other_exception

Whitespace-only changes.

torch/_dynamo/variables/lists.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -529,19 +529,22 @@ def call_method(
529529
hints=["Use something else as the key."],
530530
)
531531

532-
tx.output.side_effects.mutation(self)
533-
sorted_items_with_keys = sorted(
534-
(
532+
try:
533+
tx.output.side_effects.mutation(self)
534+
sorted_items_with_keys = sorted(
535535
(
536-
x,
537-
k.as_python_constant(),
538-
-i if reverse else i, # extra key to ensure stable sort
539-
)
540-
for i, (k, x) in enumerate(zip(keys, self.items))
541-
),
542-
key=operator.itemgetter(1, 2),
543-
reverse=reverse,
544-
)
536+
(
537+
x,
538+
k.as_python_constant(),
539+
-i if reverse else i, # extra key to ensure stable sort
540+
)
541+
for i, (k, x) in enumerate(zip(keys, self.items))
542+
),
543+
key=operator.itemgetter(1, 2),
544+
reverse=reverse,
545+
)
546+
except Exception as e:
547+
raise_observed_exception(type(e), tx, args=[ConstantVariable(a) for a in e.args])
545548
self.items[:] = [x for x, *_ in sorted_items_with_keys]
546549
return ConstantVariable.create(None)
547550

0 commit comments

Comments
 (0)