Skip to content

Commit e89a23e

Browse files
authored
Merge branch 'main' into pypy-3.11
2 parents 154deeb + ea03051 commit e89a23e

11 files changed

Lines changed: 267 additions & 233 deletions

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# For files generated by trio/_tools/gen_exports.py
1+
# For files generated by trio/_tools/gen_exports.py or trio/_tools/windows_ffi_build.py
22
trio/_core/_generated* linguist-generated=true
33
# Treat generated files as binary in git diff
44
trio/_core/_generated* -diff

.pre-commit-config.yaml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ repos:
2424
hooks:
2525
- id: black
2626
- repo: https://github.com/astral-sh/ruff-pre-commit
27-
rev: v0.11.12
27+
rev: v0.11.13
2828
hooks:
2929
- id: ruff-check
3030
types: [file]
@@ -38,7 +38,7 @@ repos:
3838
# tomli needed on 3.10. tomllib is available in stdlib on 3.11+
3939
- tomli
4040
- repo: https://github.com/adhtruong/mirrors-typos
41-
rev: v1.32.0
41+
rev: v1.33.1
4242
hooks:
4343
- id: typos
4444
- repo: https://github.com/sphinx-contrib/sphinx-lint
@@ -58,6 +58,13 @@ repos:
5858
pass_filenames: false
5959
additional_dependencies: ["astor", "attrs", "black", "ruff"]
6060
files: ^src\/trio\/_core\/(_run|(_i(o_(common|epoll|kqueue|windows)|nstrumentation)))\.py$
61+
- id: regenerate-windows-cffi
62+
name: regenerate windows CFFI
63+
language: python
64+
entry: python src/trio/_tools/windows_ffi_build.py
65+
pass_filenames: false
66+
additional_dependencies: ["cffi"]
67+
files: ^src\/trio\/_tools\/windows_ffi_build\.py$
6168
- id: sync-test-requirements
6269
name: synchronize test requirements
6370
language: python
@@ -66,7 +73,7 @@ repos:
6673
additional_dependencies: ["pyyaml"]
6774
files: ^(test-requirements\.txt)|(\.pre-commit-config\.yaml)$
6875
- repo: https://github.com/astral-sh/uv-pre-commit
69-
rev: 0.7.9
76+
rev: 0.7.12
7077
hooks:
7178
# Compile requirements
7279
- id: pip-compile

newsfragments/3263.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Decrease import time on Windows by around 10%.

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ force-exclude = '''
7878
(
7979
^/docs/source/reference-.*
8080
| ^/docs/source/tutorial
81+
| ^/src/trio/_core/_generated_windows_ffi.py
8182
)
8283
'''
8384

@@ -110,6 +111,7 @@ include = ["*.py", "*.pyi", "**/pyproject.toml"]
110111
extend-exclude = [
111112
"docs/source/reference-*",
112113
"docs/source/tutorial/*",
114+
"src/trio/_core/_generated_windows_ffi.py"
113115
]
114116

115117
[tool.ruff.lint]
@@ -309,6 +311,8 @@ omit = [
309311
"*/type_tests/*",
310312
# Script used to check type completeness that isn't run in tests
311313
"*/trio/_tests/check_type_completeness.py",
314+
# Script to generate a CFFI interface for the Windows kernel
315+
"*/trio/_tools/windows_ffi_build.py",
312316
]
313317
# The test suite spawns subprocesses to test some stuff, so make sure
314318
# this doesn't corrupt the coverage files
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# auto-generated file
2+
import _cffi_backend
3+
4+
ffi = _cffi_backend.FFI('trio._core._generated_windows_ffi',
5+
_version = 0x2601,
6+
_types = b'\x00\x00\x39\x0D\x00\x00\x1A\x01\x00\x00\x0A\x01\x00\x00\x72\x03\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x02\x03\x00\x00\x6D\x03\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x04\x01\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x72\x03\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x08\x11\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x00\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x08\x11\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x6E\x03\x00\x00\x0A\x01\x00\x00\x07\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x07\x01\x00\x00\x02\x0F\x00\x00\x39\x0D\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x1A\x01\x00\x00\x08\x11\x00\x00\x02\x0F\x00\x00\x02\x0D\x00\x00\x08\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x0A\x01\x00\x00\x03\x03\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x02\x0D\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x00\x0F\x00\x00\x03\x0D\x00\x00\x03\x11\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x03\x0D\x00\x00\x73\x03\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x03\x11\x00\x00\x00\x0F\x00\x00\x03\x0D\x00\x00\x03\x11\x00\x00\x03\x11\x00\x00\x1A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x68\x03\x00\x00\x02\x09\x00\x00\x68\x05\x00\x00\x00\x01\x00\x00\x6C\x03\x00\x00\x03\x09\x00\x00\x04\x09\x00\x00\x05\x09\x00\x00\x17\x01\x00\x00\x01\x09\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x10\x01',
7+
_globals = (b'\x00\x00\x2F\x23CancelIoEx',0,b'\x00\x00\x2C\x23CloseHandle',0,b'\x00\x00\x52\x23CreateEventA',0,b'\x00\x00\x58\x23CreateFileW',0,b'\x00\x00\x61\x23CreateIoCompletionPort',0,b'\x00\x00\x12\x23DeviceIoControl',0,b'\x00\x00\x33\x23GetQueuedCompletionStatusEx',0,b'\x00\x00\x3F\x23PostQueuedCompletionStatus',0,b'\x00\x00\x1C\x23ReadFile',0,b'\x00\x00\x0B\x23ResetEvent',0,b'\x00\x00\x45\x23RtlNtStatusToDosError',0,b'\x00\x00\x3B\x23SetConsoleCtrlHandler',0,b'\x00\x00\x0B\x23SetEvent',0,b'\x00\x00\x0E\x23SetFileCompletionNotificationModes',0,b'\x00\x00\x2A\x23WSAGetLastError',0,b'\x00\x00\x00\x23WSAIoctl',0,b'\x00\x00\x48\x23WaitForMultipleObjects',0,b'\x00\x00\x4E\x23WaitForSingleObject',0,b'\x00\x00\x23\x23WriteFile',0),
8+
_struct_unions = ((b'\x00\x00\x00\x71\x00\x00\x00\x03$1',b'\x00\x00\x70\x11DUMMYSTRUCTNAME',b'\x00\x00\x03\x11Pointer'),(b'\x00\x00\x00\x70\x00\x00\x00\x02$2',b'\x00\x00\x02\x11Offset',b'\x00\x00\x02\x11OffsetHigh'),(b'\x00\x00\x00\x68\x00\x00\x00\x02_AFD_POLL_HANDLE_INFO',b'\x00\x00\x03\x11Handle',b'\x00\x00\x02\x11Events',b'\x00\x00\x46\x11Status'),(b'\x00\x00\x00\x6C\x00\x00\x00\x02_AFD_POLL_INFO',b'\x00\x00\x6F\x11Timeout',b'\x00\x00\x02\x11NumberOfHandles',b'\x00\x00\x02\x11Exclusive',b'\x00\x00\x69\x11Handles'),(b'\x00\x00\x00\x6D\x00\x00\x00\x02_OVERLAPPED',b'\x00\x00\x01\x11Internal',b'\x00\x00\x01\x11InternalHigh',b'\x00\x00\x71\x11DUMMYUNIONNAME',b'\x00\x00\x03\x11hEvent'),(b'\x00\x00\x00\x6E\x00\x00\x00\x02_OVERLAPPED_ENTRY',b'\x00\x00\x01\x11lpCompletionKey',b'\x00\x00\x08\x11lpOverlapped',b'\x00\x00\x01\x11Internal',b'\x00\x00\x02\x11dwNumberOfBytesTransferred')),
9+
_typenames = (b'\x00\x00\x00\x68AFD_POLL_HANDLE_INFO',b'\x00\x00\x00\x6CAFD_POLL_INFO',b'\x00\x00\x00\x39BOOL',b'\x00\x00\x00\x10BOOLEAN',b'\x00\x00\x00\x10BYTE',b'\x00\x00\x00\x02DWORD',b'\x00\x00\x00\x03HANDLE',b'\x00\x00\x00\x6FLARGE_INTEGER',b'\x00\x00\x00\x03LPCSTR',b'\x00\x00\x00\x25LPCVOID',b'\x00\x00\x00\x59LPCWSTR',b'\x00\x00\x00\x07LPDWORD',b'\x00\x00\x00\x08LPOVERLAPPED',b'\x00\x00\x00\x35LPOVERLAPPED_ENTRY',b'\x00\x00\x00\x03LPSECURITY_ATTRIBUTES',b'\x00\x00\x00\x03LPVOID',b'\x00\x00\x00\x08LPWSAOVERLAPPED',b'\x00\x00\x00\x46NTSTATUS',b'\x00\x00\x00\x6DOVERLAPPED',b'\x00\x00\x00\x6EOVERLAPPED_ENTRY',b'\x00\x00\x00\x67PAFD_POLL_HANDLE_INFO',b'\x00\x00\x00\x6BPAFD_POLL_INFO',b'\x00\x00\x00\x07PULONG',b'\x00\x00\x00\x03PVOID',b'\x00\x00\x00\x01SOCKET',b'\x00\x00\x00\x10UCHAR',b'\x00\x00\x00\x01UINT_PTR',b'\x00\x00\x00\x02ULONG',b'\x00\x00\x00\x01ULONG_PTR',b'\x00\x00\x00\x6DWSAOVERLAPPED',b'\x00\x00\x00\x02u_long'),
10+
)

src/trio/_core/_io_windows.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,9 @@ def _refresh_afd(self, base_handle: Handle) -> None:
714714
kernel32.DeviceIoControl(
715715
afd_group.handle,
716716
IoControlCodes.IOCTL_AFD_POLL,
717-
cast("CType", poll_info),
717+
cast("CType", poll_info), # type: ignore[arg-type]
718718
ffi.sizeof("AFD_POLL_INFO"),
719-
cast("CType", poll_info),
719+
cast("CType", poll_info), # type: ignore[arg-type]
720720
ffi.sizeof("AFD_POLL_INFO"),
721721
ffi.NULL,
722722
lpOverlapped,

src/trio/_core/_tests/test_windows.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@
3737

3838

3939
def test_winerror(monkeypatch: pytest.MonkeyPatch) -> None:
40+
# this is unfortunately needed as the generated ffi is read-only
41+
class FFIWrapper:
42+
def getwinerror(self) -> None:
43+
raise NotImplementedError("this is a fake implementation")
44+
4045
mock = create_autospec(ffi.getwinerror)
41-
monkeypatch.setattr(ffi, "getwinerror", mock)
46+
monkeypatch.setattr("trio._core._windows_cffi.ffi", FFIWrapper)
47+
monkeypatch.setattr("trio._core._windows_cffi.ffi.getwinerror", mock)
4248

4349
# Returning none = no error, should not happen.
4450
mock.return_value = None

src/trio/_core/_windows_cffi.py

Lines changed: 10 additions & 216 deletions
Original file line numberDiff line numberDiff line change
@@ -1,232 +1,26 @@
11
from __future__ import annotations
22

33
import enum
4-
import re
54
from typing import TYPE_CHECKING, NewType, NoReturn, Protocol, cast
65

76
if TYPE_CHECKING:
7+
import cffi
88
from typing_extensions import TypeAlias
99

10-
import cffi
10+
CData: TypeAlias = cffi.api.FFI.CData
11+
CType: TypeAlias = cffi.api.FFI.CType
12+
13+
from ._generated_windows_ffi import ffi
1114

1215
################################################################
1316
# Functions and types
1417
################################################################
1518

16-
LIB = """
17-
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
18-
typedef int BOOL;
19-
typedef unsigned char BYTE;
20-
typedef BYTE BOOLEAN;
21-
typedef void* PVOID;
22-
typedef PVOID HANDLE;
23-
typedef unsigned long DWORD;
24-
typedef unsigned long ULONG;
25-
typedef unsigned int NTSTATUS;
26-
typedef unsigned long u_long;
27-
typedef ULONG *PULONG;
28-
typedef const void *LPCVOID;
29-
typedef void *LPVOID;
30-
typedef const wchar_t *LPCWSTR;
31-
32-
typedef uintptr_t ULONG_PTR;
33-
typedef uintptr_t UINT_PTR;
34-
35-
typedef UINT_PTR SOCKET;
36-
37-
typedef struct _OVERLAPPED {
38-
ULONG_PTR Internal;
39-
ULONG_PTR InternalHigh;
40-
union {
41-
struct {
42-
DWORD Offset;
43-
DWORD OffsetHigh;
44-
} DUMMYSTRUCTNAME;
45-
PVOID Pointer;
46-
} DUMMYUNIONNAME;
47-
48-
HANDLE hEvent;
49-
} OVERLAPPED, *LPOVERLAPPED;
50-
51-
typedef OVERLAPPED WSAOVERLAPPED;
52-
typedef LPOVERLAPPED LPWSAOVERLAPPED;
53-
typedef PVOID LPSECURITY_ATTRIBUTES;
54-
typedef PVOID LPCSTR;
55-
56-
typedef struct _OVERLAPPED_ENTRY {
57-
ULONG_PTR lpCompletionKey;
58-
LPOVERLAPPED lpOverlapped;
59-
ULONG_PTR Internal;
60-
DWORD dwNumberOfBytesTransferred;
61-
} OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;
62-
63-
// kernel32.dll
64-
HANDLE WINAPI CreateIoCompletionPort(
65-
_In_ HANDLE FileHandle,
66-
_In_opt_ HANDLE ExistingCompletionPort,
67-
_In_ ULONG_PTR CompletionKey,
68-
_In_ DWORD NumberOfConcurrentThreads
69-
);
70-
71-
BOOL SetFileCompletionNotificationModes(
72-
HANDLE FileHandle,
73-
UCHAR Flags
74-
);
75-
76-
HANDLE CreateFileW(
77-
LPCWSTR lpFileName,
78-
DWORD dwDesiredAccess,
79-
DWORD dwShareMode,
80-
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
81-
DWORD dwCreationDisposition,
82-
DWORD dwFlagsAndAttributes,
83-
HANDLE hTemplateFile
84-
);
85-
86-
BOOL WINAPI CloseHandle(
87-
_In_ HANDLE hObject
88-
);
89-
90-
BOOL WINAPI PostQueuedCompletionStatus(
91-
_In_ HANDLE CompletionPort,
92-
_In_ DWORD dwNumberOfBytesTransferred,
93-
_In_ ULONG_PTR dwCompletionKey,
94-
_In_opt_ LPOVERLAPPED lpOverlapped
95-
);
96-
97-
BOOL WINAPI GetQueuedCompletionStatusEx(
98-
_In_ HANDLE CompletionPort,
99-
_Out_ LPOVERLAPPED_ENTRY lpCompletionPortEntries,
100-
_In_ ULONG ulCount,
101-
_Out_ PULONG ulNumEntriesRemoved,
102-
_In_ DWORD dwMilliseconds,
103-
_In_ BOOL fAlertable
104-
);
105-
106-
BOOL WINAPI CancelIoEx(
107-
_In_ HANDLE hFile,
108-
_In_opt_ LPOVERLAPPED lpOverlapped
109-
);
110-
111-
BOOL WriteFile(
112-
HANDLE hFile,
113-
LPCVOID lpBuffer,
114-
DWORD nNumberOfBytesToWrite,
115-
LPDWORD lpNumberOfBytesWritten,
116-
LPOVERLAPPED lpOverlapped
117-
);
118-
119-
BOOL ReadFile(
120-
HANDLE hFile,
121-
LPVOID lpBuffer,
122-
DWORD nNumberOfBytesToRead,
123-
LPDWORD lpNumberOfBytesRead,
124-
LPOVERLAPPED lpOverlapped
125-
);
126-
127-
BOOL WINAPI SetConsoleCtrlHandler(
128-
_In_opt_ void* HandlerRoutine,
129-
_In_ BOOL Add
130-
);
131-
132-
HANDLE CreateEventA(
133-
LPSECURITY_ATTRIBUTES lpEventAttributes,
134-
BOOL bManualReset,
135-
BOOL bInitialState,
136-
LPCSTR lpName
137-
);
138-
139-
BOOL SetEvent(
140-
HANDLE hEvent
141-
);
142-
143-
BOOL ResetEvent(
144-
HANDLE hEvent
145-
);
146-
147-
DWORD WaitForSingleObject(
148-
HANDLE hHandle,
149-
DWORD dwMilliseconds
150-
);
151-
152-
DWORD WaitForMultipleObjects(
153-
DWORD nCount,
154-
HANDLE *lpHandles,
155-
BOOL bWaitAll,
156-
DWORD dwMilliseconds
157-
);
158-
159-
ULONG RtlNtStatusToDosError(
160-
NTSTATUS Status
161-
);
162-
163-
int WSAIoctl(
164-
SOCKET s,
165-
DWORD dwIoControlCode,
166-
LPVOID lpvInBuffer,
167-
DWORD cbInBuffer,
168-
LPVOID lpvOutBuffer,
169-
DWORD cbOutBuffer,
170-
LPDWORD lpcbBytesReturned,
171-
LPWSAOVERLAPPED lpOverlapped,
172-
// actually LPWSAOVERLAPPED_COMPLETION_ROUTINE
173-
void* lpCompletionRoutine
174-
);
175-
176-
int WSAGetLastError();
177-
178-
BOOL DeviceIoControl(
179-
HANDLE hDevice,
180-
DWORD dwIoControlCode,
181-
LPVOID lpInBuffer,
182-
DWORD nInBufferSize,
183-
LPVOID lpOutBuffer,
184-
DWORD nOutBufferSize,
185-
LPDWORD lpBytesReturned,
186-
LPOVERLAPPED lpOverlapped
187-
);
188-
189-
// From https://github.com/piscisaureus/wepoll/blob/master/src/afd.h
190-
typedef struct _AFD_POLL_HANDLE_INFO {
191-
HANDLE Handle;
192-
ULONG Events;
193-
NTSTATUS Status;
194-
} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
195-
196-
// This is really defined as a messy union to allow stuff like
197-
// i.DUMMYSTRUCTNAME.LowPart, but we don't need those complications.
198-
// Under all that it's just an int64.
199-
typedef int64_t LARGE_INTEGER;
200-
201-
typedef struct _AFD_POLL_INFO {
202-
LARGE_INTEGER Timeout;
203-
ULONG NumberOfHandles;
204-
ULONG Exclusive;
205-
AFD_POLL_HANDLE_INFO Handles[1];
206-
} AFD_POLL_INFO, *PAFD_POLL_INFO;
207-
208-
"""
209-
210-
# cribbed from pywincffi
211-
# programmatically strips out those annotations MSDN likes, like _In_
212-
REGEX_SAL_ANNOTATION = re.compile(
213-
r"\b(_In_|_Inout_|_Out_|_Outptr_|_Reserved_)(opt_)?\b",
214-
)
215-
LIB = REGEX_SAL_ANNOTATION.sub(" ", LIB)
216-
217-
# Other fixups:
218-
# - get rid of FAR, cffi doesn't like it
219-
LIB = re.sub(r"\bFAR\b", " ", LIB)
220-
# - PASCAL is apparently an alias for __stdcall (on modern compilers - modern
221-
# being _MSC_VER >= 800)
222-
LIB = re.sub(r"\bPASCAL\b", "__stdcall", LIB)
223-
224-
ffi = cffi.api.FFI()
225-
ffi.cdef(LIB)
226-
227-
CData: TypeAlias = cffi.api.FFI.CData
228-
CType: TypeAlias = cffi.api.FFI.CType
229-
AlwaysNull: TypeAlias = CType # We currently always pass ffi.NULL here.
19+
if not TYPE_CHECKING:
20+
CData: TypeAlias = ffi.CData
21+
CType: TypeAlias = ffi.CType
22+
23+
AlwaysNull: TypeAlias = CData # We currently always pass ffi.NULL here.
23024
Handle = NewType("Handle", CData)
23125
HandleArray = NewType("HandleArray", CData)
23226

src/trio/_highlevel_open_tcp_stream.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,6 @@ async def attempt_connect(
375375
# allowing the next target to be tried early
376376
attempt_failed = trio.Event()
377377

378-
# workaround to check types until typing of nursery.start_soon improved
379-
if TYPE_CHECKING:
380-
await attempt_connect(
381-
(address_family, socket_type, proto),
382-
addr,
383-
attempt_failed,
384-
)
385-
386378
nursery.start_soon(
387379
attempt_connect,
388380
(address_family, socket_type, proto),

0 commit comments

Comments
 (0)