Python readiness checklist
July 22, 2026 ยท View on GitHub
This checklist tracks the path from the current source-built Python prototype to a distributable, typed, and reliable WinRT projection.
See docs/python-ui-ecosystem.md for research on
Python UI frameworks, static pywinrt adoption, real integrations, and the value
of a dynamic projection.
Target states
- Data API preview: a clean machine can install wheels and generated bindings, then call supported Windows SDK APIs without Rust, Node.js, or a source checkout.
- Data API release: generated APIs follow normal Python semantics for typing, async, events, collections, errors, and lifecycle.
- WinUI preview: Python can bootstrap the Windows App SDK, enter an STA, construct composable WinUI classes, load Fluent resources, and close cleanly.
Verified baseline
- The PyO3 runtime builds on Windows ARM64.
- Generated
Windows.Foundation.Uribindings import and call real WinRT APIs on ARM64. - Python generation emits
.pyimplementations. -
--lang pyemits.pyi,__init__.pyi, andpy.typedby default. - Generated Python E2E covers 34 Windows SDK scenarios.
- Runtime primitives exist for arrays, structs, delegates, events, cancellation, progress callbacks, vectors, and maps.
- Python codegen snapshots cover the
Uriimplementation and stubs.
P0: generated package correctness
- Replace eager cross-module runtime imports with cycle-safe lazy resolution.
- Keep referenced types visible to static type checkers through
TYPE_CHECKINGimports. - Add an import regression for a real cyclic graph such as
Windows.Data.Xml.Dom.XmlDocument. - Preserve
Uriimplementation and.pyisnapshots. - Organize output by WinRT namespace instead of one flat short-name namespace.
- Detect and reject namespace/type filename collisions.
- Add stage/swap generation and remove stale Python output.
- Emit a consumable Python package manifest with an exact runtime dependency.
P0: runtime and generated API agreement
- Ship a
.pyiandpy.typedmarker for thedynwinrt_pyextension. - Return declared enum members as generated
IntEnuminstances while preserving unknown values as integers. - Use
invoke_all()for arbitrary multiple-out methods. - Add Python E2E for
IVector.IndexOfand other multiple-out methods. - Project
IReference<T>return positions asT | None. - Accept
T | NoneinIReference<T>input positions. - Make Python stubs part of E2E and run a static type checker.
- Make
.pyigeneration the default for--lang py.
P0: async semantics
- Return a Python awaitable instead of blocking inside generated async methods.
- Integrate WinRT completion with an
asyncioevent loop. - Propagate Python cancellation to
IAsyncInfo.Cancel. - Expose progress without forcing generated wrappers to call
.wait(). - Keep an explicit blocking API for scripts and non-async hosts.
- Reject blocking waits from an STA when they could deadlock.
P0: CI and distribution
- Execute all tests under
bindings/py/testsin CI. - Build and install wheels before running Python E2E.
- Test supported CPython versions on x64 and ARM64.
- Remove unverified PyPy metadata or add real PyPy coverage.
- Derive the Python package version from the release tag.
- Publish signed/provenanced wheels to an approved internal Python feed.
- Add Python wheel assets and installation notes to GitHub releases.
- Provide a Python-native or standalone codegen installation path.
- Add a clean-machine consumer test that uses only released artifacts.
P1: Python-native behavior
- Map HRESULT failures to
OSErrorwith a stable.winerror. - Include restricted WinRT error information when available.
- Surface Python callback failures instead of returning unconditional success to WinRT.
- Document callback threads and require explicit event unsubscription.
- Implement Python collection protocols for iterable, vector, and map projections.
- Accept normal Python sequences, mappings, bytes, UUIDs, datetimes, and timedeltas where the WinRT signature permits them.
- Emit
IntFlagfor flags enums. - Add overload-aware runtime dispatch and
typing.overloadstubs. - Generate idiomatic constructors such as
Uri(...)while retaining an internal wrapper path for returned native objects. - Replace deprecated PyO3 automatic
FromPyObjectbehavior explicitly. - Document COM apartment ownership and provide a balanced context manager.
P1: tooling and documentation
- Add a Python configuration surface to winapp CLI or a dedicated Python orchestration command.
- Generate package names and imports consistently across Windows SDK, Windows App SDK, and custom WinMD namespaces.
- Add runnable samples for files, notifications, imaging, async, events, collections, and custom WinMD consumption.
- Document generated-code version compatibility with
dynwinrt-py. - Add troubleshooting for metadata, apartment, bootstrap, architecture, and wheel compatibility failures.
WinUI milestone
- Project public composable constructors in Python codegen.
- Hide protected/system-returned constructors.
- Add composition/aggregation support required by XAML runtime classes.
- Make Windows App SDK initialization idempotent and version-aware.
- Auto-discover or explicitly provision the bootstrap DLL.
- Expose the selected framework
resources.pripath. - Add Python-specific implicit XAML metadata provider generation.
- Run
Application.start,Application,Window, and all controls on an STA. - Load Fluent Light, Dark, and High Contrast resources.
- Add a real Python WinUI application E2E on x64 and ARM64.
Later
- Preserve projected object identity where it affects Python semantics.
- Support delegates with more than two ABI parameters.
- Add zero-copy Python buffer protocol integration.
- Add performance benchmarks against pywinrt for representative APIs.
- Add diagnostics for active COM wrappers, delegates, and async operations.
Current implementation slice
- Make generated runtime imports cycle-safe.
- Add a real cyclic-package import regression.
- Re-run Python snapshots, codegen tests, and generated Python E2E.
- Return known enum values as generated
IntEnuminstances. - Verify
Calendar.day_of_weekis aDayOfWeekat runtime. - Use
invoke_all()for arbitrary multiple-out methods. - Model FillArray as caller-owned
(capacity, buffer)ABI. - Verify Python and JavaScript
IndexOfandGetMany, including zero items. - Ship typed
dynwinrt_pywheels and validate the native extension stubs. - Generate Python stubs by default and type-check generated E2E APIs.
- Unbox
IReference<T>returns asT | None. - Box native Python values and
NoneforIReference<T>inputs. - Map synchronous and asynchronous HRESULT failures to
OSError. - Preserve signed HRESULTs in
.winerrorand captured WinRT error messages. - Project WinRT collections through Python sequence, mapping, and iterator protocols.
- Accept Python-native containers, bytes, UUID, datetime, and timedelta values.
- Route delegate exceptions through
sys.unraisablehookand fail WinRT invocation. - Emit
IntFlag, overload dispatch/stubs, and idiomatic runtime-class constructors. - Balance COM initialization with
RoApartmentand add deterministicIClosablecleanup.