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
a076e4f5
Unverified
Kaydet (Commit)
a076e4f5
authored
May 09, 2019
tarafından
Andrew Svetlov
Kaydeden (comit)
GitHub
May 09, 2019
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-36802: Drop awrite()/aclose(), support await write() and await close() instead (#13099)
üst
3b2f9ab3
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
118 additions
and
51 deletions
+118
-51
asyncio-stream.rst
Doc/library/asyncio-stream.rst
+59
-31
streams.py
Lib/asyncio/streams.py
+27
-8
test_streams.py
Lib/test/test_asyncio/test_streams.py
+30
-12
2019-05-05-10-12-23.bpo-36802.HYMc8P.rst
...S.d/next/Library/2019-05-05-10-12-23.bpo-36802.HYMc8P.rst
+2
-0
No files found.
Doc/library/asyncio-stream.rst
Dosyayı görüntüle @
a076e4f5
...
...
@@ -22,13 +22,13 @@ streams::
'127.0.0.1', 8888)
print(f'Send: {message!r}')
await writer.
a
write(message.encode())
await writer.write(message.encode())
data = await reader.read(100)
print(f'Received: {data.decode()!r}')
print('Close the connection')
await writer.
a
close()
await writer.close()
asyncio.run(tcp_echo_client('Hello World!'))
...
...
@@ -226,23 +226,70 @@ StreamWriter
directly; use :func:`open_connection` and :func:`start_server`
instead.
.. coroutinemethod:: awrite(data)
.. method:: write(data)
The method attempts to write the *data* to the underlying socket immediately.
If that fails, the data is queued in an internal write buffer until it can be
sent.
Starting with Python 3.8, it is possible to directly await on the `write()`
method::
await stream.write(data)
The ``await`` pauses the current coroutine until the data is written to the
socket.
Below is an equivalent code that works with Python <= 3.7::
stream.write(data)
await stream.drain()
.. versionchanged:: 3.8
Support ``await stream.write(...)`` syntax.
.. method:: writelines(data)
The method writes a list (or any iterable) of bytes to the underlying socket
immediately.
If that fails, the data is queued in an internal write buffer until it can be
sent.
Starting with Python 3.8, it is possible to directly await on the `write()`
method::
await stream.writelines(lines)
The ``await`` pauses the current coroutine until the data is written to the
socket.
Below is an equivalent code that works with Python <= 3.7::
Write *data* to the stream.
stream.writelines(lines)
await stream.drain()
The method respects flow control, execution is paused if the write
buffer reaches the high watermark
.
.. versionchanged:: 3.8
Support ``await stream.writelines()`` syntax
.
.. versionadded:: 3.8
.. method:: close()
The method closes the stream and the underlying socket.
Starting with Python 3.8, it is possible to directly await on the `close()`
method::
await stream.close()
.. coroutinemethod:: aclose()
The ``await`` pauses the current coroutine until the stream and the underlying
socket are closed (and SSL shutdown is performed for a secure connection).
Close the stream.
Below is an equivalent code that works with Python <= 3.7::
Wait until all closing actions are complete, e.g. SSL shutdown for
secure sockets.
stream.close()
await stream.wait_closed()
.. versionadded:: 3.8
.. versionchanged:: 3.8
Support ``await stream.close()`` syntax.
.. method:: can_write_eof()
...
...
@@ -263,21 +310,6 @@ StreamWriter
Access optional transport information; see
:meth:`BaseTransport.get_extra_info` for details.
.. method:: write(data)
Write *data* to the stream.
This method is not subject to flow control. Calls to ``write()`` should
be followed by :meth:`drain`. The :meth:`awrite` method is a
recommended alternative the applies flow control automatically.
.. method:: writelines(data)
Write a list (or any iterable) of bytes to the stream.
This method is not subject to flow control. Calls to ``writelines()``
should be followed by :meth:`drain`.
.. coroutinemethod:: drain()
Wait until it is appropriate to resume writing to the stream.
...
...
@@ -293,10 +325,6 @@ StreamWriter
be resumed. When there is nothing to wait for, the :meth:`drain`
returns immediately.
.. method:: close()
Close the stream.
.. method:: is_closing()
Return ``True`` if the stream is closed or in the process of
...
...
Lib/asyncio/streams.py
Dosyayı görüntüle @
a076e4f5
...
...
@@ -352,6 +352,8 @@ class StreamWriter:
assert
reader
is
None
or
isinstance
(
reader
,
StreamReader
)
self
.
_reader
=
reader
self
.
_loop
=
loop
self
.
_complete_fut
=
self
.
_loop
.
create_future
()
self
.
_complete_fut
.
set_result
(
None
)
def
__repr__
(
self
):
info
=
[
self
.
__class__
.
__name__
,
f
'transport={self._transport!r}'
]
...
...
@@ -365,9 +367,33 @@ class StreamWriter:
def
write
(
self
,
data
):
self
.
_transport
.
write
(
data
)
return
self
.
_fast_drain
()
def
writelines
(
self
,
data
):
self
.
_transport
.
writelines
(
data
)
return
self
.
_fast_drain
()
def
_fast_drain
(
self
):
# The helper tries to use fast-path to return already existing complete future
# object if underlying transport is not paused and actual waiting for writing
# resume is not needed
if
self
.
_reader
is
not
None
:
# this branch will be simplified after merging reader with writer
exc
=
self
.
_reader
.
exception
()
if
exc
is
not
None
:
fut
=
self
.
_loop
.
create_future
()
fut
.
set_exception
(
exc
)
return
fut
if
not
self
.
_transport
.
is_closing
():
if
self
.
_protocol
.
_connection_lost
:
fut
=
self
.
_loop
.
create_future
()
fut
.
set_exception
(
ConnectionResetError
(
'Connection lost'
))
return
fut
if
not
self
.
_protocol
.
_paused
:
# fast path, the stream is not paused
# no need to wait for resume signal
return
self
.
_complete_fut
return
self
.
_loop
.
create_task
(
self
.
drain
())
def
write_eof
(
self
):
return
self
.
_transport
.
write_eof
()
...
...
@@ -377,6 +403,7 @@ class StreamWriter:
def
close
(
self
):
self
.
_transport
.
close
()
return
self
.
_protocol
.
_get_close_waiter
(
self
)
def
is_closing
(
self
):
return
self
.
_transport
.
is_closing
()
...
...
@@ -408,14 +435,6 @@ class StreamWriter:
raise
ConnectionResetError
(
'Connection lost'
)
await
self
.
_protocol
.
_drain_helper
()
async
def
aclose
(
self
):
self
.
close
()
await
self
.
wait_closed
()
async
def
awrite
(
self
,
data
):
self
.
write
(
data
)
await
self
.
drain
()
class
StreamReader
:
...
...
Lib/test/test_asyncio/test_streams.py
Dosyayı görüntüle @
a076e4f5
...
...
@@ -1035,24 +1035,42 @@ os.close(fd)
messages
[
0
][
'message'
])
def
test_async_writer_api
(
self
):
async
def
inner
(
httpd
):
rd
,
wr
=
await
asyncio
.
open_connection
(
*
httpd
.
address
)
await
wr
.
write
(
b
'GET / HTTP/1.0
\r\n\r\n
'
)
data
=
await
rd
.
readline
()
self
.
assertEqual
(
data
,
b
'HTTP/1.0 200 OK
\r\n
'
)
data
=
await
rd
.
read
()
self
.
assertTrue
(
data
.
endswith
(
b
'
\r\n\r\n
Test message'
))
await
wr
.
close
()
messages
=
[]
self
.
loop
.
set_exception_handler
(
lambda
loop
,
ctx
:
messages
.
append
(
ctx
))
with
test_utils
.
run_test_server
()
as
httpd
:
rd
,
wr
=
self
.
loop
.
run_until_complete
(
asyncio
.
open_connection
(
*
httpd
.
address
,
loop
=
self
.
loop
))
self
.
loop
.
run_until_complete
(
inner
(
httpd
))
f
=
wr
.
awrite
(
b
'GET / HTTP/1.0
\r\n\r\n
'
)
self
.
loop
.
run_until_complete
(
f
)
f
=
rd
.
readline
()
data
=
self
.
loop
.
run_until_complete
(
f
)
self
.
assertEqual
(
messages
,
[])
def
test_async_writer_api
(
self
):
async
def
inner
(
httpd
):
rd
,
wr
=
await
asyncio
.
open_connection
(
*
httpd
.
address
)
await
wr
.
write
(
b
'GET / HTTP/1.0
\r\n\r\n
'
)
data
=
await
rd
.
readline
()
self
.
assertEqual
(
data
,
b
'HTTP/1.0 200 OK
\r\n
'
)
f
=
rd
.
read
()
data
=
self
.
loop
.
run_until_complete
(
f
)
data
=
await
rd
.
read
()
self
.
assertTrue
(
data
.
endswith
(
b
'
\r\n\r\n
Test message'
))
f
=
wr
.
aclose
()
self
.
loop
.
run_until_complete
(
f
)
wr
.
close
()
with
self
.
assertRaises
(
ConnectionResetError
):
await
wr
.
write
(
b
'data'
)
messages
=
[]
self
.
loop
.
set_exception_handler
(
lambda
loop
,
ctx
:
messages
.
append
(
ctx
))
with
test_utils
.
run_test_server
()
as
httpd
:
self
.
loop
.
run_until_complete
(
inner
(
httpd
))
self
.
assertEqual
(
messages
,
[])
...
...
@@ -1066,7 +1084,7 @@ os.close(fd)
asyncio
.
open_connection
(
*
httpd
.
address
,
loop
=
self
.
loop
))
f
=
wr
.
a
close
()
f
=
wr
.
close
()
self
.
loop
.
run_until_complete
(
f
)
assert
rd
.
at_eof
()
f
=
rd
.
read
()
...
...
Misc/NEWS.d/next/Library/2019-05-05-10-12-23.bpo-36802.HYMc8P.rst
0 → 100644
Dosyayı görüntüle @
a076e4f5
Provide both sync and async calls for StreamWriter.write() and
StreamWriter.close()
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