This release is a pre-release and may not be stable for production use.
dynwinrt
dynwinrt is the native CPython runtime for Python projections generated by
dynwinrt-codegen. It supports
CPython 3.11–3.14 on Windows x64 and ARM64.
Install
python -m pip install --pre dynwinrt dynwinrt-codegen
dynwinrt-codegen generate --namespace Windows.Foundation --class-name Uri `
--lang py --output generated_uri
Generated package manifests pin dynwinrt to the exact version of
dynwinrt-codegen that produced them. The runtime wheel includes
__init__.pyi and py.typed for static type checking.
Generated IReference<T> values are projected as T | None; native values,
None, and generated IReference_* wrappers are accepted as inputs.
Async WinRT operations
Generated async methods return typed, asyncio-compatible operation objects:
operation = writer.store_async()
stored_bytes = await operation
Their public types are WinRTAsync[T] and
WinRTAsyncWithProgress[T, P]; the concrete runtime wrappers remain private.
Regenerated bindings no longer block inside async methods. Existing code that
expects an immediate result must use await operation or operation.wait().
asyncio task cancellation calls IAsyncInfo.Cancel() on the underlying
WinRT operation. Operations with supported progress values also expose
operation.progress(callback). Fast operations can finish before registration;
in that case no future progress exists and registration is a no-op.
For scripts without an event loop, operation.wait() remains available as an
explicit blocking API. It rejects started operations when called from a running
asyncio loop or an STA thread, where blocking could freeze or deadlock the
caller.
WinRT HRESULT failures raise OSError (or a standard OSError subclass) with
the signed HRESULT in error.winerror. The exception message preserves
restricted WinRT error information when Windows provides it.
Python-native values
Generated collection projections implement the standard collections.abc
protocols: vectors behave as sequences, maps as mappings, and WinRT iterables
and iterators work with iter() and next(). Mutable vectors support indexing,
slicing, assignment, insertion, and deletion; mutable maps support standard
mapping assignment and deletion.
Method inputs accept normal Python sequences and mappings in place of compatible
WinRT collection interfaces. Byte arrays accept bytes and bytearray; GUID,
DateTime, and TimeSpan values use uuid.UUID, datetime.datetime, and
datetime.timedelta.
Exceptions raised by Python event or delegate callbacks are reported through
sys.unraisablehook. The originating WinRT invocation receives
0xA0EE4005 (PYWINRT_E_UNRAISABLE_PYTHON_EXCEPTION) instead of unconditional
success. Generated delegate parameters accept normal Python callables. WinRT
chooses the callback thread, so callbacks must not assume they run on the
registration thread or an asyncio event-loop thread. Keep each token returned by
on_* and pass it to the matching off_* when the subscription is no longer
needed. For callback-style cleanup, subscribe_* returns an idempotent
unsubscribe function. once_* subscribes for at most one callback invocation.
WinRT flags enums are projected as enum.IntFlag. Overloaded methods share one
Python name with runtime type/arity dispatch and typing.overload declarations.
Activatable runtime classes use normal constructors, for example
Uri("https://example.com"). Constructor overloads come only from WinMD
ActivatableAttribute and public ComposableAttribute declarations. Classes
without that metadata, including system-returned classes and protected-only
composition, raise a class-named TypeError on normal construction and their
stubs expose no public constructor. Native return values still use the internal
_from_native/DynWinRTValue wrapping path.
Raw object projection
Use project_as(value, Type) when metadata returns Object/IInspectable but
the application knows the concrete generated type. This is common with XAML
APIs such as XamlReader.load() and FrameworkElement.find_name():
from dynwinrt import project_as
from generated.microsoft.ui.xaml.controls import Button, StackPanel
from generated.microsoft.ui.xaml.markup import XamlReader
raw_panel = XamlReader.load(XAML)
if raw_panel is None:
raise RuntimeError("XamlReader returned no value")
panel = project_as(raw_panel, StackPanel)
raw_button = panel.find_name("Submit")
if raw_button is None:
raise RuntimeError("Submit was not found")
button = project_as(raw_button, Button)
project_as() accepts generated runtime classes only and borrows its input:
the raw value or source wrapper remains valid. The returned wrapper owns the
QueryInterface result, participates in the active
projected_lifetime_scope(), and preserves the projection identity cache.
Classes with a verifiable default-interface IID remain valid projection
targets even when metadata exposes them only through Object/IInspectable.
Projection always performs QueryInterface, so a static-only declaration cannot
produce a wrapper unless the input actually implements that default interface.
Incompatible types raise the ordinary WinRT OSError. Static-only metadata
classes with no instance surface are not projection targets.
Use wrapper.as_interface(InterfaceClass) when converting an existing
wrapper to an interface view. Use InterfaceClass.from_value(raw) for a raw
DynWinRTValue. Do not call the internal _from_native() method from
application code.
COM apartments and cleanup
Use RoApartment to initialize COM for a thread and balance every successful
initialization:
with RoApartment(0): # RO_INIT_SINGLETHREADED
use_winrt()
Use RoApartment(1) for RO_INIT_MULTITHREADED. Nested contexts using the same
model are supported. Requesting a conflicting model raises OSError with
RPC_E_CHANGED_MODE. The low-level ro_initialize() API remains available, but
each successful call, including S_FALSE, must be paired with one
ro_uninitialize() call on the same thread.
Generated runtime classes that implement IClosable support with and an
idempotent close() method. Prefer deterministic cleanup instead of relying on
Python garbage collection.
Experimental WinUI support
When the required WinUI metadata is generated, Application.create() installs
XamlControlsResources and configures unpackaged resource resolution.
Application.create_with_metadata_provider(...) is available when the
application supplies its own provider.
Python subclasses of public composable controls preserve one COM identity for
inherited properties and methods. Metadata-supported
measure_override, arrange_override, and on_apply_template callbacks run
synchronously on the creating UI apartment with the contextvars context
captured during construction. Unsupported native override shapes fail during
construction instead of falling back to an unsafe ABI.
After creating the generated application, publicly composable controls can
register a Python subclass for activation by XamlReader:
from generated.microsoft.ui.xaml.controls import StackPanel
from generated.microsoft.ui.xaml.markup import XamlReader
class PythonPanel(StackPanel):
def measure_override(self, available_size):
return available_size
registration = StackPanel.register_xaml_runtime_class(
"MyApp.Controls.PythonPanel",
PythonPanel,
)
raw_panel = XamlReader.load(
'<local:PythonPanel '
'xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" '
'xmlns:local="using:MyApp.Controls" />'
)
if raw_panel is None:
raise RuntimeError("XamlReader returned no value")
panel = StackPanel(raw_panel)
# First remove every instance from the XAML tree and release application owners.
panel = None
raw_panel = None
registration.unregister()
registration.release_instances()
Registrations are process-local, and duplicate names fail. Unregistering,
closing, or dropping the registration prevents new XAML metadata lookups.
XAML-created Python owners remain rooted until release_instances(); call it
only after every corresponding native control has left the XAML tree.
Registration does not make the class globally activatable through
RoActivateInstance.
Generated Application.start() and DispatcherQueue.run_event_loop() calls
stay on the caller's native thread but release the Python GIL while WinUI pumps
messages. WinRT callbacks reacquire the GIL, and worker threads can use
DispatcherQueue.try_enqueue() to return to the UI thread.
Use a projection lifetime scope inside the COM apartment so wrappers release
their native values before RoUninitialize:
from dynwinrt import RoApartment, projected_lifetime_scope
with RoApartment(0), projected_lifetime_scope():
app = Application.create()
# Create and use WinUI objects here.
Scopes nest in LIFO order. Wrappers that survive a closed scope remain Python objects, but their native values are released and further WinRT calls fail.
Normal construction remains unavailable for protected-only composable classes and system-returned classes without public activation metadata. Named Python XAML registration does not support generic names, collection or dictionary bases, markup-extension bases, or Python-defined XAML members.
Develop
From bindings\py:
python -m pip install "maturin>=1.11,<2" "pytest>=8.3.5" "mypy>=1.13,<2"
python -m maturin develop
python -m pytest
Release process
The release tag supplies one unified npm/Cargo version. For example,
v0.1.0-preview.21 produces npm version 0.1.0-preview.21 and Python version
0.1.0rc21 after PEP 440 normalization.
- GitHub Actions builds and consumes eight CPython 3.11–3.14 runtime wheels and two standalone codegen wheels on Windows x64 and native ARM64.
- The official 1ES ADO pipeline builds both npm packages and waits for the complete Python wheel matrix.
- ADO creates one shared GitHub Release with the npm tarballs. GitHub Actions attaches the ten tested Python wheels, and ADO downloads and revalidates the complete set.
- With
DoEsrpenabled, ADO publishes both npm packages.PublishPyPIdefaults to enabled and publishes the eightdynwinrtwheels before the twodynwinrt-codegenwheels. Disable it only for a non-PyPI rehearsal.
PyPI publication uses the Microsoft ESRP release identity and is not available from GitHub Actions.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynwinrt-0.1.0rc21-cp314-cp314-win_arm64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp314-cp314-win_arm64.whl
- Upload date:
- Size: 664.2 kB
- Tags: CPython 3.14, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d79a580d3f452dfbbcbcd32dfddf9a8c3f9037e6682efda0040cb70d4e26cd0
|
|
| MD5 |
faeefb1dbf1cafbd2147dac709616309
|
|
| BLAKE2b-256 |
b67c846e1ab3c69dafccbb935e5cc6317ae124b170d4045ce199d4ab7eef53b6
|
File details
Details for the file dynwinrt-0.1.0rc21-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 689.7 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f267c85491e41a81e1e747d1a1f7d039de12c1ee5db298c69afc354e11dd79e7
|
|
| MD5 |
0b52604e91b8bcd509980bb02efcb03f
|
|
| BLAKE2b-256 |
5c9fc0f8f59044a09d5b4f10c41e5eaa977ea79883303141f445139ec61357d6
|
File details
Details for the file dynwinrt-0.1.0rc21-cp313-cp313-win_arm64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp313-cp313-win_arm64.whl
- Upload date:
- Size: 663.8 kB
- Tags: CPython 3.13, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37214e45cdd7a86fff5b5cc01120bf54c0a5ec078260be5ec23e2686bbac7dd6
|
|
| MD5 |
f3a124c337ba6108be1041770c93d596
|
|
| BLAKE2b-256 |
30c02fc27667d763f52fbbec47f0d8e546044f8566fe4fec28e3f1adf1a77791
|
File details
Details for the file dynwinrt-0.1.0rc21-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 689.4 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb435e1590de0a1d9048a7dc0df4385b8a8ec4c42116f42ff560af8b74e119ce
|
|
| MD5 |
efb2b98e5c669eba3ac0f2cc9334be76
|
|
| BLAKE2b-256 |
d9d46dcd01f981b92cfbf6777c25dadc8014b219c0c5ca6e8de1b8e4120a6949
|
File details
Details for the file dynwinrt-0.1.0rc21-cp312-cp312-win_arm64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp312-cp312-win_arm64.whl
- Upload date:
- Size: 662.9 kB
- Tags: CPython 3.12, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea26c3748d8f050770dd2768d02a34a4b6b95295750cdeae29e474eda1cd458d
|
|
| MD5 |
4b3970fb8243246c49b3b5d72ff79252
|
|
| BLAKE2b-256 |
bd64c4327a354c5348dd32e2e9deb5f75d2b74e8534f3c3395524f0b29b13909
|
File details
Details for the file dynwinrt-0.1.0rc21-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 688.6 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b705306a75ed74288ad4f74367ae6923e021c3851e7a359fc1635480741dd10
|
|
| MD5 |
25200b40ba4043b63b53eb6b10047f6f
|
|
| BLAKE2b-256 |
f7a1bef11deb0725225ffea0212f6e2af9480a61d9475cb0cdd40296f614c8de
|
File details
Details for the file dynwinrt-0.1.0rc21-cp311-cp311-win_arm64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp311-cp311-win_arm64.whl
- Upload date:
- Size: 669.1 kB
- Tags: CPython 3.11, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccd38e33ca85b2f7c67ecfd53dd1587d9bdad58d5728286a4cf3778252ae99f0
|
|
| MD5 |
8e2ebd89288f1f06fcc8658bdbd8dc4c
|
|
| BLAKE2b-256 |
22d5a6c50973156a299e15c5bbe3d32b1ab8ebaecf2f6452d0ed40ea0116a6f8
|
File details
Details for the file dynwinrt-0.1.0rc21-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: dynwinrt-0.1.0rc21-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 696.0 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
RestSharp/106.13.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e32718c20556e30e46ead07cf7f03cebf55493cc6d90a55dd0c04a345dcb120b
|
|
| MD5 |
501fbf31c93bafa0a2e74269a23d6d19
|
|
| BLAKE2b-256 |
745e6237d95565d04b44b744f82c1eba638f7bb785f3274f1581c108e7623dc3
|