()
| 590 | |
| 591 | |
| 592 | def test_with_resource_nested_exception() -> None: |
| 593 | class TestContext(AbstractContextManager[list[int]]): |
| 594 | _handle_exception: bool |
| 595 | _base_val: int |
| 596 | val: list[int] |
| 597 | |
| 598 | def __init__(self, base_val: int = 1, *, handle_exception: bool = True) -> None: |
| 599 | self._handle_exception = handle_exception |
| 600 | self._base_val = base_val |
| 601 | |
| 602 | def __enter__(self) -> list[int]: |
| 603 | self.val = [self._base_val] |
| 604 | return self.val |
| 605 | |
| 606 | def __exit__( |
| 607 | self, |
| 608 | exc_type: type[BaseException] | None, |
| 609 | exc_value: BaseException | None, |
| 610 | traceback: TracebackType | None, |
| 611 | ) -> bool | None: |
| 612 | if not exc_type: |
| 613 | self.val[0] = self._base_val - 1 |
| 614 | return None |
| 615 | |
| 616 | self.val[0] = self._base_val + 1 |
| 617 | return self._handle_exception |
| 618 | |
| 619 | class TestException(Exception): |
| 620 | pass |
| 621 | |
| 622 | ctx = click.Context(click.Command("test")) |
| 623 | base_val = 1 |
| 624 | base_val_nested = 11 |
| 625 | |
| 626 | with ctx.scope(): |
| 627 | rv = ctx.with_resource(TestContext(base_val=base_val)) |
| 628 | rv_nested = ctx.with_resource(TestContext(base_val=base_val_nested)) |
| 629 | assert rv[0] == base_val |
| 630 | assert rv_nested[0] == base_val_nested |
| 631 | |
| 632 | assert rv == [base_val - 1] |
| 633 | assert rv_nested == [base_val_nested - 1] |
| 634 | |
| 635 | with ctx.scope(): |
| 636 | rv = ctx.with_resource(TestContext(base_val=base_val)) |
| 637 | rv_nested = ctx.with_resource(TestContext(base_val=base_val_nested)) |
| 638 | raise TestException() |
| 639 | |
| 640 | # If one of the context "eats" the exceptions they will not be forwarded to other |
| 641 | # parts. This is due to how ExitStack unwinding works |
| 642 | assert rv_nested == [base_val_nested + 1] |
| 643 | assert rv == [base_val - 1] |
| 644 | |
| 645 | with ctx.scope(): |
| 646 | rv = ctx.with_resource(TestContext(base_val=base_val)) |
| 647 | rv_nested = ctx.with_resource( |
| 648 | TestContext(base_val=base_val_nested, handle_exception=False) |
| 649 | ) |
nothing calls this directly
no test coverage detected