| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent b647d70 commit 2a2270d
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -520,34 +520,38 @@ def test_func_3(self): | |||
| 520 | 520 | async def foo(): | |
| 521 | 521 | raise StopIteration | |
| 522 | 522 | ||
| 523 | - with silence_coro_gc(): | ||
| 524 | - self.assertRegex(repr(foo()), '^<coroutine object.* at 0x.*>$') | ||
| 523 | + coro = foo() | ||
| 524 | + self.assertRegex(repr(coro), '^<coroutine object.* at 0x.*>$') | ||
| 525 | + coro.close() | ||
| 525 | 526 | ||
| 526 | 527 | def test_func_4(self): | |
| 527 | 528 | async def foo(): | |
| 528 | 529 | raise StopIteration | |
| 530 | + coro = foo() | ||
| 529 | 531 | ||
| 530 | 532 | check = lambda: self.assertRaisesRegex( | |
| 531 | 533 | TypeError, "'coroutine' object is not iterable") | |
| 532 | 534 | ||
| 533 | 535 | with check(): | |
| 534 | - list(foo()) | ||
| 536 | + list(coro) | ||
| 535 | 537 | ||
| 536 | 538 | with check(): | |
| 537 | - tuple(foo()) | ||
| 539 | + tuple(coro) | ||
| 538 | 540 | ||
| 539 | 541 | with check(): | |
| 540 | - sum(foo()) | ||
| 542 | + sum(coro) | ||
| 541 | 543 | ||
| 542 | 544 | with check(): | |
| 543 | - iter(foo()) | ||
| 545 | + iter(coro) | ||
| 544 | 546 | ||
| 545 | - with silence_coro_gc(), check(): | ||
| 546 | - for i in foo(): | ||
| 547 | + with check(): | ||
| 548 | + for i in coro: | ||
| 547 | 549 | pass | |
| 548 | 550 | ||
| 549 | - with silence_coro_gc(), check(): | ||
| 550 | - [i for i in foo()] | ||
| 551 | + with check(): | ||
| 552 | + [i for i in coro] | ||
| 553 | + | ||
| 554 | + coro.close() | ||
| 551 | 555 | ||
| 552 | 556 | def test_func_5(self): | |
| 553 | 557 | @types.coroutine | |
@@ -560,8 +564,11 @@ async def foo(): | |||
| 560 | 564 | check = lambda: self.assertRaisesRegex( | |
| 561 | 565 | TypeError, "'coroutine' object is not iterable") | |
| 562 | 566 | ||
| 567 | + coro = foo() | ||
| 563 | 568 | with check(): | |
| 564 | - for el in foo(): pass | ||
| 569 | + for el in coro: | ||
| 570 | + pass | ||
| 571 | + coro.close() | ||
| 565 | 572 | ||
| 566 | 573 | # the following should pass without an error | |
| 567 | 574 | for el in bar(): | |
@@ -588,35 +595,53 @@ async def foo(): | |||
| 588 | 595 | def test_func_7(self): | |
| 589 | 596 | async def bar(): | |
| 590 | 597 | return 10 | |
| 598 | + coro = bar() | ||
| 591 | 599 | ||
| 592 | 600 | def foo(): | |
| 593 | - yield from bar() | ||
| 594 | - | ||
| 595 | - with silence_coro_gc(), self.assertRaisesRegex( | ||
| 596 | - TypeError, | ||
| 597 | - "cannot 'yield from' a coroutine object in a non-coroutine generator"): | ||
| 601 | + yield from coro | ||
| 598 | 602 | ||
| 603 | + with self.assertRaisesRegex( | ||
| 604 | + TypeError, | ||
| 605 | + "cannot 'yield from' a coroutine object in " | ||
| 606 | + "a non-coroutine generator"): | ||
| 599 | 607 | list(foo()) | |
| 600 | 608 | ||
| 609 | + coro.close() | ||
| 610 | + | ||
| 601 | 611 | def test_func_8(self): | |
| 602 | 612 | @types.coroutine | |
| 603 | 613 | def bar(): | |
| 604 | - return (yield from foo()) | ||
| 614 | + return (yield from coro) | ||
| 605 | 615 | ||
| 606 | 616 | async def foo(): | |
| 607 | 617 | return 'spam' | |
| 608 | 618 | ||
| 609 | - self.assertEqual(run_async(bar()), ([], 'spam') ) | ||
| 619 | + coro = foo() | ||
| 620 | + self.assertEqual(run_async(bar()), ([], 'spam')) | ||
| 621 | + coro.close() | ||
| 610 | 622 | ||
| 611 | 623 | def test_func_9(self): | |
| 612 | - async def foo(): pass | ||
| 624 | + async def foo(): | ||
| 625 | + pass | ||
| 613 | 626 | ||
| 614 | 627 | with self.assertWarnsRegex( | |
| 615 | - RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"): | ||
| 628 | + RuntimeWarning, | ||
| 629 | + r"coroutine '.*test_func_9.*foo' was never awaited"): | ||
| 616 | 630 | ||
| 617 | 631 | foo() | |
| 618 | 632 | support.gc_collect() | |
| 619 | 633 | ||
| 634 | + with self.assertWarnsRegex( | ||
| 635 | + RuntimeWarning, | ||
| 636 | + r"coroutine '.*test_func_9.*foo' was never awaited"): | ||
| 637 | + | ||
| 638 | + with self.assertRaises(TypeError): | ||
| 639 | + # See bpo-32703. | ||
| 640 | + for _ in foo(): | ||
| 641 | + pass | ||
| 642 | + | ||
| 643 | + support.gc_collect() | ||
| 644 | + | ||
| 620 | 645 | def test_func_10(self): | |
| 621 | 646 | N = 0 | |
| 622 | 647 | ||
@@ -674,11 +699,14 @@ async def g(): | |||
| 674 | 699 | def test_func_13(self): | |
| 675 | 700 | async def g(): | |
| 676 | 701 | pass | |
| 702 | + | ||
| 703 | + coro = g() | ||
| 677 | 704 | with self.assertRaisesRegex( | |
| 678 | - TypeError, | ||
| 679 | - "can't send non-None value to a just-started coroutine"): | ||
| 705 | + TypeError, | ||
| 706 | + "can't send non-None value to a just-started coroutine"): | ||
| 707 | + coro.send('spam') | ||
| 680 | 708 | ||
| 681 | - g().send('spam') | ||
| 709 | + coro.close() | ||
| 682 | 710 | ||
| 683 | 711 | def test_func_14(self): | |
| 684 | 712 | @types.coroutine | |
@@ -977,8 +1005,6 @@ async def bar(): | |||
| 977 | 1005 | return 42 | |
| 978 | 1006 | ||
| 979 | 1007 | async def foo(): | |
| 980 | - b = bar() | ||
| 981 | - | ||
| 982 | 1008 | db = {'b': lambda: wrap} | |
| 983 | 1009 | ||
| 984 | 1010 | class DB: | |
@@ -1023,19 +1049,21 @@ async def foo2(): | |||
| 1023 | 1049 | def test_await_12(self): | |
| 1024 | 1050 | async def coro(): | |
| 1025 | 1051 | return 'spam' | |
| 1052 | + c = coro() | ||
| 1026 | 1053 | ||
| 1027 | 1054 | class Awaitable: | |
| 1028 | 1055 | def __await__(self): | |
| 1029 | - return coro() | ||
| 1056 | + return c | ||
| 1030 | 1057 | ||
| 1031 | 1058 | async def foo(): | |
| 1032 | 1059 | return await Awaitable() | |
| 1033 | 1060 | ||
| 1034 | 1061 | with self.assertRaisesRegex( | |
| 1035 | - TypeError, r"__await__\(\) returned a coroutine"): | ||
| 1036 | - | ||
| 1062 | + TypeError, r"__await__\(\) returned a coroutine"): | ||
| 1037 | 1063 | run_async(foo()) | |
| 1038 | 1064 | ||
| 1065 | + c.close() | ||
| 1066 | + | ||
| 1039 | 1067 | def test_await_13(self): | |
| 1040 | 1068 | class Awaitable: | |
| 1041 | 1069 | def __await__(self): | |
@@ -1991,14 +2019,15 @@ def wrap(gen): | |||
| 1991 | 2019 | finally: | |
| 1992 | 2020 | with self.assertWarns(DeprecationWarning): | |
| 1993 | 2021 | sys.set_coroutine_wrapper(None) | |
| 2022 | + f.close() | ||
| 1994 | 2023 | ||
| 1995 | 2024 | with self.assertWarns(DeprecationWarning): | |
| 1996 | 2025 | self.assertIsNone(sys.get_coroutine_wrapper()) | |
| 1997 | 2026 | ||
| 1998 | 2027 | wrapped = None | |
| 1999 | - with silence_coro_gc(): | ||
| 2000 | - foo() | ||
| 2028 | + coro = foo() | ||
| 2001 | 2029 | self.assertFalse(wrapped) | |
| 2030 | + coro.close() | ||
| 2002 | 2031 | ||
| 2003 | 2032 | def test_set_wrapper_2(self): | |
| 2004 | 2033 | with self.assertWarns(DeprecationWarning): | |
@@ -2022,11 +2051,12 @@ async def wrap(coro): | |||
| 2022 | 2051 | sys.set_coroutine_wrapper(wrapper) | |
| 2023 | 2052 | try: | |
| 2024 | 2053 | with silence_coro_gc(), self.assertRaisesRegex( | |
| 2025 | - RuntimeError, | ||
| 2026 | - r"coroutine wrapper.*\.wrapper at 0x.*attempted to " | ||
| 2027 | - r"recursively wrap .* wrap .*"): | ||
| 2054 | + RuntimeError, | ||
| 2055 | + r"coroutine wrapper.*\.wrapper at 0x.*attempted to " | ||
| 2056 | + r"recursively wrap .* wrap .*"): | ||
| 2028 | 2057 | ||
| 2029 | 2058 | foo() | |
| 2059 | + | ||
| 2030 | 2060 | finally: | |
| 2031 | 2061 | with self.assertWarns(DeprecationWarning): | |
| 2032 | 2062 | sys.set_coroutine_wrapper(None) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Fix coroutine's ResourceWarning when there's an active error set when it's | ||
| 2 | + being finalized. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -44,9 +44,10 @@ _PyGen_Finalize(PyObject *self) | |||
| 44 | 44 | PyObject *res = NULL; | |
| 45 | 45 | PyObject *error_type, *error_value, *error_traceback; | |
| 46 | 46 | ||
| 47 | - if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) | ||
| 47 | + if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) { | ||
| 48 | 48 | /* Generator isn't paused, so no need to close */ | |
| 49 | 49 | return; | |
| 50 | + } | ||
| 50 | 51 | ||
| 51 | 52 | if (PyAsyncGen_CheckExact(self)) { | |
| 52 | 53 | PyAsyncGenObject *agen = (PyAsyncGenObject*)self; | |
@@ -75,18 +76,18 @@ _PyGen_Finalize(PyObject *self) | |||
| 75 | 76 | issue a RuntimeWarning. */ | |
| 76 | 77 | if (gen->gi_code != NULL && | |
| 77 | 78 | ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && | |
| 78 | - gen->gi_frame->f_lasti == -1) { | ||
| 79 | - if (!error_value) { | ||
| 80 | - _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); | ||
| 81 | - } | ||
| 79 | + gen->gi_frame->f_lasti == -1) | ||
| 80 | + { | ||
| 81 | + _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); | ||
| 82 | 82 | } | |
| 83 | 83 | else { | |
| 84 | 84 | res = gen_close(gen, NULL); | |
| 85 | 85 | } | |
| 86 | 86 | ||
| 87 | 87 | if (res == NULL) { | |
| 88 | - if (PyErr_Occurred()) | ||
| 88 | + if (PyErr_Occurred()) { | ||
| 89 | 89 | PyErr_WriteUnraisable(self); | |
| 90 | + } | ||
| 90 | 91 | } | |
| 91 | 92 | else { | |
| 92 | 93 | Py_DECREF(res); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments