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
e470bc00
Commit
e470bc00
authored
May 02, 2015
by
Guido van Rossum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Asyncio issue 222 / PR 231 (Victor Stinner) -- fix @coroutine functions without __name__.
parent
34da805f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
70 additions
and
32 deletions
+70
-32
Lib/asyncio/coroutines.py
Lib/asyncio/coroutines.py
+12
-6
Lib/asyncio/events.py
Lib/asyncio/events.py
+10
-4
Lib/asyncio/futures.py
Lib/asyncio/futures.py
+1
-1
Lib/test/test_asyncio/test_tasks.py
Lib/test/test_asyncio/test_tasks.py
+44
-21
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Lib/asyncio/coroutines.py
View file @
e470bc00
...
...
@@ -151,7 +151,8 @@ def coroutine(func):
w
=
CoroWrapper
(
coro
(
*
args
,
**
kwds
),
func
)
if
w
.
_source_traceback
:
del
w
.
_source_traceback
[
-
1
]
w
.
__name__
=
func
.
__name__
if
hasattr
(
func
,
'__name__'
):
w
.
__name__
=
func
.
__name__
if
hasattr
(
func
,
'__qualname__'
):
w
.
__qualname__
=
func
.
__qualname__
w
.
__doc__
=
func
.
__doc__
...
...
@@ -175,25 +176,30 @@ def iscoroutine(obj):
def
_format_coroutine
(
coro
):
assert
iscoroutine
(
coro
)
coro_name
=
getattr
(
coro
,
'__qualname__'
,
coro
.
__name__
)
if
isinstance
(
coro
,
CoroWrapper
):
func
=
coro
.
func
else
:
func
=
coro
coro_name
=
events
.
_format_callback
(
func
,
())
filename
=
coro
.
gi_code
.
co_filename
if
(
isinstance
(
coro
,
CoroWrapper
)
and
not
inspect
.
isgeneratorfunction
(
coro
.
func
)):
filename
,
lineno
=
events
.
_get_function_source
(
coro
.
func
)
if
coro
.
gi_frame
is
None
:
coro_repr
=
(
'%s
()
done, defined at %s:%s'
coro_repr
=
(
'%s done, defined at %s:%s'
%
(
coro_name
,
filename
,
lineno
))
else
:
coro_repr
=
(
'%s
()
running, defined at %s:%s'
coro_repr
=
(
'%s running, defined at %s:%s'
%
(
coro_name
,
filename
,
lineno
))
elif
coro
.
gi_frame
is
not
None
:
lineno
=
coro
.
gi_frame
.
f_lineno
coro_repr
=
(
'%s
()
running at %s:%s'
coro_repr
=
(
'%s running at %s:%s'
%
(
coro_name
,
filename
,
lineno
))
else
:
lineno
=
coro
.
gi_code
.
co_firstlineno
coro_repr
=
(
'%s
()
done, defined at %s:%s'
coro_repr
=
(
'%s done, defined at %s:%s'
%
(
coro_name
,
filename
,
lineno
))
return
coro_repr
Lib/asyncio/events.py
View file @
e470bc00
...
...
@@ -54,15 +54,21 @@ def _format_callback(func, args, suffix=''):
suffix
=
_format_args
(
args
)
+
suffix
return
_format_callback
(
func
.
func
,
func
.
args
,
suffix
)
func_repr
=
getattr
(
func
,
'__qualname__'
,
None
)
if
not
func_repr
:
if
hasattr
(
func
,
'__qualname__'
):
func_repr
=
getattr
(
func
,
'__qualname__'
)
elif
hasattr
(
func
,
'__name__'
):
func_repr
=
getattr
(
func
,
'__name__'
)
else
:
func_repr
=
repr
(
func
)
if
args
is
not
None
:
func_repr
+=
_format_args
(
args
)
if
suffix
:
func_repr
+=
suffix
return
func_repr
def
_format_callback_source
(
func
,
args
):
func_repr
=
_format_callback
(
func
,
args
)
source
=
_get_function_source
(
func
)
if
source
:
func_repr
+=
' at %s:%s'
%
source
...
...
@@ -92,7 +98,7 @@ class Handle:
if
self
.
_cancelled
:
info
.
append
(
'cancelled'
)
if
self
.
_callback
is
not
None
:
info
.
append
(
_format_callback
(
self
.
_callback
,
self
.
_args
))
info
.
append
(
_format_callback
_source
(
self
.
_callback
,
self
.
_args
))
if
self
.
_source_traceback
:
frame
=
self
.
_source_traceback
[
-
1
]
info
.
append
(
'created at %s:%s'
%
(
frame
[
0
],
frame
[
1
]))
...
...
@@ -119,7 +125,7 @@ class Handle:
try
:
self
.
_callback
(
*
self
.
_args
)
except
Exception
as
exc
:
cb
=
_format_callback
(
self
.
_callback
,
self
.
_args
)
cb
=
_format_callback
_source
(
self
.
_callback
,
self
.
_args
)
msg
=
'Exception in callback {}'
.
format
(
cb
)
context
=
{
'message'
:
msg
,
...
...
Lib/asyncio/futures.py
View file @
e470bc00
...
...
@@ -162,7 +162,7 @@ class Future:
cb
=
''
def
format_cb
(
callback
):
return
events
.
_format_callback
(
callback
,
())
return
events
.
_format_callback
_source
(
callback
,
())
if
size
==
1
:
cb
=
format_cb
(
cb
[
0
])
...
...
Lib/test/test_asyncio/test_tasks.py
View file @
e470bc00
"""Tests for tasks.py."""
import
contextlib
import
functools
import
os
import
re
import
sys
...
...
@@ -28,6 +30,19 @@ def coroutine_function():
pass
@
contextlib
.
contextmanager
def
set_coroutine_debug
(
enabled
):
coroutines
=
asyncio
.
coroutines
old_debug
=
coroutines
.
_DEBUG
try
:
coroutines
.
_DEBUG
=
enabled
yield
finally
:
coroutines
.
_DEBUG
=
old_debug
def
format_coroutine
(
qualname
,
state
,
src
,
source_traceback
,
generator
=
False
):
if
generator
:
state
=
'%s'
%
state
...
...
@@ -279,6 +294,29 @@ class TaskTests(test_utils.TestCase):
fut
.
set_result
(
None
)
self
.
loop
.
run_until_complete
(
task
)
def
test_task_repr_partial_corowrapper
(
self
):
# Issue #222: repr(CoroWrapper) must not fail in debug mode if the
# coroutine is a partial function
with
set_coroutine_debug
(
True
):
self
.
loop
.
set_debug
(
True
)
@
asyncio
.
coroutine
def
func
(
x
,
y
):
yield
from
asyncio
.
sleep
(
0
)
partial_func
=
asyncio
.
coroutine
(
functools
.
partial
(
func
,
1
))
task
=
self
.
loop
.
create_task
(
partial_func
(
2
))
# make warnings quiet
task
.
_log_destroy_pending
=
False
self
.
addCleanup
(
task
.
_coro
.
close
)
coro_repr
=
repr
(
task
.
_coro
)
expected
=
(
'<CoroWrapper TaskTests.test_task_repr_partial_corowrapper'
'.<locals>.func(1)() running, '
)
self
.
assertTrue
(
coro_repr
.
startswith
(
expected
),
coro_repr
)
def
test_task_basics
(
self
):
@
asyncio
.
coroutine
def
outer
():
...
...
@@ -1555,25 +1593,16 @@ class TaskTests(test_utils.TestCase):
# The frame should have changed.
self
.
assertIsNone
(
gen
.
gi_frame
)
# Save debug flag.
old_debug
=
asyncio
.
coroutines
.
_DEBUG
try
:
# Test with debug flag cleared.
asyncio
.
coroutines
.
_DEBUG
=
False
# Test with debug flag cleared.
with
set_coroutine_debug
(
False
):
check
()
# Test with debug flag set.
asyncio
.
coroutines
.
_DEBUG
=
True
# Test with debug flag set.
with
set_coroutine_debug
(
True
):
check
()
finally
:
# Restore original debug flag.
asyncio
.
coroutines
.
_DEBUG
=
old_debug
def
test_yield_from_corowrapper
(
self
):
old_debug
=
asyncio
.
coroutines
.
_DEBUG
asyncio
.
coroutines
.
_DEBUG
=
True
try
:
with
set_coroutine_debug
(
True
):
@
asyncio
.
coroutine
def
t1
():
return
(
yield
from
t2
())
...
...
@@ -1591,8 +1620,6 @@ class TaskTests(test_utils.TestCase):
task
=
asyncio
.
Task
(
t1
(),
loop
=
self
.
loop
)
val
=
self
.
loop
.
run_until_complete
(
task
)
self
.
assertEqual
(
val
,
(
1
,
2
,
3
))
finally
:
asyncio
.
coroutines
.
_DEBUG
=
old_debug
def
test_yield_from_corowrapper_send
(
self
):
def
foo
():
...
...
@@ -1663,14 +1690,10 @@ class TaskTests(test_utils.TestCase):
@
mock
.
patch
(
'asyncio.coroutines.logger'
)
def
test_coroutine_never_yielded
(
self
,
m_log
):
debug
=
asyncio
.
coroutines
.
_DEBUG
try
:
asyncio
.
coroutines
.
_DEBUG
=
True
with
set_coroutine_debug
(
True
):
@
asyncio
.
coroutine
def
coro_noop
():
pass
finally
:
asyncio
.
coroutines
.
_DEBUG
=
debug
tb_filename
=
__file__
tb_lineno
=
sys
.
_getframe
().
f_lineno
+
2
...
...
Misc/NEWS
View file @
e470bc00
...
...
@@ -39,6 +39,9 @@ Core and Builtins
Library
-------
- Asyncio issue 222 / PR 231 (Victor Stinner) -- fix @coroutine
functions without __name__.
- Issue #9246: On POSIX, os.getcwd() now supports paths longer than 1025 bytes.
Patch written by William Orr.
...
...
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