Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
1af2bf75
Kaydet (Commit)
1af2bf75
authored
May 12, 2015
tarafından
Yury Selivanov
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
asyncio: Support PEP 492. Issue #24017.
üst
d7e19bb5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
116 additions
and
27 deletions
+116
-27
base_events.py
Lib/asyncio/base_events.py
+38
-9
coroutines.py
Lib/asyncio/coroutines.py
+64
-13
futures.py
Lib/asyncio/futures.py
+4
-0
tasks.py
Lib/asyncio/tasks.py
+6
-2
test_base_events.py
Lib/test/test_asyncio/test_base_events.py
+2
-1
test_tasks.py
Lib/test/test_asyncio/test_tasks.py
+2
-2
No files found.
Lib/asyncio/base_events.py
Dosyayı görüntüle @
1af2bf75
...
@@ -191,8 +191,8 @@ class BaseEventLoop(events.AbstractEventLoop):
...
@@ -191,8 +191,8 @@ class BaseEventLoop(events.AbstractEventLoop):
self
.
_thread_id
=
None
self
.
_thread_id
=
None
self
.
_clock_resolution
=
time
.
get_clock_info
(
'monotonic'
)
.
resolution
self
.
_clock_resolution
=
time
.
get_clock_info
(
'monotonic'
)
.
resolution
self
.
_exception_handler
=
None
self
.
_exception_handler
=
None
self
.
_debug
=
(
not
sys
.
flags
.
ignore_environment
self
.
set_debug
(
(
not
sys
.
flags
.
ignore_environment
and
bool
(
os
.
environ
.
get
(
'PYTHONASYNCIODEBUG'
)))
and
bool
(
os
.
environ
.
get
(
'PYTHONASYNCIODEBUG'
)
)))
# In debug mode, if the execution of a callback or a step of a task
# In debug mode, if the execution of a callback or a step of a task
# exceed this duration in seconds, the slow callback/task is logged.
# exceed this duration in seconds, the slow callback/task is logged.
self
.
slow_callback_duration
=
0.1
self
.
slow_callback_duration
=
0.1
...
@@ -360,13 +360,18 @@ class BaseEventLoop(events.AbstractEventLoop):
...
@@ -360,13 +360,18 @@ class BaseEventLoop(events.AbstractEventLoop):
return
return
if
self
.
_debug
:
if
self
.
_debug
:
logger
.
debug
(
"Close
%
r"
,
self
)
logger
.
debug
(
"Close
%
r"
,
self
)
self
.
_closed
=
True
try
:
self
.
_ready
.
clear
()
self
.
_closed
=
True
self
.
_scheduled
.
clear
()
self
.
_ready
.
clear
()
executor
=
self
.
_default_executor
self
.
_scheduled
.
clear
()
if
executor
is
not
None
:
executor
=
self
.
_default_executor
self
.
_default_executor
=
None
if
executor
is
not
None
:
executor
.
shutdown
(
wait
=
False
)
self
.
_default_executor
=
None
executor
.
shutdown
(
wait
=
False
)
finally
:
# It is important to unregister "sys.coroutine_wrapper"
# if it was registered.
self
.
set_debug
(
False
)
def
is_closed
(
self
):
def
is_closed
(
self
):
"""Returns True if the event loop was closed."""
"""Returns True if the event loop was closed."""
...
@@ -1199,3 +1204,27 @@ class BaseEventLoop(events.AbstractEventLoop):
...
@@ -1199,3 +1204,27 @@ class BaseEventLoop(events.AbstractEventLoop):
def
set_debug
(
self
,
enabled
):
def
set_debug
(
self
,
enabled
):
self
.
_debug
=
enabled
self
.
_debug
=
enabled
wrapper
=
coroutines
.
debug_wrapper
try
:
set_wrapper
=
sys
.
set_coroutine_wrapper
except
AttributeError
:
pass
else
:
current_wrapper
=
sys
.
get_coroutine_wrapper
()
if
enabled
:
if
current_wrapper
not
in
(
None
,
wrapper
):
warnings
.
warn
(
"loop.set_debug(True): cannot set debug coroutine "
"wrapper; another wrapper is already set
%
r"
%
current_wrapper
,
RuntimeWarning
)
else
:
set_wrapper
(
wrapper
)
else
:
if
current_wrapper
not
in
(
None
,
wrapper
):
warnings
.
warn
(
"loop.set_debug(False): cannot unset debug coroutine "
"wrapper; another wrapper was set
%
r"
%
current_wrapper
,
RuntimeWarning
)
else
:
set_wrapper
(
None
)
Lib/asyncio/coroutines.py
Dosyayı görüntüle @
1af2bf75
...
@@ -14,6 +14,9 @@ from . import futures
...
@@ -14,6 +14,9 @@ from . import futures
from
.log
import
logger
from
.log
import
logger
_PY35
=
sys
.
version_info
>=
(
3
,
5
)
# Opcode of "yield from" instruction
# Opcode of "yield from" instruction
_YIELD_FROM
=
opcode
.
opmap
[
'YIELD_FROM'
]
_YIELD_FROM
=
opcode
.
opmap
[
'YIELD_FROM'
]
...
@@ -30,6 +33,27 @@ _DEBUG = (not sys.flags.ignore_environment
...
@@ -30,6 +33,27 @@ _DEBUG = (not sys.flags.ignore_environment
and
bool
(
os
.
environ
.
get
(
'PYTHONASYNCIODEBUG'
)))
and
bool
(
os
.
environ
.
get
(
'PYTHONASYNCIODEBUG'
)))
try
:
types
.
coroutine
except
AttributeError
:
native_coroutine_support
=
False
else
:
native_coroutine_support
=
True
try
:
_iscoroutinefunction
=
inspect
.
iscoroutinefunction
except
AttributeError
:
_iscoroutinefunction
=
lambda
func
:
False
try
:
inspect
.
CO_COROUTINE
except
AttributeError
:
_is_native_coro_code
=
lambda
code
:
False
else
:
_is_native_coro_code
=
lambda
code
:
(
code
.
co_flags
&
inspect
.
CO_COROUTINE
)
# Check for CPython issue #21209
# Check for CPython issue #21209
def
has_yield_from_bug
():
def
has_yield_from_bug
():
class
MyGen
:
class
MyGen
:
...
@@ -54,16 +78,27 @@ _YIELD_FROM_BUG = has_yield_from_bug()
...
@@ -54,16 +78,27 @@ _YIELD_FROM_BUG = has_yield_from_bug()
del
has_yield_from_bug
del
has_yield_from_bug
def
debug_wrapper
(
gen
):
# This function is called from 'sys.set_coroutine_wrapper'.
# We only wrap here coroutines defined via 'async def' syntax.
# Generator-based coroutines are wrapped in @coroutine
# decorator.
if
_is_native_coro_code
(
gen
.
gi_code
):
return
CoroWrapper
(
gen
,
None
)
else
:
return
gen
class
CoroWrapper
:
class
CoroWrapper
:
# Wrapper for coroutine object in _DEBUG mode.
# Wrapper for coroutine object in _DEBUG mode.
def
__init__
(
self
,
gen
,
func
):
def
__init__
(
self
,
gen
,
func
=
None
):
assert
inspect
.
isgenerator
(
gen
),
gen
assert
inspect
.
isgenerator
(
gen
)
or
inspect
.
iscoroutine
(
gen
)
,
gen
self
.
gen
=
gen
self
.
gen
=
gen
self
.
func
=
func
self
.
func
=
func
# Used to unwrap @coroutine decorator
self
.
_source_traceback
=
traceback
.
extract_stack
(
sys
.
_getframe
(
1
))
self
.
_source_traceback
=
traceback
.
extract_stack
(
sys
.
_getframe
(
1
))
# __name__, __qualname__, __doc__ attributes are set by the coroutine(
)
self
.
__name__
=
getattr
(
gen
,
'__name__'
,
None
)
# decorator
self
.
__qualname__
=
getattr
(
gen
,
'__qualname__'
,
None
)
def
__repr__
(
self
):
def
__repr__
(
self
):
coro_repr
=
_format_coroutine
(
self
)
coro_repr
=
_format_coroutine
(
self
)
...
@@ -75,6 +110,9 @@ class CoroWrapper:
...
@@ -75,6 +110,9 @@ class CoroWrapper:
def
__iter__
(
self
):
def
__iter__
(
self
):
return
self
return
self
if
_PY35
:
__await__
=
__iter__
# make compatible with 'await' expression
def
__next__
(
self
):
def
__next__
(
self
):
return
next
(
self
.
gen
)
return
next
(
self
.
gen
)
...
@@ -133,6 +171,14 @@ def coroutine(func):
...
@@ -133,6 +171,14 @@ def coroutine(func):
If the coroutine is not yielded from before it is destroyed,
If the coroutine is not yielded from before it is destroyed,
an error message is logged.
an error message is logged.
"""
"""
is_coroutine
=
_iscoroutinefunction
(
func
)
if
is_coroutine
and
_is_native_coro_code
(
func
.
__code__
):
# In Python 3.5 that's all we need to do for coroutines
# defiend with "async def".
# Wrapping in CoroWrapper will happen via
# 'sys.set_coroutine_wrapper' function.
return
func
if
inspect
.
isgeneratorfunction
(
func
):
if
inspect
.
isgeneratorfunction
(
func
):
coro
=
func
coro
=
func
else
:
else
:
...
@@ -144,18 +190,22 @@ def coroutine(func):
...
@@ -144,18 +190,22 @@ def coroutine(func):
return
res
return
res
if
not
_DEBUG
:
if
not
_DEBUG
:
wrapper
=
coro
if
native_coroutine_support
:
wrapper
=
types
.
coroutine
(
coro
)
else
:
wrapper
=
coro
else
:
else
:
@functools.wraps
(
func
)
@functools.wraps
(
func
)
def
wrapper
(
*
args
,
**
kwds
):
def
wrapper
(
*
args
,
**
kwds
):
w
=
CoroWrapper
(
coro
(
*
args
,
**
kwds
),
func
)
w
=
CoroWrapper
(
coro
(
*
args
,
**
kwds
),
func
=
func
)
if
w
.
_source_traceback
:
if
w
.
_source_traceback
:
del
w
.
_source_traceback
[
-
1
]
del
w
.
_source_traceback
[
-
1
]
if
hasattr
(
func
,
'__name__'
):
# Python < 3.5 does not implement __qualname__
w
.
__name__
=
func
.
__name__
# on generator objects, so we set it manually.
if
hasattr
(
func
,
'__qualname__'
):
# We use getattr as some callables (such as
w
.
__qualname__
=
func
.
__qualname__
# functools.partial may lack __qualname__).
w
.
__doc__
=
func
.
__doc__
w
.
__name__
=
getattr
(
func
,
'__name__'
,
None
)
w
.
__qualname__
=
getattr
(
func
,
'__qualname__'
,
None
)
return
w
return
w
wrapper
.
_is_coroutine
=
True
# For iscoroutinefunction().
wrapper
.
_is_coroutine
=
True
# For iscoroutinefunction().
...
@@ -164,7 +214,8 @@ def coroutine(func):
...
@@ -164,7 +214,8 @@ def coroutine(func):
def
iscoroutinefunction
(
func
):
def
iscoroutinefunction
(
func
):
"""Return True if func is a decorated coroutine function."""
"""Return True if func is a decorated coroutine function."""
return
getattr
(
func
,
'_is_coroutine'
,
False
)
return
(
getattr
(
func
,
'_is_coroutine'
,
False
)
or
_iscoroutinefunction
(
func
))
_COROUTINE_TYPES
=
(
types
.
GeneratorType
,
CoroWrapper
)
_COROUTINE_TYPES
=
(
types
.
GeneratorType
,
CoroWrapper
)
...
...
Lib/asyncio/futures.py
Dosyayı görüntüle @
1af2bf75
...
@@ -19,6 +19,7 @@ _CANCELLED = 'CANCELLED'
...
@@ -19,6 +19,7 @@ _CANCELLED = 'CANCELLED'
_FINISHED
=
'FINISHED'
_FINISHED
=
'FINISHED'
_PY34
=
sys
.
version_info
>=
(
3
,
4
)
_PY34
=
sys
.
version_info
>=
(
3
,
4
)
_PY35
=
sys
.
version_info
>=
(
3
,
5
)
Error
=
concurrent
.
futures
.
_base
.
Error
Error
=
concurrent
.
futures
.
_base
.
Error
CancelledError
=
concurrent
.
futures
.
CancelledError
CancelledError
=
concurrent
.
futures
.
CancelledError
...
@@ -387,6 +388,9 @@ class Future:
...
@@ -387,6 +388,9 @@ class Future:
assert
self
.
done
(),
"yield from wasn't used with future"
assert
self
.
done
(),
"yield from wasn't used with future"
return
self
.
result
()
# May raise too.
return
self
.
result
()
# May raise too.
if
_PY35
:
__await__
=
__iter__
# make compatible with 'await' expression
def
wrap_future
(
fut
,
*
,
loop
=
None
):
def
wrap_future
(
fut
,
*
,
loop
=
None
):
"""Wrap concurrent.futures.Future object."""
"""Wrap concurrent.futures.Future object."""
...
...
Lib/asyncio/tasks.py
Dosyayı görüntüle @
1af2bf75
...
@@ -11,6 +11,7 @@ import functools
...
@@ -11,6 +11,7 @@ import functools
import
inspect
import
inspect
import
linecache
import
linecache
import
sys
import
sys
import
types
import
traceback
import
traceback
import
warnings
import
warnings
import
weakref
import
weakref
...
@@ -73,7 +74,10 @@ class Task(futures.Future):
...
@@ -73,7 +74,10 @@ class Task(futures.Future):
super
()
.
__init__
(
loop
=
loop
)
super
()
.
__init__
(
loop
=
loop
)
if
self
.
_source_traceback
:
if
self
.
_source_traceback
:
del
self
.
_source_traceback
[
-
1
]
del
self
.
_source_traceback
[
-
1
]
self
.
_coro
=
iter
(
coro
)
# Use the iterator just in case.
if
coro
.
__class__
is
types
.
GeneratorType
:
self
.
_coro
=
coro
else
:
self
.
_coro
=
iter
(
coro
)
# Use the iterator just in case.
self
.
_fut_waiter
=
None
self
.
_fut_waiter
=
None
self
.
_must_cancel
=
False
self
.
_must_cancel
=
False
self
.
_loop
.
call_soon
(
self
.
_step
)
self
.
_loop
.
call_soon
(
self
.
_step
)
...
@@ -236,7 +240,7 @@ class Task(futures.Future):
...
@@ -236,7 +240,7 @@ class Task(futures.Future):
elif
value
is
not
None
:
elif
value
is
not
None
:
result
=
coro
.
send
(
value
)
result
=
coro
.
send
(
value
)
else
:
else
:
result
=
next
(
coro
)
result
=
coro
.
send
(
None
)
except
StopIteration
as
exc
:
except
StopIteration
as
exc
:
self
.
set_result
(
exc
.
value
)
self
.
set_result
(
exc
.
value
)
except
futures
.
CancelledError
as
exc
:
except
futures
.
CancelledError
as
exc
:
...
...
Lib/test/test_asyncio/test_base_events.py
Dosyayı görüntüle @
1af2bf75
...
@@ -61,7 +61,8 @@ class BaseEventLoopTests(test_utils.TestCase):
...
@@ -61,7 +61,8 @@ class BaseEventLoopTests(test_utils.TestCase):
NotImplementedError
,
NotImplementedError
,
self
.
loop
.
_make_write_pipe_transport
,
m
,
m
)
self
.
loop
.
_make_write_pipe_transport
,
m
,
m
)
gen
=
self
.
loop
.
_make_subprocess_transport
(
m
,
m
,
m
,
m
,
m
,
m
,
m
)
gen
=
self
.
loop
.
_make_subprocess_transport
(
m
,
m
,
m
,
m
,
m
,
m
,
m
)
self
.
assertRaises
(
NotImplementedError
,
next
,
iter
(
gen
))
with
self
.
assertRaises
(
NotImplementedError
):
gen
.
send
(
None
)
def
test_close
(
self
):
def
test_close
(
self
):
self
.
assertFalse
(
self
.
loop
.
is_closed
())
self
.
assertFalse
(
self
.
loop
.
is_closed
())
...
...
Lib/test/test_asyncio/test_tasks.py
Dosyayı görüntüle @
1af2bf75
...
@@ -1638,7 +1638,7 @@ class TaskTests(test_utils.TestCase):
...
@@ -1638,7 +1638,7 @@ class TaskTests(test_utils.TestCase):
return
a
return
a
def
call
(
arg
):
def
call
(
arg
):
cw
=
asyncio
.
coroutines
.
CoroWrapper
(
foo
()
,
foo
)
cw
=
asyncio
.
coroutines
.
CoroWrapper
(
foo
())
cw
.
send
(
None
)
cw
.
send
(
None
)
try
:
try
:
cw
.
send
(
arg
)
cw
.
send
(
arg
)
...
@@ -1653,7 +1653,7 @@ class TaskTests(test_utils.TestCase):
...
@@ -1653,7 +1653,7 @@ class TaskTests(test_utils.TestCase):
def
test_corowrapper_weakref
(
self
):
def
test_corowrapper_weakref
(
self
):
wd
=
weakref
.
WeakValueDictionary
()
wd
=
weakref
.
WeakValueDictionary
()
def
foo
():
yield
from
[]
def
foo
():
yield
from
[]
cw
=
asyncio
.
coroutines
.
CoroWrapper
(
foo
()
,
foo
)
cw
=
asyncio
.
coroutines
.
CoroWrapper
(
foo
())
wd
[
'cw'
]
=
cw
# Would fail without __weakref__ slot.
wd
[
'cw'
]
=
cw
# Would fail without __weakref__ slot.
cw
.
gen
=
None
# Suppress warning from __del__.
cw
.
gen
=
None
# Suppress warning from __del__.
...
...
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