The WinRT type system
The winsdk
package is a “projection” that uses the Windows Runtime (WinRT) type system
to automatically generate Python bindings for the Windows SDK. This page describes
how the WinRT types look and feel in this Python projection.
Naming conventions
In the WinRT documentation, most names use PascalCasing
in the style of .NET.
In the Python projection, names are adapted to fit PEP8 naming conventions.
Type names remain as
CapitalizedWords
.Constants, such as enum members are converted to
UPPER_CASE_WITH_UNDERSCORES
.All other identifiers are converted to
lower_case_with_underscores
(namespaces, fields, properties, methods, events, etc.).
Namespaces
Each Windows SDK namespace is projected as a Python package and follows the usual Python import conventions:
# import members of a namespace
from winsdk.windows.foundation import Uri
# or import the namespace module itself
import winsdk.windows.foundation as wf
Fundamental types
The WinRT type system defines the following fundamental types which are mapped to the corresponding Python builtin types.
WinRT type |
Python type |
Python format string |
Description |
---|---|---|---|
|
|
an 8-bit signed integer |
|
|
|
a 16-bit signed integer |
|
|
|
a 32-bit signed integer |
|
|
|
a 64-bit signed integer |
|
|
|
an 8-bit unsigned integer |
|
|
|
a 16-bit unsigned integer |
|
|
|
a 32-bit unsigned integer |
|
|
|
a 64-bit unsigned integer |
|
|
|
a 32-bit IEEE 754 floating point number |
|
|
|
a 64-bit IEEE 754 floating point number |
|
|
|
a 16-bit non-numeric value representing a UTF-16 code unit |
|
|
|
an 8-bit Boolean value |
|
|
|
an immutable sequence of Char16 used to represent text |
|
|
|
a 128-bit standard globally unique identifier |
The Python format strings use the syntax defined in the struct module and
the PEP 3118 additions and are used as the format for the buffer protocol for
arrays of these types. These format strings can be read at runtime by using
memoryview.format
.
Enums
WinRT enums are projected using the Python standard library enum
module. The
WinRT Type system has a [Flags]
attribute that indicates if an enum is
treated as bit flags or not. Enum types without this attribute are projected as
an enum.IntEnum
type or if the [Flags]
attribute is present, the type is
projected as an enum.IntFlags
type.
For arrays and buffers containing enums, use the "i"
format string for
regular enums and "I"
for flags.
Structs
Structs are simple data types that are passed by value in WinRT. In the Python projection, each struct is wrapped in a Python object.
Fields
The fields of a structure are projected as Python descriptor-like
attributes. Getting and setting are supported but deleting is not allowed. The
names of fields are converted to use the lower_case_with_underscores
naming convention.
Example:
from winsdk.windows.foundation import Point
point = Point(1, 2)
x = point.x
point.x = 3
Objects
Todo
explain objects aka runtime classes
Methods
Todo
explain method naming and overload rules
Properties
Properties are projected as Python descriptor-like attributes. Properties with WinRT getter support getting and properties with a WinRT setter allow setting. Deleting properties is never allowed.
Names of properties are converted to use the lower_case_with_underscores
naming convention.
Example:
from winsdk.windows.foundation import Uri
uri = Uri("https://example.com")
print(uri.scheme_name)
Static properties are implemented as class attributes, so are accessed by using the type object rather than an instance object:
from winsdk.windows.foundation import GuidHelper
empty_uuid = GuidHelper.empty
In the type hints, static properties are denoted using typing.ClassVar
.
Changed in version v1.0.0b8: Previous beta releases implemented static properties as get_name()
and
put_name()
methods instead of class attributes.
Events
Todo
explain events
Interfaces
Todo
explain interfaces
Delegates
Todo
explain delegates
Todo
explain exceptions in callbacks
Arrays
Todo
document array types
Specialized types
Some types have special handling and don’t strictly follow the patterns described above.
Awaitables
Todo
document IAsync*
Buffers
Todo
document IBuffer and IMemoryBuffer
Collections
Todo
document Iterable, Sequence, Map
Context managers
Any type that implements IClosable can (and probably should) be used as a context manager in Python:
from winsdk.windows.foundation import MemoryBuffer
with MemoryBuffer(256) as buf:
...
Note
.NET programmers may recognize this as similar to using
statements
in C# with IDisposable
types.
Date and time
Windows.Foundation.DateTime
This type is converted to a datetime.datetime
object from the standard
Python library.
WinRT has a resolution of 100 nanoseconds while the Python type has a resolution of 1 microsecond, so there is a small loss of precision in the conversion. Python also has a much smaller allowed range of dates (years from 1 to 9999).
WinRT serializes values of this type as 100s of nanoseconds since since January 1, 1601 (UTC).
It uses a signed 64-bit integer for this, so the "q"
format string is used in Python.
WinRT uses UTC for all values, so any datetime
object returned from a Windows
API will use that timezone. It is recommended to use the UTC timezone when
creating datetime
objects to pass to Windows APIs as well. Naive datetime
objects (without a timezone) are assumed to use the local timezone and will
be converted to UTC.
Example:
# set notification to expire 10 seconds from now
toaster.expiration_time = datetime.now(timezone.utc) + timedelta(seconds=10)
Windows.Foundation.TimeSpan
This type is converted to a datetime.timedelta
object from the standard
Python library.
WinRT has a resolution of 100 nanoseconds while the Python type has a resolution of 1 microsecond, so there is a small loss of precision in the conversion. Python is also limited to +/-999999999 days.
WinRT serializes values of this type as 100s of nanoseconds.
It uses a signed 64-bit integer for this, so the "q"
format string is used in Python.