Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
e13f8f3c
Commit
e13f8f3c
authored
Jul 03, 2015
by
Yury Selivanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #24450: Add gi_yieldfrom to generators; cr_await to coroutines.
Patch by Benno Leslie and Yury Selivanov.
parent
b32b998b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
101 additions
and
1 deletion
+101
-1
Doc/library/inspect.rst
Doc/library/inspect.rst
+7
-0
Doc/whatsnew/3.5.rst
Doc/whatsnew/3.5.rst
+3
-0
Lib/test/test_coroutines.py
Lib/test/test_coroutines.py
+30
-0
Lib/test/test_generators.py
Lib/test/test_generators.py
+36
-1
Misc/NEWS
Misc/NEWS
+3
-0
Objects/genobject.c
Objects/genobject.c
+22
-0
No files found.
Doc/library/inspect.rst
View file @
e13f8f3c
...
...
@@ -182,12 +182,19 @@ attributes:
+-----------+-----------------+---------------------------+
| | __qualname__ | qualified name |
+-----------+-----------------+---------------------------+
| | cr_await | object being awaited on, |
| | | or ``None`` |
+-----------+-----------------+---------------------------+
| | cr_frame | frame |
+-----------+-----------------+---------------------------+
| | cr_running | is the coroutine running? |
+-----------+-----------------+---------------------------+
| | cr_code | code |
+-----------+-----------------+---------------------------+
| | gi_yieldfrom | object being iterated by |
| | | ``yield from``, or |
| | | ``None`` |
+-----------+-----------------+---------------------------+
| builtin | __doc__ | documentation string |
+-----------+-----------------+---------------------------+
| | __name__ | original name of this |
...
...
Doc/whatsnew/3.5.rst
View file @
e13f8f3c
...
...
@@ -84,6 +84,9 @@ New built-in features:
* ``b'\xf0\x9f\x90\x8d'.hex()``, ``bytearray(b'\xf0\x9f\x90\x8d').hex()``,
``memoryview(b'\xf0\x9f\x90\x8d').hex()``: :issue:`9951` - A ``hex`` method
has been added to bytes, bytearray, and memoryview.
* Generators have new ``gi_yieldfrom`` attribute, which returns the
object being iterated by ``yield from`` expressions. (Contributed
by Benno Leslie and Yury Selivanov in :issue:`24450`.)
Implementation improvements:
...
...
Lib/test/test_coroutines.py
View file @
e13f8f3c
...
...
@@ -350,6 +350,36 @@ class CoroutineTest(unittest.TestCase):
"coroutine ignored GeneratorExit"
):
c
.
close
()
def
test_cr_await
(
self
):
@
types
.
coroutine
def
a
():
self
.
assertEqual
(
inspect
.
getcoroutinestate
(
coro_b
),
inspect
.
CORO_RUNNING
)
self
.
assertIsNone
(
coro_b
.
cr_await
)
yield
self
.
assertEqual
(
inspect
.
getcoroutinestate
(
coro_b
),
inspect
.
CORO_RUNNING
)
self
.
assertIsNone
(
coro_b
.
cr_await
)
async
def
c
():
await
a
()
async
def
b
():
self
.
assertIsNone
(
coro_b
.
cr_await
)
await
c
()
self
.
assertIsNone
(
coro_b
.
cr_await
)
coro_b
=
b
()
self
.
assertEqual
(
inspect
.
getcoroutinestate
(
coro_b
),
inspect
.
CORO_CREATED
)
self
.
assertIsNone
(
coro_b
.
cr_await
)
coro_b
.
send
(
None
)
self
.
assertEqual
(
inspect
.
getcoroutinestate
(
coro_b
),
inspect
.
CORO_SUSPENDED
)
self
.
assertEqual
(
coro_b
.
cr_await
.
cr_await
.
gi_code
.
co_name
,
'a'
)
with
self
.
assertRaises
(
StopIteration
):
coro_b
.
send
(
None
)
# complete coroutine
self
.
assertEqual
(
inspect
.
getcoroutinestate
(
coro_b
),
inspect
.
CORO_CLOSED
)
self
.
assertIsNone
(
coro_b
.
cr_await
)
def
test_corotype_1
(
self
):
ct
=
types
.
CoroutineType
self
.
assertIn
(
'into coroutine'
,
ct
.
send
.
__doc__
)
...
...
Lib/test/test_generators.py
View file @
e13f8f3c
...
...
@@ -3,6 +3,8 @@ import sys
import
unittest
import
warnings
import
weakref
import
inspect
import
types
from
test
import
support
...
...
@@ -259,6 +261,39 @@ class ExceptionTest(unittest.TestCase):
next
(
g
)
class
YieldFromTests
(
unittest
.
TestCase
):
def
test_generator_gi_yieldfrom
(
self
):
def
a
():
self
.
assertEqual
(
inspect
.
getgeneratorstate
(
gen_b
),
inspect
.
GEN_RUNNING
)
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
yield
self
.
assertEqual
(
inspect
.
getgeneratorstate
(
gen_b
),
inspect
.
GEN_RUNNING
)
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
def
b
():
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
yield
from
a
()
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
yield
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
gen_b
=
b
()
self
.
assertEqual
(
inspect
.
getgeneratorstate
(
gen_b
),
inspect
.
GEN_CREATED
)
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
gen_b
.
send
(
None
)
self
.
assertEqual
(
inspect
.
getgeneratorstate
(
gen_b
),
inspect
.
GEN_SUSPENDED
)
self
.
assertEqual
(
gen_b
.
gi_yieldfrom
.
gi_code
.
co_name
,
'a'
)
gen_b
.
send
(
None
)
self
.
assertEqual
(
inspect
.
getgeneratorstate
(
gen_b
),
inspect
.
GEN_SUSPENDED
)
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
[]
=
gen_b
# Exhaust generator
self
.
assertEqual
(
inspect
.
getgeneratorstate
(
gen_b
),
inspect
.
GEN_CLOSED
)
self
.
assertIsNone
(
gen_b
.
gi_yieldfrom
)
tutorial_tests
=
"""
Let's try a simple generator:
...
...
@@ -624,7 +659,7 @@ From the Iterators list, about the types of these things.
>>> type(i)
<class 'generator'>
>>> [s for s in dir(i) if not s.startswith('_')]
['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw']
['close', 'gi_code', 'gi_frame', 'gi_running', '
gi_yieldfrom', '
send', 'throw']
>>> from test.support import HAVE_DOCSTRINGS
>>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implement next(self).')
Implement next(self).
...
...
Misc/NEWS
View file @
e13f8f3c
...
...
@@ -27,6 +27,9 @@ Core and Builtins
used in types.coroutine to be instance of collections.abc.Generator;
inspect.isawaitable was removed (use collections.abc.Awaitable).
- Issue #24450: Add gi_yieldfrom to generators and cr_await to coroutines.
Contributed by Benno Leslie and Yury Selivanov.
Library
-------
...
...
Objects/genobject.c
View file @
e13f8f3c
...
...
@@ -552,11 +552,22 @@ gen_set_qualname(PyGenObject *op, PyObject *value)
return
0
;
}
static
PyObject
*
gen_getyieldfrom
(
PyGenObject
*
gen
)
{
PyObject
*
yf
=
gen_yf
(
gen
);
if
(
yf
==
NULL
)
Py_RETURN_NONE
;
return
yf
;
}
static
PyGetSetDef
gen_getsetlist
[]
=
{
{
"__name__"
,
(
getter
)
gen_get_name
,
(
setter
)
gen_set_name
,
PyDoc_STR
(
"name of the generator"
)},
{
"__qualname__"
,
(
getter
)
gen_get_qualname
,
(
setter
)
gen_set_qualname
,
PyDoc_STR
(
"qualified name of the generator"
)},
{
"gi_yieldfrom"
,
(
getter
)
gen_getyieldfrom
,
NULL
,
PyDoc_STR
(
"object being iterated by yield from, or None"
)},
{
NULL
}
/* Sentinel */
};
...
...
@@ -776,11 +787,22 @@ coro_await(PyCoroObject *coro)
return
(
PyObject
*
)
cw
;
}
static
PyObject
*
coro_get_cr_await
(
PyCoroObject
*
coro
)
{
PyObject
*
yf
=
gen_yf
((
PyGenObject
*
)
coro
);
if
(
yf
==
NULL
)
Py_RETURN_NONE
;
return
yf
;
}
static
PyGetSetDef
coro_getsetlist
[]
=
{
{
"__name__"
,
(
getter
)
gen_get_name
,
(
setter
)
gen_set_name
,
PyDoc_STR
(
"name of the coroutine"
)},
{
"__qualname__"
,
(
getter
)
gen_get_qualname
,
(
setter
)
gen_set_qualname
,
PyDoc_STR
(
"qualified name of the coroutine"
)},
{
"cr_await"
,
(
getter
)
coro_get_cr_await
,
NULL
,
PyDoc_STR
(
"object being awaited on, or None"
)},
{
NULL
}
/* Sentinel */
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment