mirror of https://github.com/MagicStack/uvloop.git
parent
e21ceea0f0
commit
cdd2218fa3
|
@ -72,7 +72,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
|
||||
python-version: [3.7, 3.8, 3.9]
|
||||
os: [ubuntu-20.04, macos-latest]
|
||||
arch: [x86_64, aarch64]
|
||||
exclude:
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
|
||||
python-version: [3.7, 3.8, 3.9]
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
|
|
|
@ -39,7 +39,7 @@ about it.
|
|||
Installation
|
||||
------------
|
||||
|
||||
uvloop requires Python 3.5 or greater and is available on PyPI.
|
||||
uvloop requires Python 3.7 or greater and is available on PyPI.
|
||||
Use pip to install it::
|
||||
|
||||
$ pip install uvloop
|
||||
|
@ -72,7 +72,7 @@ manually creating an asyncio event loop:
|
|||
Building From Source
|
||||
--------------------
|
||||
|
||||
To build uvloop, you'll need Python 3.5 or greater:
|
||||
To build uvloop, you'll need Python 3.7 or greater:
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ from the `libuv` Github repository.
|
|||
Build
|
||||
-----
|
||||
|
||||
To build `uvloop`, you'll need ``Cython`` and Python 3.5.
|
||||
To build `uvloop`, you'll need ``Cython`` and Python 3.7.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ uvloop
|
|||
`uvloop` is a fast, drop-in replacement of the built-in asyncio event loop.
|
||||
`uvloop` is released under the MIT license.
|
||||
|
||||
`uvloop` and asyncio, combined with the power of async/await in Python 3.5,
|
||||
`uvloop` and asyncio, combined with the power of async/await in Python 3.7,
|
||||
makes it easier than ever to write high-performance networking code in Python.
|
||||
|
||||
`uvloop` makes asyncio fast. In fact, it is at least 2x faster than nodejs,
|
||||
|
|
|
@ -8,7 +8,7 @@ uvloop.
|
|||
Installation
|
||||
------------
|
||||
|
||||
`uvloop` is available from PyPI. It requires Python 3.5.
|
||||
`uvloop` is available from PyPI. It requires Python 3.7.
|
||||
|
||||
Use pip to install it.
|
||||
|
||||
|
|
9
setup.py
9
setup.py
|
@ -1,11 +1,8 @@
|
|||
import sys
|
||||
|
||||
vi = sys.version_info
|
||||
if vi < (3, 5):
|
||||
raise RuntimeError('uvloop requires Python 3.5 or greater')
|
||||
if vi[:2] == (3, 6):
|
||||
if vi.releaselevel == 'beta' and vi.serial < 3:
|
||||
raise RuntimeError('uvloop requires Python 3.5 or 3.6b3 or greater')
|
||||
if vi < (3, 7):
|
||||
raise RuntimeError('uvloop requires Python 3.7 or greater')
|
||||
|
||||
if sys.platform in ('win32', 'cygwin', 'cli'):
|
||||
raise RuntimeError('uvloop does not support Windows at the moment')
|
||||
|
@ -310,8 +307,6 @@ setup(
|
|||
'Development Status :: 5 - Production/Stable',
|
||||
'Framework :: AsyncIO',
|
||||
'Programming Language :: Python :: 3 :: Only',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
|
|
|
@ -345,9 +345,6 @@ class _TestBase:
|
|||
self.loop.run_until_complete(foo())
|
||||
|
||||
def test_run_until_complete_loop_orphan_future_close_loop(self):
|
||||
if self.implementation == 'asyncio' and sys.version_info < (3, 6, 2):
|
||||
raise unittest.SkipTest('unfixed asyncio')
|
||||
|
||||
async def foo(delay):
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
|
@ -463,9 +460,7 @@ class _TestBase:
|
|||
|
||||
self.loop.set_debug(True)
|
||||
|
||||
if hasattr(self.loop, 'get_exception_handler'):
|
||||
# Available since Python 3.5.2
|
||||
self.assertIsNone(self.loop.get_exception_handler())
|
||||
self.assertIsNone(self.loop.get_exception_handler())
|
||||
self.loop.set_exception_handler(handler)
|
||||
if hasattr(self.loop, 'get_exception_handler'):
|
||||
self.assertIs(self.loop.get_exception_handler(), handler)
|
||||
|
@ -582,31 +577,19 @@ class _TestBase:
|
|||
self.loop.set_task_factory(None)
|
||||
self.assertIsNone(self.loop.get_task_factory())
|
||||
|
||||
def _compile_agen(self, src):
|
||||
try:
|
||||
g = {}
|
||||
exec(src, globals(), g)
|
||||
except SyntaxError:
|
||||
# Python < 3.6
|
||||
raise unittest.SkipTest()
|
||||
else:
|
||||
return g['waiter']
|
||||
|
||||
def test_shutdown_asyncgens_01(self):
|
||||
finalized = list()
|
||||
|
||||
if not hasattr(self.loop, 'shutdown_asyncgens'):
|
||||
raise unittest.SkipTest()
|
||||
|
||||
waiter = self._compile_agen(
|
||||
'''async def waiter(timeout, finalized):
|
||||
try:
|
||||
await asyncio.sleep(timeout)
|
||||
yield 1
|
||||
finally:
|
||||
await asyncio.sleep(0)
|
||||
finalized.append(1)
|
||||
''')
|
||||
async def waiter(timeout, finalized):
|
||||
try:
|
||||
await asyncio.sleep(timeout)
|
||||
yield 1
|
||||
finally:
|
||||
await asyncio.sleep(0)
|
||||
finalized.append(1)
|
||||
|
||||
async def wait():
|
||||
async for _ in waiter(1, finalized):
|
||||
|
@ -641,13 +624,12 @@ class _TestBase:
|
|||
self.assertIn('asyncgen', context)
|
||||
logged += 1
|
||||
|
||||
waiter = self._compile_agen('''async def waiter(timeout):
|
||||
async def waiter(timeout):
|
||||
try:
|
||||
await asyncio.sleep(timeout)
|
||||
yield 1
|
||||
finally:
|
||||
1 / 0
|
||||
''')
|
||||
|
||||
async def wait():
|
||||
async for _ in waiter(1):
|
||||
|
@ -669,10 +651,9 @@ class _TestBase:
|
|||
if not hasattr(self.loop, 'shutdown_asyncgens'):
|
||||
raise unittest.SkipTest()
|
||||
|
||||
waiter = self._compile_agen('''async def waiter():
|
||||
async def waiter():
|
||||
yield 1
|
||||
yield 2
|
||||
''')
|
||||
|
||||
async def foo():
|
||||
# We specifically want to hit _asyncgen_finalizer_hook
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
import asyncio
|
||||
import contextvars
|
||||
import decimal
|
||||
import random
|
||||
import sys
|
||||
import unittest
|
||||
import weakref
|
||||
|
||||
from uvloop import _testbase as tb
|
||||
|
||||
|
||||
PY37 = sys.version_info >= (3, 7, 0)
|
||||
|
||||
|
||||
class _ContextBaseTests:
|
||||
|
||||
@unittest.skipUnless(PY37, 'requires Python 3.7')
|
||||
def test_task_decimal_context(self):
|
||||
async def fractions(t, precision, x, y):
|
||||
with decimal.localcontext() as ctx:
|
||||
|
@ -37,9 +32,7 @@ class _ContextBaseTests:
|
|||
self.assertEqual(str(r2[0]), '0.333333')
|
||||
self.assertEqual(str(r2[1]), '0.111111')
|
||||
|
||||
@unittest.skipUnless(PY37, 'requires Python 3.7')
|
||||
def test_task_context_1(self):
|
||||
import contextvars
|
||||
cvar = contextvars.ContextVar('cvar', default='nope')
|
||||
|
||||
async def sub():
|
||||
|
@ -58,9 +51,7 @@ class _ContextBaseTests:
|
|||
task = self.loop.create_task(main())
|
||||
self.loop.run_until_complete(task)
|
||||
|
||||
@unittest.skipUnless(PY37, 'requires Python 3.7')
|
||||
def test_task_context_2(self):
|
||||
import contextvars
|
||||
cvar = contextvars.ContextVar('cvar', default='nope')
|
||||
|
||||
async def main():
|
||||
|
@ -90,9 +81,7 @@ class _ContextBaseTests:
|
|||
|
||||
self.assertEqual(cvar.get(), 'nope')
|
||||
|
||||
@unittest.skipUnless(PY37, 'requires Python 3.7')
|
||||
def test_task_context_3(self):
|
||||
import contextvars
|
||||
cvar = contextvars.ContextVar('cvar', default=-1)
|
||||
|
||||
# Run 100 Tasks in parallel, each modifying cvar.
|
||||
|
@ -115,9 +104,7 @@ class _ContextBaseTests:
|
|||
|
||||
self.assertEqual(cvar.get(), -1)
|
||||
|
||||
@unittest.skipUnless(PY37, 'requires Python 3.7')
|
||||
def test_task_context_4(self):
|
||||
import contextvars
|
||||
cvar = contextvars.ContextVar('cvar', default='nope')
|
||||
|
||||
class TrackMe:
|
||||
|
@ -141,23 +128,7 @@ class _ContextBaseTests:
|
|||
|
||||
|
||||
class Test_UV_Context(_ContextBaseTests, tb.UVTestCase):
|
||||
|
||||
@unittest.skipIf(PY37, 'requires Python <3.6')
|
||||
def test_context_arg(self):
|
||||
def cb():
|
||||
pass
|
||||
|
||||
with self.assertRaisesRegex(NotImplementedError,
|
||||
'requires Python 3.7'):
|
||||
self.loop.call_soon(cb, context=1)
|
||||
|
||||
with self.assertRaisesRegex(NotImplementedError,
|
||||
'requires Python 3.7'):
|
||||
self.loop.call_soon_threadsafe(cb, context=1)
|
||||
|
||||
with self.assertRaisesRegex(NotImplementedError,
|
||||
'requires Python 3.7'):
|
||||
self.loop.call_later(0.1, cb, context=1)
|
||||
pass
|
||||
|
||||
|
||||
class Test_AIO_Context(_ContextBaseTests, tb.AIOTestCase):
|
||||
|
|
|
@ -21,10 +21,6 @@ class _TestSockets:
|
|||
return buf
|
||||
|
||||
def test_socket_connect_recv_send(self):
|
||||
if self.is_asyncio_loop() and sys.version_info[:3] == (3, 5, 2):
|
||||
# See https://github.com/python/asyncio/pull/366 for details.
|
||||
raise unittest.SkipTest()
|
||||
|
||||
if sys.version_info[:3] >= (3, 8, 0):
|
||||
# @asyncio.coroutine is deprecated in 3.8
|
||||
raise unittest.SkipTest()
|
||||
|
|
|
@ -10,8 +10,6 @@ def find_uvloop_root():
|
|||
|
||||
class TestFlake8(unittest.TestCase):
|
||||
|
||||
@unittest.skipIf(sys.version_info < (3, 6, 0),
|
||||
"flake8 under 3.5 does not recognize f-strings in *.pyx")
|
||||
def test_flake8(self):
|
||||
edgepath = find_uvloop_root()
|
||||
config_path = os.path.join(edgepath, '.flake8')
|
||||
|
|
|
@ -5,7 +5,6 @@ import os
|
|||
import select
|
||||
import socket
|
||||
import unittest.mock
|
||||
import uvloop
|
||||
import ssl
|
||||
import sys
|
||||
import threading
|
||||
|
@ -55,10 +54,6 @@ class MyBaseProto(asyncio.Protocol):
|
|||
|
||||
class _TestTCP:
|
||||
def test_create_server_1(self):
|
||||
if self.is_asyncio_loop() and sys.version_info[:3] == (3, 5, 2):
|
||||
# See https://github.com/python/asyncio/pull/366 for details.
|
||||
raise unittest.SkipTest()
|
||||
|
||||
CNT = 0 # number of clients that were successful
|
||||
TOTAL_CNT = 25 # total number of clients that test will create
|
||||
TIMEOUT = 5.0 # timeout for this test
|
||||
|
@ -118,21 +113,14 @@ class _TestTCP:
|
|||
nonlocal CNT
|
||||
CNT = 0
|
||||
|
||||
addrs = ('127.0.0.1', 'localhost')
|
||||
if not isinstance(self.loop, uvloop.Loop):
|
||||
# Hack to let tests run on Python 3.5.0
|
||||
# (asyncio doesn't support multiple hosts in 3.5.0)
|
||||
addrs = '127.0.0.1'
|
||||
|
||||
srv = await asyncio.start_server(
|
||||
handle_client,
|
||||
addrs, 0,
|
||||
('127.0.0.1', 'localhost'), 0,
|
||||
family=socket.AF_INET)
|
||||
|
||||
srv_socks = srv.sockets
|
||||
self.assertTrue(srv_socks)
|
||||
if self.has_start_serving():
|
||||
self.assertTrue(srv.is_serving())
|
||||
self.assertTrue(srv.is_serving())
|
||||
|
||||
addr = srv_socks[0].getsockname()
|
||||
|
||||
|
@ -149,8 +137,7 @@ class _TestTCP:
|
|||
for srv_sock in srv_socks:
|
||||
self.assertEqual(srv_sock.fileno(), -1)
|
||||
|
||||
if self.has_start_serving():
|
||||
self.assertFalse(srv.is_serving())
|
||||
self.assertFalse(srv.is_serving())
|
||||
|
||||
async def start_server_sock():
|
||||
nonlocal CNT
|
||||
|
@ -166,13 +153,11 @@ class _TestTCP:
|
|||
family=socket.AF_INET,
|
||||
sock=sock)
|
||||
|
||||
if self.PY37:
|
||||
self.assertIs(srv.get_loop(), self.loop)
|
||||
self.assertIs(srv.get_loop(), self.loop)
|
||||
|
||||
srv_socks = srv.sockets
|
||||
self.assertTrue(srv_socks)
|
||||
if self.has_start_serving():
|
||||
self.assertTrue(srv.is_serving())
|
||||
self.assertTrue(srv.is_serving())
|
||||
|
||||
tasks = []
|
||||
for _ in range(TOTAL_CNT):
|
||||
|
@ -187,8 +172,7 @@ class _TestTCP:
|
|||
for srv_sock in srv_socks:
|
||||
self.assertEqual(srv_sock.fileno(), -1)
|
||||
|
||||
if self.has_start_serving():
|
||||
self.assertFalse(srv.is_serving())
|
||||
self.assertFalse(srv.is_serving())
|
||||
|
||||
self.loop.run_until_complete(start_server())
|
||||
self.assertEqual(CNT, TOTAL_CNT)
|
||||
|
@ -213,8 +197,7 @@ class _TestTCP:
|
|||
|
||||
srv_socks = srv.sockets
|
||||
self.assertTrue(srv_socks)
|
||||
if self.has_start_serving():
|
||||
self.assertTrue(srv.is_serving())
|
||||
self.assertTrue(srv.is_serving())
|
||||
|
||||
host, port = srv_socks[0].getsockname()
|
||||
self.assertNotEqual(0, port)
|
||||
|
@ -226,8 +209,7 @@ class _TestTCP:
|
|||
for srv_sock in srv_socks:
|
||||
self.assertEqual(srv_sock.fileno(), -1)
|
||||
|
||||
if self.has_start_serving():
|
||||
self.assertFalse(srv.is_serving())
|
||||
self.assertFalse(srv.is_serving())
|
||||
|
||||
self.loop.run_until_complete(start_server_ephemeral_ports())
|
||||
|
||||
|
@ -267,11 +249,6 @@ class _TestTCP:
|
|||
raise unittest.SkipTest(
|
||||
'The system does not support SO_REUSEPORT')
|
||||
|
||||
if sys.version_info[:3] < (3, 5, 1):
|
||||
raise unittest.SkipTest(
|
||||
'asyncio in CPython 3.5.0 does not have the '
|
||||
'reuse_port argument')
|
||||
|
||||
port = tb.find_free_port()
|
||||
|
||||
async def runner():
|
||||
|
@ -338,9 +315,6 @@ class _TestTCP:
|
|||
self.loop.run_until_complete(test())
|
||||
|
||||
def test_create_server_8(self):
|
||||
if self.implementation == 'asyncio' and not self.PY37:
|
||||
raise unittest.SkipTest()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, 'ssl_handshake_timeout is only meaningful'):
|
||||
self.loop.run_until_complete(
|
||||
|
@ -348,9 +322,6 @@ class _TestTCP:
|
|||
lambda: None, host='::', port=0, ssl_handshake_timeout=10))
|
||||
|
||||
def test_create_server_9(self):
|
||||
if not self.has_start_serving():
|
||||
raise unittest.SkipTest()
|
||||
|
||||
async def handle_client(reader, writer):
|
||||
pass
|
||||
|
||||
|
@ -375,9 +346,6 @@ class _TestTCP:
|
|||
self.loop.run_until_complete(start_server())
|
||||
|
||||
def test_create_server_10(self):
|
||||
if not self.has_start_serving():
|
||||
raise unittest.SkipTest()
|
||||
|
||||
async def handle_client(reader, writer):
|
||||
pass
|
||||
|
||||
|
@ -578,9 +546,6 @@ class _TestTCP:
|
|||
self.loop.run_until_complete(client(srv.addr))
|
||||
|
||||
def test_create_connection_6(self):
|
||||
if self.implementation == 'asyncio' and not self.PY37:
|
||||
raise unittest.SkipTest()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, 'ssl_handshake_timeout is only meaningful'):
|
||||
self.loop.run_until_complete(
|
||||
|
@ -1093,9 +1058,6 @@ class Test_UV_TCP(_TestTCP, tb.UVTestCase):
|
|||
self.loop.run_until_complete(srv.wait_closed())
|
||||
|
||||
def test_connect_accepted_socket_ssl_args(self):
|
||||
if self.implementation == 'asyncio' and not self.PY37:
|
||||
raise unittest.SkipTest()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, 'ssl_handshake_timeout is only meaningful'):
|
||||
with socket.socket() as s:
|
||||
|
@ -1152,7 +1114,7 @@ class Test_UV_TCP(_TestTCP, tb.UVTestCase):
|
|||
proto.loop = loop
|
||||
|
||||
extras = {}
|
||||
if server_ssl and (self.implementation != 'asyncio' or self.PY37):
|
||||
if server_ssl:
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
|
||||
f = loop.create_task(
|
||||
|
@ -1318,9 +1280,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
await fut
|
||||
|
||||
async def start_server():
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
|
||||
srv = await asyncio.start_server(
|
||||
handle_client,
|
||||
|
@ -1383,9 +1343,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
sock.close()
|
||||
|
||||
async def client(addr):
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
|
||||
reader, writer = await asyncio.open_connection(
|
||||
*addr,
|
||||
|
@ -1517,10 +1475,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
max_clients=1,
|
||||
backlog=1) as srv:
|
||||
|
||||
exc_type = ssl.SSLError
|
||||
if self.PY37:
|
||||
exc_type = ssl.SSLCertVerificationError
|
||||
with self.assertRaises(exc_type):
|
||||
with self.assertRaises(ssl.SSLCertVerificationError):
|
||||
self.loop.run_until_complete(client(srv.addr))
|
||||
|
||||
def test_start_tls_wrong_args(self):
|
||||
|
@ -2190,9 +2145,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
await fut
|
||||
|
||||
async def start_server():
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
|
||||
srv = await self.loop.create_server(
|
||||
server_protocol_factory,
|
||||
|
@ -2282,9 +2235,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
conn.shutdown()
|
||||
|
||||
async def client(addr):
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
|
||||
reader, writer = await asyncio.open_connection(
|
||||
*addr,
|
||||
|
@ -2408,9 +2359,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
await fut
|
||||
|
||||
async def start_server():
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras['ssl_handshake_timeout'] = SSL_HANDSHAKE_TIMEOUT
|
||||
extras = {'ssl_handshake_timeout': SSL_HANDSHAKE_TIMEOUT}
|
||||
if self.implementation != 'asyncio': # or self.PY38
|
||||
extras['ssl_shutdown_timeout'] = 0.5
|
||||
|
||||
|
@ -2473,9 +2422,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
sock.close()
|
||||
|
||||
async def client(addr):
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
extras = dict(ssl_handshake_timeout=SSL_HANDSHAKE_TIMEOUT)
|
||||
|
||||
reader, writer = await asyncio.open_connection(
|
||||
*addr,
|
||||
|
|
|
@ -64,8 +64,7 @@ class _TestUDP:
|
|||
self.assertIs(server.transport, s_transport)
|
||||
|
||||
extra = {}
|
||||
if hasattr(socket, 'SO_REUSEPORT') and \
|
||||
sys.version_info[:3] >= (3, 5, 1):
|
||||
if hasattr(socket, 'SO_REUSEPORT'):
|
||||
extra['reuse_port'] = True
|
||||
|
||||
coro = self.loop.create_datagram_endpoint(
|
||||
|
@ -179,21 +178,13 @@ class _TestUDP:
|
|||
assert False, 'Can not create socket.'
|
||||
|
||||
with sock:
|
||||
try:
|
||||
f = self.loop.create_datagram_endpoint(
|
||||
lambda: MyDatagramProto(loop=self.loop), sock=sock)
|
||||
except TypeError as ex:
|
||||
# asyncio in 3.5.0 doesn't have the 'sock' argument
|
||||
if 'got an unexpected keyword argument' not in ex.args[0]:
|
||||
raise
|
||||
else:
|
||||
tr, pr = self.loop.run_until_complete(f)
|
||||
self.assertIsInstance(pr, MyDatagramProto)
|
||||
tr.close()
|
||||
self.loop.run_until_complete(pr.done)
|
||||
f = self.loop.create_datagram_endpoint(
|
||||
lambda: MyDatagramProto(loop=self.loop), sock=sock)
|
||||
tr, pr = self.loop.run_until_complete(f)
|
||||
self.assertIsInstance(pr, MyDatagramProto)
|
||||
tr.close()
|
||||
self.loop.run_until_complete(pr.done)
|
||||
|
||||
@unittest.skipIf(sys.version_info < (3, 5, 1),
|
||||
"asyncio in 3.5.0 doesn't have the 'sock' argument")
|
||||
def test_create_datagram_endpoint_sock_unix_domain(self):
|
||||
|
||||
class Proto(asyncio.DatagramProtocol):
|
||||
|
@ -295,38 +286,32 @@ class _TestUDP:
|
|||
s1, s2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM, 0)
|
||||
|
||||
with s1, s2:
|
||||
try:
|
||||
f = self.loop.create_datagram_endpoint(
|
||||
lambda: Proto(loop=self.loop), sock=s1)
|
||||
except TypeError as ex:
|
||||
# asyncio in 3.5.0 doesn't have the 'sock' argument
|
||||
if 'got an unexpected keyword argument' not in ex.args[0]:
|
||||
raise
|
||||
f = self.loop.create_datagram_endpoint(
|
||||
lambda: Proto(loop=self.loop), sock=s1)
|
||||
tr, pr = self.loop.run_until_complete(f)
|
||||
self.assertIsInstance(pr, Proto)
|
||||
|
||||
s2.send(b'hello, socketpair')
|
||||
addr = self.loop.run_until_complete(
|
||||
asyncio.wait_for(peername, 1))
|
||||
if sys.platform.startswith('linux'):
|
||||
self.assertEqual(addr, None)
|
||||
else:
|
||||
tr, pr = self.loop.run_until_complete(f)
|
||||
self.assertIsInstance(pr, Proto)
|
||||
self.assertEqual(addr, '')
|
||||
self.assertEqual(pr.nbytes, 17)
|
||||
|
||||
s2.send(b'hello, socketpair')
|
||||
addr = self.loop.run_until_complete(
|
||||
asyncio.wait_for(peername, 1))
|
||||
if sys.platform.startswith('linux'):
|
||||
self.assertEqual(addr, None)
|
||||
else:
|
||||
self.assertEqual(addr, '')
|
||||
self.assertEqual(pr.nbytes, 17)
|
||||
if not self.is_asyncio_loop():
|
||||
# asyncio doesn't support sendto(xx) on UDP sockets
|
||||
# https://git.io/Jfqbw
|
||||
data = b'from uvloop'
|
||||
tr.sendto(data)
|
||||
result = self.loop.run_until_complete(asyncio.wait_for(
|
||||
self.loop.run_in_executor(None, s2.recv, 1024),
|
||||
1))
|
||||
self.assertEqual(data, result)
|
||||
|
||||
if not self.is_asyncio_loop():
|
||||
# asyncio doesn't support sendto(xx) on UDP sockets
|
||||
# https://git.io/Jfqbw
|
||||
data = b'from uvloop'
|
||||
tr.sendto(data)
|
||||
result = self.loop.run_until_complete(asyncio.wait_for(
|
||||
self.loop.run_in_executor(None, s2.recv, 1024),
|
||||
1))
|
||||
self.assertEqual(data, result)
|
||||
|
||||
tr.close()
|
||||
self.loop.run_until_complete(pr.done)
|
||||
tr.close()
|
||||
self.loop.run_until_complete(pr.done)
|
||||
|
||||
def _skip_create_datagram_endpoint_reuse_addr(self):
|
||||
if self.implementation == 'asyncio':
|
||||
|
@ -336,8 +321,6 @@ class _TestUDP:
|
|||
raise unittest.SkipTest()
|
||||
if (3, 7, 0) <= sys.version_info < (3, 7, 6):
|
||||
raise unittest.SkipTest()
|
||||
if sys.version_info < (3, 6, 10):
|
||||
raise unittest.SkipTest()
|
||||
|
||||
def test_create_datagram_endpoint_reuse_address_error(self):
|
||||
# bpo-37228: Ensure that explicit passing of `reuse_address=True`
|
||||
|
@ -418,8 +401,8 @@ class Test_UV_UDP(_TestUDP, tb.UVTestCase):
|
|||
class Test_AIO_UDP(_TestUDP, tb.AIOTestCase):
|
||||
@unittest.skipUnless(tb.has_IPv6, 'no IPv6')
|
||||
@unittest.skipIf(
|
||||
sys.version_info[:3] < (3, 6, 7) or sys.version_info[:3] == (3, 7, 0),
|
||||
'bpo-27500: bug fixed in Python 3.6.7, 3.7.1 and above.',
|
||||
sys.version_info[:3] == (3, 7, 0),
|
||||
'bpo-27500: bug fixed in Python 3.7.1 and above.',
|
||||
)
|
||||
def test_create_datagram_endpoint_addrs_ipv6(self):
|
||||
self._test_create_datagram_endpoint_addrs_ipv6()
|
||||
|
|
|
@ -66,8 +66,7 @@ class _TestUnix:
|
|||
try:
|
||||
srv_socks = srv.sockets
|
||||
self.assertTrue(srv_socks)
|
||||
if self.has_start_serving():
|
||||
self.assertTrue(srv.is_serving())
|
||||
self.assertTrue(srv.is_serving())
|
||||
|
||||
tasks = []
|
||||
for _ in range(TOTAL_CNT):
|
||||
|
@ -83,8 +82,7 @@ class _TestUnix:
|
|||
for srv_sock in srv_socks:
|
||||
self.assertEqual(srv_sock.fileno(), -1)
|
||||
|
||||
if self.has_start_serving():
|
||||
self.assertFalse(srv.is_serving())
|
||||
self.assertFalse(srv.is_serving())
|
||||
|
||||
# asyncio doesn't cleanup the sock file
|
||||
self.assertTrue(os.path.exists(sock_name))
|
||||
|
@ -103,8 +101,7 @@ class _TestUnix:
|
|||
try:
|
||||
srv_socks = srv.sockets
|
||||
self.assertTrue(srv_socks)
|
||||
if self.has_start_serving():
|
||||
self.assertTrue(srv.is_serving())
|
||||
self.assertTrue(srv.is_serving())
|
||||
|
||||
tasks = []
|
||||
for _ in range(TOTAL_CNT):
|
||||
|
@ -120,8 +117,7 @@ class _TestUnix:
|
|||
for srv_sock in srv_socks:
|
||||
self.assertEqual(srv_sock.fileno(), -1)
|
||||
|
||||
if self.has_start_serving():
|
||||
self.assertFalse(srv.is_serving())
|
||||
self.assertFalse(srv.is_serving())
|
||||
|
||||
# asyncio doesn't cleanup the sock file
|
||||
self.assertTrue(os.path.exists(sock_name))
|
||||
|
@ -160,9 +156,6 @@ class _TestUnix:
|
|||
self.loop.create_unix_server(object, sock_name))
|
||||
|
||||
def test_create_unix_server_3(self):
|
||||
if self.implementation == 'asyncio' and not self.PY37:
|
||||
raise unittest.SkipTest()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, 'ssl_handshake_timeout is only meaningful'):
|
||||
self.loop.run_until_complete(
|
||||
|
@ -371,30 +364,12 @@ class _TestUnix:
|
|||
(BrokenPipeError, ConnectionResetError))
|
||||
|
||||
def test_create_unix_connection_6(self):
|
||||
if self.implementation == 'asyncio' and not self.PY37:
|
||||
raise unittest.SkipTest()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, 'ssl_handshake_timeout is only meaningful'):
|
||||
self.loop.run_until_complete(
|
||||
self.loop.create_unix_connection(
|
||||
lambda: None, path='/tmp/a', ssl_handshake_timeout=10))
|
||||
|
||||
@unittest.skipUnless(sys.version_info < (3, 7),
|
||||
'Python version must be < 3.7')
|
||||
def test_transport_unclosed_warning(self):
|
||||
async def test(sock):
|
||||
return await self.loop.create_unix_connection(
|
||||
asyncio.Protocol,
|
||||
None,
|
||||
sock=sock)
|
||||
|
||||
with self.assertWarnsRegex(ResourceWarning, 'unclosed'):
|
||||
s1, s2 = socket.socketpair(socket.AF_UNIX)
|
||||
with s1, s2:
|
||||
self.loop.run_until_complete(test(s1))
|
||||
self.loop.close()
|
||||
|
||||
|
||||
class Test_UV_Unix(_TestUnix, tb.UVTestCase):
|
||||
|
||||
|
@ -592,9 +567,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
await fut
|
||||
|
||||
async def start_server():
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=10.0)
|
||||
extras = dict(ssl_handshake_timeout=10.0)
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
sock_name = os.path.join(td, 'sock')
|
||||
|
@ -655,9 +628,7 @@ class _TestSSL(tb.SSLTestCase):
|
|||
sock.close()
|
||||
|
||||
async def client(addr):
|
||||
extras = {}
|
||||
if self.implementation != 'asyncio' or self.PY37:
|
||||
extras = dict(ssl_handshake_timeout=10.0)
|
||||
extras = dict(ssl_handshake_timeout=10.0)
|
||||
|
||||
reader, writer = await asyncio.open_unix_connection(
|
||||
addr,
|
||||
|
|
|
@ -3,7 +3,6 @@ import asyncio as __asyncio
|
|||
from asyncio.events import BaseDefaultEventLoopPolicy as __BasePolicy
|
||||
|
||||
from . import includes as __includes # NOQA
|
||||
from . import _patch # NOQA
|
||||
from .loop import Loop as __BaseLoop # NOQA
|
||||
from ._version import __version__ # NOQA
|
||||
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
import asyncio
|
||||
import sys
|
||||
|
||||
|
||||
def _format_coroutine(coro):
|
||||
if asyncio.iscoroutine(coro) \
|
||||
and not hasattr(coro, 'cr_code') \
|
||||
and not hasattr(coro, 'gi_code'):
|
||||
|
||||
# Most likely a Cython coroutine
|
||||
coro_name = '{}()'.format(coro.__qualname__ or coro.__name__)
|
||||
|
||||
running = False
|
||||
try:
|
||||
running = coro.cr_running
|
||||
except AttributeError:
|
||||
try:
|
||||
running = coro.gi_running
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if running:
|
||||
return '{} running'.format(coro_name)
|
||||
else:
|
||||
return coro_name
|
||||
|
||||
return _old_format_coroutine(coro)
|
||||
|
||||
|
||||
async def _wait_for_data(self, func_name):
|
||||
"""Wait until feed_data() or feed_eof() is called.
|
||||
|
||||
If stream was paused, automatically resume it.
|
||||
"""
|
||||
if self._waiter is not None:
|
||||
raise RuntimeError('%s() called while another coroutine is '
|
||||
'already waiting for incoming data' % func_name)
|
||||
|
||||
assert not self._eof, '_wait_for_data after EOF'
|
||||
|
||||
# Waiting for data while paused will make deadlock, so prevent it.
|
||||
if self._paused:
|
||||
self._paused = False
|
||||
self._transport.resume_reading()
|
||||
|
||||
try:
|
||||
create_future = self._loop.create_future
|
||||
except AttributeError:
|
||||
self._waiter = asyncio.Future(loop=self._loop)
|
||||
else:
|
||||
self._waiter = create_future()
|
||||
|
||||
try:
|
||||
await self._waiter
|
||||
finally:
|
||||
self._waiter = None
|
||||
|
||||
|
||||
if sys.version_info < (3, 5, 3):
|
||||
# This is needed to support Cython 'async def' coroutines.
|
||||
from asyncio import coroutines
|
||||
_old_format_coroutine = coroutines._format_coroutine
|
||||
coroutines._format_coroutine = _format_coroutine
|
||||
|
||||
if sys.version_info < (3, 5, 2):
|
||||
# Fix a possible deadlock, improve performance.
|
||||
from asyncio import streams
|
||||
_old_wait_for_data = streams.StreamReader._wait_for_data
|
||||
_wait_for_data.__module__ = _old_wait_for_data.__module__
|
||||
streams.StreamReader._wait_for_data = _wait_for_data
|
|
@ -13,7 +13,6 @@ import re
|
|||
import select
|
||||
import socket
|
||||
import ssl
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
|
@ -73,15 +72,10 @@ class BaseTestCase(unittest.TestCase, metaclass=BaseTestCaseMeta):
|
|||
async def wait_closed(self, obj):
|
||||
if not isinstance(obj, asyncio.StreamWriter):
|
||||
return
|
||||
if sys.version_info >= (3, 7, 0):
|
||||
try:
|
||||
await obj.wait_closed()
|
||||
except (BrokenPipeError, ConnectionError):
|
||||
pass
|
||||
|
||||
def has_start_serving(self):
|
||||
return not (self.is_asyncio_loop() and
|
||||
sys.version_info[:2] in [(3, 5), (3, 6)])
|
||||
try:
|
||||
await obj.wait_closed()
|
||||
except (BrokenPipeError, ConnectionError):
|
||||
pass
|
||||
|
||||
def is_asyncio_loop(self):
|
||||
return type(self.loop).__module__.startswith('asyncio.')
|
||||
|
@ -102,9 +96,6 @@ class BaseTestCase(unittest.TestCase, metaclass=BaseTestCaseMeta):
|
|||
self.loop.set_exception_handler(self.loop_exception_handler)
|
||||
self.__unhandled_exceptions = []
|
||||
|
||||
self.PY37 = sys.version_info[:2] >= (3, 7)
|
||||
self.PY36 = sys.version_info[:2] >= (3, 6)
|
||||
|
||||
def tearDown(self):
|
||||
self.loop.close()
|
||||
|
||||
|
|
|
@ -15,15 +15,9 @@ cdef class Handle:
|
|||
self._source_traceback = extract_stack()
|
||||
|
||||
cdef inline _set_context(self, object context):
|
||||
if PY37:
|
||||
if context is None:
|
||||
context = Context_CopyCurrent()
|
||||
self.context = context
|
||||
else:
|
||||
if context is not None:
|
||||
raise NotImplementedError(
|
||||
'"context" argument requires Python 3.7')
|
||||
self.context = None
|
||||
if context is None:
|
||||
context = Context_CopyCurrent()
|
||||
self.context = context
|
||||
|
||||
def __dealloc__(self):
|
||||
if UVLOOP_DEBUG and self.loop is not None:
|
||||
|
@ -52,9 +46,8 @@ cdef class Handle:
|
|||
Py_INCREF(self)
|
||||
|
||||
try:
|
||||
if PY37:
|
||||
assert self.context is not None
|
||||
Context_Enter(self.context)
|
||||
assert self.context is not None
|
||||
Context_Enter(self.context)
|
||||
|
||||
if cb_type == 1:
|
||||
callback = self.arg1
|
||||
|
@ -108,8 +101,7 @@ cdef class Handle:
|
|||
finally:
|
||||
context = self.context
|
||||
Py_DECREF(self)
|
||||
if PY37:
|
||||
Context_Exit(context)
|
||||
Context_Exit(context)
|
||||
|
||||
cdef _cancel(self):
|
||||
self._cancelled = 1
|
||||
|
@ -185,15 +177,9 @@ cdef class TimerHandle:
|
|||
self.loop._debug_cb_timer_handles_total += 1
|
||||
self.loop._debug_cb_timer_handles_count += 1
|
||||
|
||||
if PY37:
|
||||
if context is None:
|
||||
context = Context_CopyCurrent()
|
||||
self.context = context
|
||||
else:
|
||||
if context is not None:
|
||||
raise NotImplementedError(
|
||||
'"context" argument requires Python 3.7')
|
||||
self.context = None
|
||||
if context is None:
|
||||
context = Context_CopyCurrent()
|
||||
self.context = context
|
||||
|
||||
if loop._debug:
|
||||
self._debug_info = (
|
||||
|
@ -257,9 +243,8 @@ cdef class TimerHandle:
|
|||
if self.loop._debug:
|
||||
started = time_monotonic()
|
||||
try:
|
||||
if PY37:
|
||||
assert self.context is not None
|
||||
Context_Enter(self.context)
|
||||
assert self.context is not None
|
||||
Context_Enter(self.context)
|
||||
|
||||
if args is not None:
|
||||
callback(*args)
|
||||
|
@ -288,8 +273,7 @@ cdef class TimerHandle:
|
|||
finally:
|
||||
context = self.context
|
||||
Py_DECREF(self)
|
||||
if PY37:
|
||||
Context_Exit(context)
|
||||
Context_Exit(context)
|
||||
self._clear()
|
||||
|
||||
# Public API
|
||||
|
|
|
@ -252,14 +252,7 @@ cdef class UVProcess(UVHandle):
|
|||
self.options.flags |= uv.UV_PROCESS_DETACHED
|
||||
|
||||
if cwd is not None:
|
||||
try:
|
||||
# Lookup __fspath__ manually, as os.fspath() isn't
|
||||
# available on Python 3.5.
|
||||
fspath = type(cwd).__fspath__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
cwd = fspath(cwd)
|
||||
cwd = os_fspath(cwd)
|
||||
|
||||
if isinstance(cwd, str):
|
||||
cwd = PyUnicode_EncodeFSDefault(cwd)
|
||||
|
@ -283,14 +276,7 @@ cdef class UVProcess(UVHandle):
|
|||
|
||||
self.__args = args.copy()
|
||||
for i in range(an):
|
||||
arg = args[i]
|
||||
try:
|
||||
fspath = type(arg).__fspath__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
arg = fspath(arg)
|
||||
|
||||
arg = os_fspath(args[i])
|
||||
if isinstance(arg, str):
|
||||
self.__args[i] = PyUnicode_EncodeFSDefault(arg)
|
||||
elif not isinstance(arg, bytes):
|
||||
|
|
|
@ -54,27 +54,7 @@ MakeUnixSockPyAddr(struct sockaddr_un *addr)
|
|||
}
|
||||
|
||||
|
||||
#if PY_VERSION_HEX < 0x03070000
|
||||
|
||||
PyObject * Context_CopyCurrent(void) {
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"\"contextvars\" support requires Python 3.7+");
|
||||
return NULL;
|
||||
};
|
||||
|
||||
int Context_Enter(PyObject *ctx) {
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"\"contextvars\" support requires Python 3.7+");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Context_Exit(PyObject *ctx) {
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"\"contextvars\" support requires Python 3.7+");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#elif PY_VERSION_HEX < 0x03070100
|
||||
#if PY_VERSION_HEX < 0x03070100
|
||||
|
||||
PyObject * Context_CopyCurrent(void) {
|
||||
return (PyObject *)PyContext_CopyCurrent();
|
||||
|
@ -103,26 +83,3 @@ int Context_Exit(PyObject *ctx) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_VERSION_HEX < 0x03070000
|
||||
|
||||
void PyOS_BeforeFork(void)
|
||||
{
|
||||
_PyImport_AcquireLock();
|
||||
}
|
||||
|
||||
void PyOS_AfterFork_Parent(void)
|
||||
{
|
||||
if (_PyImport_ReleaseLock() <= 0) {
|
||||
Py_FatalError("failed releasing import lock after fork");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PyOS_AfterFork_Child(void)
|
||||
{
|
||||
PyOS_AfterFork();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -111,6 +111,7 @@ cdef os_pipe = os.pipe
|
|||
cdef os_read = os.read
|
||||
cdef os_remove = os.remove
|
||||
cdef os_stat = os.stat
|
||||
cdef os_fspath = os.fspath
|
||||
|
||||
cdef stat_S_ISSOCK = stat.S_ISSOCK
|
||||
|
||||
|
|
107
uvloop/loop.pyx
107
uvloop/loop.pyx
|
@ -49,8 +49,6 @@ include "errors.pyx"
|
|||
|
||||
cdef:
|
||||
int PY39 = PY_VERSION_HEX >= 0x03090000
|
||||
int PY37 = PY_VERSION_HEX >= 0x03070000
|
||||
int PY36 = PY_VERSION_HEX >= 0x03060000
|
||||
uint64_t MAX_SLEEP = 3600 * 24 * 365 * 100
|
||||
|
||||
|
||||
|
@ -177,13 +175,9 @@ cdef class Loop:
|
|||
|
||||
self._coroutine_debug_set = False
|
||||
|
||||
if hasattr(sys, 'get_asyncgen_hooks'):
|
||||
# Python >= 3.6
|
||||
# A weak set of all asynchronous generators that are
|
||||
# being iterated by the loop.
|
||||
self._asyncgens = weakref_WeakSet()
|
||||
else:
|
||||
self._asyncgens = None
|
||||
# A weak set of all asynchronous generators that are
|
||||
# being iterated by the loop.
|
||||
self._asyncgens = weakref_WeakSet()
|
||||
|
||||
# Set to True when `loop.shutdown_asyncgens` is called.
|
||||
self._asyncgens_shutdown_called = False
|
||||
|
@ -1100,39 +1094,16 @@ cdef class Loop:
|
|||
if self._coroutine_debug_set == enabled:
|
||||
return
|
||||
|
||||
if PY37:
|
||||
if enabled:
|
||||
self._coroutine_origin_tracking_saved_depth = (
|
||||
sys.get_coroutine_origin_tracking_depth())
|
||||
sys.set_coroutine_origin_tracking_depth(
|
||||
DEBUG_STACK_DEPTH)
|
||||
else:
|
||||
sys.set_coroutine_origin_tracking_depth(
|
||||
self._coroutine_origin_tracking_saved_depth)
|
||||
|
||||
self._coroutine_debug_set = enabled
|
||||
if enabled:
|
||||
self._coroutine_origin_tracking_saved_depth = (
|
||||
sys.get_coroutine_origin_tracking_depth())
|
||||
sys.set_coroutine_origin_tracking_depth(
|
||||
DEBUG_STACK_DEPTH)
|
||||
else:
|
||||
wrapper = aio_debug_wrapper
|
||||
current_wrapper = sys_get_coroutine_wrapper()
|
||||
sys.set_coroutine_origin_tracking_depth(
|
||||
self._coroutine_origin_tracking_saved_depth)
|
||||
|
||||
if enabled:
|
||||
if current_wrapper not in (None, wrapper):
|
||||
_warn_with_source(
|
||||
"loop.set_debug(True): cannot set debug coroutine "
|
||||
"wrapper; another wrapper is already set %r" %
|
||||
current_wrapper, RuntimeWarning, self)
|
||||
else:
|
||||
sys_set_coroutine_wrapper(wrapper)
|
||||
self._coroutine_debug_set = True
|
||||
else:
|
||||
if current_wrapper not in (None, wrapper):
|
||||
_warn_with_source(
|
||||
"loop.set_debug(False): cannot unset debug coroutine "
|
||||
"wrapper; another wrapper was set %r" %
|
||||
current_wrapper, RuntimeWarning, self)
|
||||
else:
|
||||
sys_set_coroutine_wrapper(None)
|
||||
self._coroutine_debug_set = False
|
||||
self._coroutine_debug_set = enabled
|
||||
|
||||
def _get_backend_id(self):
|
||||
"""This method is used by uvloop tests and is not part of the API."""
|
||||
|
@ -1352,16 +1323,14 @@ cdef class Loop:
|
|||
# This is how asyncio loop behaves.
|
||||
mode = uv.UV_RUN_NOWAIT
|
||||
self._set_coroutine_debug(self._debug)
|
||||
if self._asyncgens is not None:
|
||||
old_agen_hooks = sys.get_asyncgen_hooks()
|
||||
sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
|
||||
finalizer=self._asyncgen_finalizer_hook)
|
||||
old_agen_hooks = sys.get_asyncgen_hooks()
|
||||
sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
|
||||
finalizer=self._asyncgen_finalizer_hook)
|
||||
try:
|
||||
self._run(mode)
|
||||
finally:
|
||||
self._set_coroutine_debug(False)
|
||||
if self._asyncgens is not None:
|
||||
sys.set_asyncgen_hooks(*old_agen_hooks)
|
||||
sys.set_asyncgen_hooks(*old_agen_hooks)
|
||||
|
||||
def close(self):
|
||||
"""Close the event loop.
|
||||
|
@ -1509,11 +1478,8 @@ cdef class Loop:
|
|||
if sl > 2:
|
||||
flowinfo = sockaddr[2]
|
||||
if flowinfo < 0 or flowinfo > 0xfffff:
|
||||
if PY37:
|
||||
msg = 'getnameinfo(): flowinfo must be 0-1048575.'
|
||||
else:
|
||||
msg = 'getsockaddrarg: flowinfo must be 0-1048575.'
|
||||
raise OverflowError(msg)
|
||||
raise OverflowError(
|
||||
'getnameinfo(): flowinfo must be 0-1048575.')
|
||||
else:
|
||||
flowinfo = 0
|
||||
|
||||
|
@ -2095,14 +2061,7 @@ cdef class Loop:
|
|||
'path and sock can not be specified at the same time')
|
||||
orig_path = path
|
||||
|
||||
try:
|
||||
# Lookup __fspath__ manually, as os.fspath() isn't
|
||||
# available on Python 3.5.
|
||||
fspath = type(path).__fspath__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
path = fspath(path)
|
||||
path = os_fspath(path)
|
||||
|
||||
if isinstance(path, str):
|
||||
path = PyUnicode_EncodeFSDefault(path)
|
||||
|
@ -2221,14 +2180,7 @@ cdef class Loop:
|
|||
raise ValueError(
|
||||
'path and sock can not be specified at the same time')
|
||||
|
||||
try:
|
||||
# Lookup __fspath__ manually, as os.fspath() isn't
|
||||
# available on Python 3.5.
|
||||
fspath = type(path).__fspath__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
path = fspath(path)
|
||||
path = os_fspath(path)
|
||||
|
||||
if isinstance(path, str):
|
||||
path = PyUnicode_EncodeFSDefault(path)
|
||||
|
@ -2850,13 +2802,13 @@ cdef class Loop:
|
|||
if (hasattr(callback, '__self__') and
|
||||
isinstance(callback.__self__, aio_AbstractChildWatcher)):
|
||||
|
||||
_warn_with_source(
|
||||
warnings_warn(
|
||||
"!!! asyncio is trying to install its ChildWatcher for "
|
||||
"SIGCHLD signal !!!\n\nThis is probably because a uvloop "
|
||||
"instance is used with asyncio.set_event_loop(). "
|
||||
"The correct way to use uvloop is to install its policy: "
|
||||
"`asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())`"
|
||||
"\n\n", RuntimeWarning, self)
|
||||
"\n\n", RuntimeWarning, source=self)
|
||||
|
||||
# TODO: ideally we should always raise an error here,
|
||||
# but that would be a backwards incompatible change,
|
||||
|
@ -3107,10 +3059,10 @@ cdef class Loop:
|
|||
|
||||
def _asyncgen_firstiter_hook(self, agen):
|
||||
if self._asyncgens_shutdown_called:
|
||||
_warn_with_source(
|
||||
warnings_warn(
|
||||
"asynchronous generator {!r} was scheduled after "
|
||||
"loop.shutdown_asyncgens() call".format(agen),
|
||||
ResourceWarning, self)
|
||||
ResourceWarning, source=self)
|
||||
|
||||
self._asyncgens.add(agen)
|
||||
|
||||
|
@ -3119,9 +3071,7 @@ cdef class Loop:
|
|||
"""Shutdown all active asynchronous generators."""
|
||||
self._asyncgens_shutdown_called = True
|
||||
|
||||
if self._asyncgens is None or not len(self._asyncgens):
|
||||
# If Python version is <3.6 or we don't have any asynchronous
|
||||
# generators alive.
|
||||
if not len(self._asyncgens):
|
||||
return
|
||||
|
||||
closing_agens = list(self._asyncgens)
|
||||
|
@ -3304,19 +3254,12 @@ cdef __install_pymem():
|
|||
|
||||
|
||||
cdef _set_signal_wakeup_fd(fd):
|
||||
if PY37 and fd >= 0:
|
||||
if fd >= 0:
|
||||
return signal_set_wakeup_fd(fd, warn_on_full_buffer=False)
|
||||
else:
|
||||
return signal_set_wakeup_fd(fd)
|
||||
|
||||
|
||||
cdef _warn_with_source(msg, cls, source):
|
||||
if PY36:
|
||||
warnings_warn(msg, cls, source=source)
|
||||
else:
|
||||
warnings_warn(msg, cls)
|
||||
|
||||
|
||||
# Helpers for tests
|
||||
|
||||
@cython.iterable_coroutine
|
||||
|
|
Loading…
Reference in New Issue