Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for Cython3 #587

Merged
merged 17 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ _default: compile


clean:
rm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd
rm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd uvloop/loop_d.*.pyd
rm -fr uvloop/*.c uvloop/*.html uvloop/*.so
rm -fr uvloop/handles/*.html uvloop/includes/*.html
find . -name '__pycache__' | xargs rm -rf
Expand Down
10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ test = [
# pycodestyle is a dependency of flake8, but it must be frozen because
# their combination breaks too often
# (example breakage: https://gitlab.com/pycqa/flake8/issues/427)
'aiohttp>=3.8.1; python_version < "3.12"',
'aiohttp==3.9.0b0; python_version >= "3.12"',
'aiohttp>=3.10.5',
'flake8~=5.0',
'psutil',
'pycodestyle~=2.9.0',
'pyOpenSSL~=23.0.0',
'mypy>=0.800',
'Cython(>=0.29.36,<0.30.0)',
]
dev = [
'setuptools>=60',
'Cython~=3.0',
]
docs = [
'Sphinx~=4.1.2',
Expand All @@ -55,7 +57,7 @@ docs = [
requires = [
"setuptools>=60",
"wheel",
"Cython(>=0.29.36,<0.30.0)",
"Cython~=3.0",
]
build-backend = "setuptools.build_meta"

Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from setuptools.command.sdist import sdist


CYTHON_DEPENDENCY = 'Cython(>=0.29.36,<0.30.0)'
CYTHON_DEPENDENCY = 'Cython~=3.0'
MACHINE = platform.machine()
MODULES_CFLAGS = [os.getenv('UVLOOP_OPT_CFLAGS', '-O2')]
_ROOT = pathlib.Path(__file__).parent
Expand Down Expand Up @@ -144,7 +144,9 @@ def finalize_options(self):
self.distribution.ext_modules[:] = cythonize(
self.distribution.ext_modules,
compiler_directives=directives,
annotate=self.cython_annotate)
annotate=self.cython_annotate,
compile_time_env=dict(DEFAULT_FREELIST_SIZE=250),
emit_linenums=self.debug)

super().finalize_options()

Expand Down
21 changes: 12 additions & 9 deletions tests/test_tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1631,17 +1631,22 @@ async def client(addr):
self.fail("unexpected call to connection_made()")

def test_ssl_connect_accepted_socket(self):
if hasattr(ssl, 'PROTOCOL_TLS'):
proto = ssl.PROTOCOL_TLS
if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):
server_proto = ssl.PROTOCOL_TLS_SERVER
client_proto = ssl.PROTOCOL_TLS_CLIENT
else:
proto = ssl.PROTOCOL_SSLv23
server_context = ssl.SSLContext(proto)
if hasattr(ssl, 'PROTOCOL_TLS'):
client_proto = server_proto = ssl.PROTOCOL_TLS
else:
client_proto = server_proto = ssl.PROTOCOL_SSLv23

server_context = ssl.SSLContext(server_proto)
server_context.load_cert_chain(self.ONLYCERT, self.ONLYKEY)
if hasattr(server_context, 'check_hostname'):
server_context.check_hostname = False
server_context.verify_mode = ssl.CERT_NONE

client_context = ssl.SSLContext(proto)
client_context = ssl.SSLContext(client_proto)
if hasattr(server_context, 'check_hostname'):
client_context.check_hostname = False
client_context.verify_mode = ssl.CERT_NONE
Expand Down Expand Up @@ -2234,8 +2239,7 @@ def test_renegotiation(self):
sslctx.use_privatekey_file(self.ONLYKEY)
sslctx.use_certificate_chain_file(self.ONLYCERT)
client_sslctx = self._create_client_ssl_context()
if hasattr(ssl, 'OP_NO_TLSv1_3'):
client_sslctx.options |= ssl.OP_NO_TLSv1_3
client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2

def server(sock):
conn = openssl_ssl.Connection(sslctx, sock)
Expand Down Expand Up @@ -2593,8 +2597,7 @@ def test_flush_before_shutdown(self):
sslctx_openssl.use_privatekey_file(self.ONLYKEY)
sslctx_openssl.use_certificate_chain_file(self.ONLYCERT)
client_sslctx = self._create_client_ssl_context()
if hasattr(ssl, 'OP_NO_TLSv1_3'):
client_sslctx.options |= ssl.OP_NO_TLSv1_3
client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2

future = None

Expand Down
4 changes: 3 additions & 1 deletion uvloop/_testbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ def find_free_port(start_from=50000):
class SSLTestCase:

def _create_server_ssl_context(self, certfile, keyfile=None):
if hasattr(ssl, 'PROTOCOL_TLS'):
if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
elif hasattr(ssl, 'PROTOCOL_TLS'):
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS)
else:
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Expand Down
2 changes: 1 addition & 1 deletion uvloop/dns.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ cdef class AddrInfo:
uv.uv_freeaddrinfo(self.data) # returns void
self.data = NULL

cdef void set_data(self, system.addrinfo *data):
cdef void set_data(self, system.addrinfo *data) noexcept:
self.data = data

cdef unpack(self):
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/handle.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ cdef void __uv_close_handle_cb(uv.uv_handle_t* handle) noexcept with gil:
Py_DECREF(h) # Was INCREFed in UVHandle._close


cdef void __close_all_handles(Loop loop):
cdef void __close_all_handles(Loop loop) noexcept:
uv.uv_walk(loop.uvloop,
__uv_walk_close_all_handles_cb,
<void*>loop) # void
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/pipe.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cdef __pipe_init_uv_handle(UVStream handle, Loop loop):
cdef __pipe_open(UVStream handle, int fd):
cdef int err
err = uv.uv_pipe_open(<uv.uv_pipe_t *>handle._handle,
<uv.uv_file>fd)
<uv.uv_os_fd_t>fd)
if err < 0:
exc = convert_error(err)
raise exc
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/poll.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cdef class UVPoll(UVHandle):
cdef inline _poll_start(self, int flags)
cdef inline _poll_stop(self)

cdef int is_active(self)
cdef int is_active(self) noexcept

cdef is_reading(self)
cdef is_writing(self)
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/poll.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cdef class UVPoll(UVHandle):
handle._init(loop, fd)
return handle

cdef int is_active(self):
cdef int is_active(self) noexcept:
return (self.reading_handle is not None or
self.writing_handle is not None)

Expand Down
6 changes: 5 additions & 1 deletion uvloop/handles/stream.pyx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
DEF __PREALLOCED_BUFS = 4
cdef extern from *:
'''
enum {__PREALLOCED_BUFS = 4};
'''
const bint __PREALLOCED_BUFS


@cython.no_gc_clear
Expand Down
40 changes: 24 additions & 16 deletions uvloop/includes/consts.pxi
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
DEF UV_STREAM_RECV_BUF_SIZE = 256000 # 250kb
cdef enum:
UV_STREAM_RECV_BUF_SIZE = 256000 # 250kb

DEF FLOW_CONTROL_HIGH_WATER = 64 # KiB
DEF FLOW_CONTROL_HIGH_WATER_SSL_READ = 256 # KiB
DEF FLOW_CONTROL_HIGH_WATER_SSL_WRITE = 512 # KiB
FLOW_CONTROL_HIGH_WATER = 64 # KiB
FLOW_CONTROL_HIGH_WATER_SSL_READ = 256 # KiB
FLOW_CONTROL_HIGH_WATER_SSL_WRITE = 512 # KiB

DEF DEFAULT_FREELIST_SIZE = 250
DEF DNS_PYADDR_TO_SOCKADDR_CACHE_SIZE = 2048
DEFAULT_FREELIST_SIZE = 250
DNS_PYADDR_TO_SOCKADDR_CACHE_SIZE = 2048

DEF DEBUG_STACK_DEPTH = 10
DEBUG_STACK_DEPTH = 10


DEF __PROCESS_DEBUG_SLEEP_AFTER_FORK = 1
__PROCESS_DEBUG_SLEEP_AFTER_FORK = 1


DEF LOG_THRESHOLD_FOR_CONNLOST_WRITES = 5
LOG_THRESHOLD_FOR_CONNLOST_WRITES = 5
SSL_READ_MAX_SIZE = 256 * 1024


# Number of seconds to wait for SSL handshake to complete
# The default timeout matches that of Nginx.
DEF SSL_HANDSHAKE_TIMEOUT = 60.0
# Number of seconds to wait for SSL shutdown to complete
# The default timeout mimics lingering_time
DEF SSL_SHUTDOWN_TIMEOUT = 30.0
DEF SSL_READ_MAX_SIZE = 256 * 1024
cdef extern from *:
'''
// Number of seconds to wait for SSL handshake to complete
// The default timeout matches that of Nginx.
#define SSL_HANDSHAKE_TIMEOUT 60.0

// Number of seconds to wait for SSL shutdown to complete
// The default timeout mimics lingering_time
#define SSL_SHUTDOWN_TIMEOUT 30.0
'''

const float SSL_HANDSHAKE_TIMEOUT
const float SSL_SHUTDOWN_TIMEOUT
6 changes: 5 additions & 1 deletion uvloop/includes/fork_handler.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#ifndef UVLOOP_FORK_HANDLER_H_
#define UVLOOP_FORK_HANDLER_H_

volatile uint64_t MAIN_THREAD_ID = 0;
volatile int8_t MAIN_THREAD_ID_SET = 0;

typedef void (*OnForkHandler)();
typedef void (*OnForkHandler)(void);

OnForkHandler __forkHandler = NULL;

Expand Down Expand Up @@ -36,3 +39,4 @@ void setMainThreadID(uint64_t id) {
MAIN_THREAD_ID = id;
MAIN_THREAD_ID_SET = 1;
}
#endif
6 changes: 3 additions & 3 deletions uvloop/includes/uv.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ cdef extern from "uv.h" nogil:
UV_LEAVE_GROUP = 0,
UV_JOIN_GROUP

cpdef enum uv_fs_event:
cdef enum uv_fs_event:
UV_RENAME = 1,
UV_CHANGE = 2

Expand Down Expand Up @@ -282,7 +282,7 @@ cdef extern from "uv.h" nogil:
int uv_loop_close(uv_loop_t* loop)
int uv_loop_alive(uv_loop_t* loop)
int uv_loop_fork(uv_loop_t* loop)
int uv_backend_fd(uv_loop_t* loop)
uv_os_fd_t uv_backend_fd(uv_loop_t* loop)

void uv_update_time(uv_loop_t* loop)
uint64_t uv_now(const uv_loop_t*)
Expand Down Expand Up @@ -378,7 +378,7 @@ cdef extern from "uv.h" nogil:
# Pipes

int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc)
int uv_pipe_open(uv_pipe_t* handle, uv_file file)
int uv_pipe_open(uv_pipe_t* handle, uv_os_fd_t file)
int uv_pipe_bind(uv_pipe_t* handle, const char* name)

void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
Expand Down
15 changes: 8 additions & 7 deletions uvloop/loop.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ from cpython.pycapsule cimport PyCapsule_New, PyCapsule_GetPointer
from . import _noop


include "includes/consts.pxi"
include "includes/stdlib.pxi"

include "errors.pyx"
Expand Down Expand Up @@ -1118,7 +1117,7 @@ cdef class Loop:

cdef _sock_set_reuseport(self, int fd):
cdef:
int err
int err = 0
int reuseport_flag = 1

err = system.setsockopt(
Expand Down Expand Up @@ -1396,8 +1395,7 @@ cdef class Loop:
def set_debug(self, enabled):
self._debug = bool(enabled)
if self.is_running():
self.call_soon_threadsafe(
self._set_coroutine_debug, self, self._debug)
self.call_soon_threadsafe(self._set_coroutine_debug, self._debug)

def is_running(self):
"""Return whether the event loop is currently running."""
Expand Down Expand Up @@ -2749,8 +2747,7 @@ cdef class Loop:
start_new_session=False,
executable=None,
pass_fds=(),
# For tests only! Do not use in your code. Ever.
__uvloop_sleep_after_fork=False):
**kwargs):

# TODO: Implement close_fds (might not be very important in
# Python 3.5, since all FDs aren't inheritable by default.)
Expand All @@ -2770,8 +2767,12 @@ cdef class Loop:
if executable is not None:
args[0] = executable

if __uvloop_sleep_after_fork:
# For tests only! Do not use in your code. Ever.
if kwargs.pop("__uvloop_sleep_after_fork", False):
debug_flags |= __PROCESS_DEBUG_SLEEP_AFTER_FORK
if kwargs:
raise ValueError(
'unexpected kwargs: {}'.format(', '.join(kwargs.keys())))

waiter = self._new_future()
protocol = protocol_factory()
Expand Down
Loading