winrt-runtime 4.0.0__cp315-cp315-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ """
2
+ Where PyInstaller finds PyWinRT's hook.
3
+
4
+ ``winrt-runtime`` declares this module in the ``pyinstaller40`` entry point
5
+ group, so PyInstaller asks it for the directory the hook is in and needs no
6
+ configuration from the application being frozen.
7
+ """
8
+
9
+ import os
10
+
11
+
12
+ def get_hook_dirs() -> list[str]:
13
+ return [os.path.dirname(__file__)]
@@ -0,0 +1,85 @@
1
+ """
2
+ What a frozen application needs from PyWinRT that PyInstaller cannot see.
3
+
4
+ Two things are invisible to an import graph.
5
+
6
+ A projected namespace is a data file. ``winrt.windows.storage`` is an
7
+ ``__init__.py`` that asks the runtime to read the ``_table.pywinrt`` sitting
8
+ beside it, so freezing the module without the table produces an executable
9
+ that fails at import. PyInstaller collects the module and not the table.
10
+
11
+ A projected type is resolved by importing the module that owns it, by name,
12
+ while the program runs (``py::get_python_type()`` in the runtime). A call
13
+ that hands back an ``IAsyncOperation`` imports ``winrt.windows.foundation``
14
+ whether or not the application ever names it, and nothing in the source says
15
+ so. So every projection package that is installed is collected rather than
16
+ only the ones the graph reached: what an application imports says little
17
+ about which namespaces its calls return types from.
18
+
19
+ Nothing here names a Windows SDK, a Windows App SDK or any other family. What
20
+ is collected is what the installed distributions say they ship, so a
21
+ projection somebody else generated is collected on the same terms as the ones
22
+ published from this repository.
23
+ """
24
+
25
+ from importlib.metadata import distributions
26
+
27
+ # the data file a projection package carries, which
28
+ # winrt.runtime._internals.load_projection() reads from beside the module
29
+ TABLE_NAME = "_table.pywinrt"
30
+
31
+ binaries: list[tuple[str, str]] = []
32
+ datas: list[tuple[str, str]] = []
33
+ hiddenimports: list[str] = []
34
+
35
+
36
+ def _installed_files() -> list[tuple[str, str, str]]:
37
+ """
38
+ Every file of every installed distribution, as (name, package, source).
39
+
40
+ ``package`` is the dotted package the file sits in and ``source`` is where
41
+ it is now. A distribution installed from a wheel records what it put where;
42
+ one that did not record it is something this can say nothing about.
43
+ """
44
+ files: list[tuple[str, str, str]] = []
45
+
46
+ for distribution in distributions():
47
+ for file in distribution.files or []:
48
+ directory = str(file).replace("\\", "/").rpartition("/")[0]
49
+
50
+ if directory:
51
+ files.append(
52
+ (file.name, directory, str(distribution.locate_file(file)))
53
+ )
54
+
55
+ return files
56
+
57
+
58
+ def _collect() -> None:
59
+ installed = _installed_files()
60
+
61
+ # The namespace roots PyWinRT projects into are whichever ones hold a
62
+ # table, rather than a list of names kept here: the runtime has no
63
+ # business knowing which families exist.
64
+ roots = {
65
+ package.partition("/")[0]
66
+ for name, package, _ in installed
67
+ if name == TABLE_NAME
68
+ }
69
+
70
+ for name, package, source in installed:
71
+ if package.partition("/")[0] not in roots:
72
+ continue
73
+
74
+ if name == TABLE_NAME:
75
+ datas.append((source, package))
76
+ hiddenimports.append(package.replace("/", "."))
77
+
78
+ # A package that redistributes a component .dll loads it by bare name
79
+ # after putting its own directory on the DLL search path, so no import
80
+ # table mentions it and nothing else would collect it.
81
+ if name.lower().endswith(".dll"):
82
+ binaries.append((source, package))
83
+
84
+
85
+ _collect()
Binary file
winrt/_winrt.pyi ADDED
@@ -0,0 +1,169 @@
1
+ import abc
2
+ import collections.abc
3
+ from datetime import datetime, timedelta
4
+ import types
5
+ from typing import (
6
+ Any,
7
+ ClassVar,
8
+ Protocol,
9
+ Self,
10
+ SupportsIndex,
11
+ TypeVar,
12
+ final,
13
+ overload,
14
+ )
15
+ from collections.abc import Iterable, Iterator
16
+ from uuid import UUID
17
+
18
+ from typing_extensions import Buffer, TypeForm, deprecated
19
+
20
+ from winrt.runtime import ApartmentType
21
+ from winrt.runtime.interop import InterfaceCapsule
22
+
23
+ MTA: int
24
+ STA: int
25
+
26
+ def init_apartment(apartment_type: ApartmentType, /) -> None: ...
27
+ def uninit_apartment() -> None: ...
28
+ def initialize_with_window(obj: Object, hwnd: SupportsIndex, /) -> None: ...
29
+ def load_projection(module: types.ModuleType, table_path: str, /) -> None: ...
30
+ @overload
31
+ def as_interface(obj: Object, iid: UUID | type[Object], /) -> InterfaceCapsule: ...
32
+ @overload
33
+ def as_interface(obj: None, iid: UUID | type[Object], /) -> None: ...
34
+ def get_activation_factory(
35
+ cls: type[Object], iid: UUID | type[Object], /
36
+ ) -> InterfaceCapsule: ...
37
+ @overload
38
+ def wrap_interface(
39
+ capsule: InterfaceCapsule, type: TypeForm[_TObject], /
40
+ ) -> _TObject: ...
41
+ @overload
42
+ def wrap_interface(capsule: InterfaceCapsule, qualified_name: str, /) -> Any: ...
43
+ @overload
44
+ def wrap_interface(capsule: None, type: type[Object] | str, /) -> None: ...
45
+ def hresult_error(
46
+ hresult: SupportsIndex, error_info: InterfaceCapsule | None = None, /
47
+ ) -> OSError: ...
48
+ def box_boolean(value: bool, /) -> Object: ...
49
+ def box_int8(value: SupportsIndex, /) -> Object: ...
50
+ def box_uint8(value: SupportsIndex, /) -> Object: ...
51
+ def box_int16(value: SupportsIndex, /) -> Object: ...
52
+ def box_uint16(value: SupportsIndex, /) -> Object: ...
53
+ def box_int32(value: SupportsIndex, /) -> Object: ...
54
+ def box_uint32(value: SupportsIndex, /) -> Object: ...
55
+ def box_int64(value: SupportsIndex, /) -> Object: ...
56
+ def box_uint64(value: SupportsIndex, /) -> Object: ...
57
+ def box_single(value: float, /) -> Object: ...
58
+ def box_double(value: float, /) -> Object: ...
59
+ def box_char16(value: str, /) -> Object: ...
60
+ def box_string(value: str, /) -> Object: ...
61
+ def box_guid(value: UUID, /) -> Object: ...
62
+ def box_date_time(value: datetime, /) -> Object: ...
63
+ def box_time_span(value: timedelta, /) -> Object: ...
64
+ def unbox_boolean(value: Object, /) -> bool: ...
65
+ def unbox_int8(value: Object, /) -> int: ...
66
+ def unbox_uint8(value: Object, /) -> int: ...
67
+ def unbox_int16(value: Object, /) -> int: ...
68
+ def unbox_uint16(value: Object, /) -> int: ...
69
+ def unbox_int32(value: Object, /) -> int: ...
70
+ def unbox_uint32(value: Object, /) -> int: ...
71
+ def unbox_int64(value: Object, /) -> int: ...
72
+ def unbox_uint64(value: Object, /) -> int: ...
73
+ def unbox_single(value: Object, /) -> float: ...
74
+ def unbox_double(value: Object, /) -> float: ...
75
+ def unbox_char16(value: Object, /) -> str: ...
76
+ def unbox_string(value: Object, /) -> str: ...
77
+ def unbox_guid(value: Object, /) -> UUID: ...
78
+ def unbox_date_time(value: Object, /) -> datetime: ...
79
+ def unbox_time_span(value: Object, /) -> timedelta: ...
80
+
81
+ # Reads a projection table and returns its contents as plain Python objects, so
82
+ # that test/test_table.py can check that the generator's writer and this
83
+ # module's reader agree on the format. The shape of the result follows
84
+ # runtime/src/table-format.md rather than a type of its own.
85
+ def read_table(data: Buffer, /) -> dict[str, Any]: ...
86
+
87
+ _T = TypeVar("_T")
88
+ _TObject = TypeVar("_TObject", bound=Object)
89
+
90
+ # What as_() asks of the type it is given, a projected one or an interop
91
+ # interface alike: as_(type) is type._query_interface_(obj).
92
+ class _SupportsQueryInterface(Protocol):
93
+ @classmethod
94
+ def _query_interface_(cls, obj: Object, /) -> Self: ...
95
+
96
+ _TQueryInterface = TypeVar("_TQueryInterface", bound=_SupportsQueryInterface)
97
+
98
+ # Declared as an ABCMeta although at run time it derives from type: a type
99
+ # checker requires an abstract member to be implemented only under ABCMeta, and
100
+ # the members of an interface are abstract.
101
+ class Object_Static(abc.ABCMeta):
102
+ def __instancecheck__(self, instance: Any) -> bool: ...
103
+ def __subclasscheck__(self, subclass: type) -> bool: ...
104
+
105
+ # The type of everything WinRT can hold. A Python class that implements a WinRT
106
+ # interface derives from the projected name of that interface, and therefore
107
+ # from this, without being a wrapper around a WinRT object (at run time it does
108
+ # not derive from Object, and isinstance() says it is one all the same): the
109
+ # runtime gives it the three members below as it gives a wrapper. The members
110
+ # of the interface itself are abstract, because implementing them is what
111
+ # deriving from it means.
112
+ class Object(metaclass=Object_Static):
113
+ def as_(self, type: TypeForm[_TQueryInterface], /) -> _TQueryInterface: ...
114
+ @property
115
+ def _iids_(self) -> Array[UUID]: ...
116
+ @property
117
+ def _runtime_class_name_(self) -> str: ...
118
+ # what as_() calls, which the runtime gives the projected name of an
119
+ # interface as well as the wrapper
120
+ @classmethod
121
+ def _query_interface_(cls, obj: Object, /) -> Self: ...
122
+
123
+ @final
124
+ class Array(collections.abc.Sequence[_T]):
125
+ _winrt_element_type_name_: str
126
+ def __class_getitem__(cls, key: Any) -> types.GenericAlias: ...
127
+ @overload
128
+ def __init__(self, type: TypeForm[_T], /) -> None: ...
129
+ @overload
130
+ def __init__(
131
+ self,
132
+ type: TypeForm[_T],
133
+ size: SupportsIndex,
134
+ /,
135
+ ) -> None: ...
136
+ @overload
137
+ def __init__(
138
+ self,
139
+ type: TypeForm[_T],
140
+ initializer: Buffer,
141
+ /,
142
+ ) -> None: ...
143
+ @overload
144
+ def __init__(
145
+ self,
146
+ type: TypeForm[_T],
147
+ initializer: Iterable[_T],
148
+ /,
149
+ ) -> None: ...
150
+ @overload
151
+ @deprecated("Passing a format string to Array is deprecated: pass the type instead")
152
+ def __init__(
153
+ self,
154
+ type: str,
155
+ initializer: SupportsIndex | Buffer | Iterable[Any],
156
+ /,
157
+ ) -> None: ...
158
+ def __buffer__(self, flags: int, /) -> memoryview: ...
159
+ def __release_buffer__(self, view: memoryview, /) -> None: ...
160
+ def __len__(self) -> int: ...
161
+ @overload
162
+ def __getitem__(self, index: SupportsIndex) -> _T: ...
163
+ @overload
164
+ def __getitem__(self, index: slice) -> Array[_T]: ...
165
+ def __setitem__(self, index: SupportsIndex, value: _T) -> None: ...
166
+ def __iter__(self) -> Iterator[_T]: ...
167
+ def __eq__(self, other: object, /) -> bool: ...
168
+ def __ne__(self, other: object, /) -> bool: ...
169
+ __hash__: ClassVar[None] # type: ignore[assignment]
winrt/py.typed ADDED
File without changes
@@ -0,0 +1,28 @@
1
+ from enum import IntEnum
2
+
3
+ # winrt._winrt imports uuid when it loads, from compiled code, where a freezer
4
+ # that follows a program's imports cannot see it. Everything that loads the
5
+ # runtime imports this package, so saying it here puts uuid in the bundle.
6
+ import uuid
7
+
8
+ del uuid
9
+
10
+ from winrt._winrt import init_apartment, uninit_apartment, STA, MTA
11
+
12
+
13
+ __all__ = ["ApartmentType", "init_apartment", "uninit_apartment"]
14
+
15
+
16
+ class ApartmentType(IntEnum):
17
+ """
18
+ Enumeration of COM apartment types.
19
+ """
20
+
21
+ SINGLE_THREADED = STA
22
+ """
23
+ Single-threaded apartment.
24
+ """
25
+ MULTI_THREADED = MTA
26
+ """
27
+ Multi-threaded apartment.
28
+ """
@@ -0,0 +1,488 @@
1
+ from abc import ABCMeta
2
+ import asyncio
3
+ from importlib.machinery import ModuleSpec
4
+ import os
5
+ from collections.abc import (
6
+ Callable,
7
+ Mapping,
8
+ MutableMapping,
9
+ MutableSequence,
10
+ Sequence,
11
+ )
12
+ from enum import IntEnum
13
+ from pathlib import Path
14
+ import sys
15
+ from typing import Any, Self, TypeVar, Protocol, TYPE_CHECKING, cast
16
+ import warnings
17
+
18
+ # NB: have to import Object from here instead of winrt.system to avoid circular import issues.
19
+ from winrt._winrt import (
20
+ load_projection as _load_projection,
21
+ Object,
22
+ )
23
+
24
+ # Unfortunately, we can't import at runtime because of circular imports.
25
+ if TYPE_CHECKING:
26
+ from winrt.windows.foundation import AsyncStatus
27
+
28
+
29
+ #: The file a projection package keeps its namespace's table in, beside the
30
+ #: ``__init__.py`` that loads it. It is part of the table format, which
31
+ #: ``runtime/src/table-format.md`` is the contract for; winrt-table-compiler
32
+ #: spells it for itself, as the two ends of the format spell the magic and the
33
+ #: record sizes for themselves.
34
+ TABLE_NAME = "_table.pywinrt"
35
+
36
+
37
+ def load_projection(spec: ModuleSpec) -> None:
38
+ """
39
+ Creates the Python types of one WinRT namespace from its projection table.
40
+
41
+ A projection package ships a table rather than an extension module, so this
42
+ is what its ``__init__.py`` calls before anything else: the runtime reads
43
+ the table beside it and builds the classes, interfaces and structs straight
44
+ into the module. Everything after that line - the enums, the delegate
45
+ aliases, the protocol mixins - is ordinary Python that expects them to be
46
+ there.
47
+
48
+ Args:
49
+ spec: The module's own ``__spec__``, which says where it was loaded
50
+ from and therefore where its table is.
51
+ """
52
+ if not spec.origin:
53
+ raise ImportError(f"{spec.name} was not loaded from a file")
54
+
55
+ table = os.fspath(Path(spec.origin).parent / TABLE_NAME)
56
+
57
+ try:
58
+ _load_projection(sys.modules[spec.name], table)
59
+ except OSError as error:
60
+ # The table is opened and mapped, so a missing or unreadable one
61
+ # arrives here as an OSError that says only what the operating system
62
+ # said - no file name, no module. That is nearly always a package
63
+ # whose module was copied without the data file beside it, which is
64
+ # what a freezer does when nothing tells it about the table, so the
65
+ # message has to name both and say what kind of thing is missing.
66
+ raise ImportError(
67
+ f"{spec.name} could not read its projection table, which a"
68
+ " projection package carries beside the module that loads it."
69
+ f" Reading {table} failed: {error}",
70
+ name=spec.name,
71
+ path=table,
72
+ ) from error
73
+
74
+
75
+ class WinrtIntEnum(IntEnum):
76
+ """
77
+ The base of every projected WinRT enum that is not a set of flags.
78
+
79
+ A newer version of Windows can hand back a value that the projection was
80
+ generated without, so a value with no member of its own makes a member
81
+ of its own, rather than a ``ValueError`` that fails the call it came from,
82
+ as ``IntFlag`` keeps a bit it has no member for. Such a member equals its
83
+ number, is named with it, as in ``"99"``, which no member name can be, and
84
+ does not appear when the enum is iterated.
85
+ """
86
+
87
+ @classmethod
88
+ def _missing_(cls, value: object) -> Self | None:
89
+ # A WinRT enum that is not a set of flags is a signed 32-bit integer,
90
+ # so a value WinRT could not hold is still refused.
91
+ if not isinstance(value, int) or not -(2**31) <= value < 2**31:
92
+ return None
93
+
94
+ # A bool, or a member of another enum, is made the plain number that
95
+ # every member holds.
96
+ number = int(value)
97
+
98
+ member = int.__new__(cls, number)
99
+ member._name_ = str(number)
100
+ member._value_ = number
101
+ return member
102
+
103
+ def __repr__(self) -> str:
104
+ if self._name_ not in type(self)._member_map_:
105
+ return f"<{type(self).__name__}: {self._value_!r}>"
106
+
107
+ return super().__repr__()
108
+
109
+
110
+ # Staged deprecation of the method names that pywinrt v3.x used for overloaded
111
+ # methods. DeprecationWarning is aimed at developers of code that uses pywinrt.
112
+ # In a future release, this will become FutureWarning, which is shown to end
113
+ # users as well, and after that the aliases will be removed.
114
+ # https://docs.python.org/3/library/exceptions.html#DeprecationWarning
115
+ #
116
+ # NB: The calls to the functions below are generated. See the note on the
117
+ # aliases in PyWinRT/Projection/ProjectedType.cs for everything that has to be
118
+ # removed when the aliases go away.
119
+ _LEGACY_METHOD_WARNING: type[Warning] = DeprecationWarning
120
+
121
+
122
+ def _add_alias(target: type, owner: type, alias: str, name: str) -> None:
123
+ # a real attribute of the type always wins over an alias
124
+ if alias in vars(target):
125
+ return
126
+
127
+ def method(self: Any, *args: Any) -> Any:
128
+ warnings.warn(
129
+ f"{owner.__name__}.{alias}() is deprecated, use {name}() instead",
130
+ _LEGACY_METHOD_WARNING,
131
+ stacklevel=2,
132
+ )
133
+ return getattr(self, name)(*args)
134
+
135
+ method.__name__ = alias
136
+ method.__qualname__ = f"{owner.__name__}.{alias}"
137
+ method.__doc__ = f"Deprecated alias of ``{name}()``."
138
+
139
+ setattr(target, alias, method)
140
+
141
+
142
+ def alias_method(typ: type, alias: str, name: str) -> None:
143
+ """
144
+ Adds a deprecated alias of a method to a projected type.
145
+
146
+ Args:
147
+ typ: The projected type.
148
+ alias: The name the method had in pywinrt v3.x.
149
+ name: The name of the method now.
150
+ """
151
+ _add_alias(typ, typ, alias, name)
152
+
153
+
154
+ def alias_static_method(typ: type, alias: str, name: str) -> None:
155
+ """
156
+ Adds a deprecated alias of a static method to a projected type.
157
+
158
+ Args:
159
+ typ: The projected type.
160
+ alias: The name the method had in pywinrt v3.x.
161
+ name: The name of the method now.
162
+ """
163
+ # static methods are implemented by the metaclass of the projected type
164
+ _add_alias(type(typ), typ, alias, name)
165
+
166
+
167
+ def alias_field(typ: type, name: str) -> None:
168
+ """
169
+ Adds a deprecated property for the one field a projected type used to have.
170
+
171
+ A WinRT struct that holds a single integer - an HRESULT, an event token -
172
+ is projected as a subclass of ``int`` rather than as a wrapper, so the
173
+ value is the object itself. Reading the field by the name it had in
174
+ pywinrt v3.x still works and warns.
175
+
176
+ Args:
177
+ typ: The projected type.
178
+ name: The name the field had.
179
+ """
180
+
181
+ def field(self: Any) -> Any:
182
+ warnings.warn(
183
+ f"{typ.__name__}.{name} is deprecated, "
184
+ f"the value is the {typ.__name__} itself",
185
+ _LEGACY_METHOD_WARNING,
186
+ stacklevel=2,
187
+ )
188
+ return int(self)
189
+
190
+ field.__name__ = name
191
+ field.__qualname__ = f"{typ.__name__}.{name}"
192
+ field.__doc__ = f"Deprecated: the value is the {typ.__name__} itself."
193
+
194
+ setattr(typ, name, property(field))
195
+
196
+
197
+ # NB: The types implemented in C cannot inherit from abc.ABC since Python 3.12
198
+ # so we have to implement the protocols like this instead.
199
+ # https://github.com/python/cpython/issues/103968#issuecomment-1589928055
200
+
201
+
202
+ def _register(abc_type: type, typ: type) -> None:
203
+ """
204
+ Registers typ as a virtual subclass of abc_type.
205
+
206
+ The collections.abc types are ABCMeta instances at run time, but typeshed
207
+ derives most of them from typing.Protocol without saying so, which leaves
208
+ pyright without their register() method.
209
+ """
210
+ cast(ABCMeta, abc_type).register(typ)
211
+
212
+
213
+ def _sequence_index(
214
+ self: Sequence[Any], value: Any, start: int = 0, stop: int = sys.maxsize
215
+ ) -> int:
216
+ """
217
+ Sequence.index(), with a message like the one list.index() gives rather
218
+ than none at all. It names a vector rather than the type, which may be a
219
+ wrapper such as _IVector[String] that the user never sees.
220
+ """
221
+ try:
222
+ return Sequence[Any].index(self, value, start, stop)
223
+ except ValueError:
224
+ raise ValueError("index(x): x not in vector") from None
225
+
226
+
227
+ def _mutable_sequence_remove(self: MutableSequence[Any], value: Any) -> None:
228
+ """
229
+ MutableSequence.remove(), with a message like the one list.remove() gives.
230
+ """
231
+ try:
232
+ index = Sequence[Any].index(self, value)
233
+ except ValueError:
234
+ raise ValueError("remove(x): x not in vector") from None
235
+
236
+ del self[index]
237
+
238
+
239
+ def _mutable_mapping_popitem(self: MutableMapping[Any, Any]) -> tuple[Any, Any]:
240
+ """
241
+ MutableMapping.popitem(), with a message like the one dict.popitem() gives.
242
+ """
243
+ try:
244
+ key = next(iter(self))
245
+ except StopIteration:
246
+ raise KeyError("popitem(): map is empty") from None
247
+
248
+ value = self[key]
249
+ del self[key]
250
+ return key, value
251
+
252
+
253
+ def mixin_sequence(typ: type) -> None:
254
+ """
255
+ Adds missing Python mapping methods to types that implement IVectorView and
256
+ registers the type as a Sequence.
257
+ """
258
+ # mixin methods
259
+ if not hasattr(typ, "index"):
260
+ setattr(typ, "index", _sequence_index)
261
+
262
+ if not hasattr(typ, "count"):
263
+ setattr(typ, "count", Sequence[Any].count)
264
+
265
+ if not hasattr(typ, "__contains__"):
266
+ setattr(typ, "__contains__", Sequence[Any].__contains__)
267
+
268
+ if not hasattr(typ, "__iter__"):
269
+ setattr(typ, "__iter__", Sequence[Any].__iter__)
270
+
271
+ if not hasattr(typ, "__reversed__"):
272
+ setattr(typ, "__reversed__", Sequence[Any].__reversed__)
273
+
274
+ _register(Sequence, typ)
275
+
276
+
277
+ def mixin_mutable_sequence(typ: type) -> None:
278
+ """
279
+ Adds missing Python mapping methods to types that implement IVector and
280
+ registers the type as a MutableSequence.
281
+ """
282
+ mixin_sequence(typ)
283
+
284
+ # mixin methods
285
+ if not hasattr(typ, "append"):
286
+ setattr(typ, "append", MutableSequence[Any].append)
287
+
288
+ if not hasattr(typ, "clear"):
289
+ setattr(typ, "clear", MutableSequence[Any].clear)
290
+
291
+ if not hasattr(typ, "extend"):
292
+ setattr(typ, "extend", MutableSequence[Any].extend)
293
+
294
+ if not hasattr(typ, "reverse"):
295
+ setattr(typ, "reverse", MutableSequence[Any].reverse)
296
+
297
+ if not hasattr(typ, "pop"):
298
+ setattr(typ, "pop", MutableSequence[Any].pop)
299
+
300
+ if not hasattr(typ, "remove"):
301
+ setattr(typ, "remove", _mutable_sequence_remove)
302
+
303
+ if not hasattr(typ, "__iadd__"):
304
+ setattr(typ, "__iadd__", MutableSequence[Any].__iadd__)
305
+
306
+ _register(MutableSequence, typ)
307
+
308
+
309
+ def mixin_mapping(typ: type) -> None:
310
+ """
311
+ Adds missing Python mapping methods to types that implement IMapView and
312
+ registers the type as a Mapping.
313
+ """
314
+ # mixin methods
315
+ if not hasattr(typ, "keys"):
316
+ setattr(typ, "keys", Mapping[Any, Any].keys)
317
+
318
+ if not hasattr(typ, "items"):
319
+ setattr(typ, "items", Mapping[Any, Any].items)
320
+
321
+ if not hasattr(typ, "values"):
322
+ setattr(typ, "values", Mapping[Any, Any].values)
323
+
324
+ if not hasattr(typ, "get"):
325
+ setattr(typ, "get", Mapping[Any, Any].get)
326
+
327
+ if not hasattr(typ, "__contains__"):
328
+ setattr(typ, "__contains__", Mapping[Any, Any].__contains__)
329
+
330
+ # HACK: Version check works around inheritance anomaly caused by hacky
331
+ # metaclass inheritance implementation in runtime.cpp. This works as long
332
+ # as we don't change the projection to implement rich comparison methods
333
+ # on mapping types.
334
+
335
+ if (
336
+ typ.__eq__ == object.__eq__
337
+ or typ.__eq__ == Object.__eq__
338
+ or sys.version_info < (3, 12)
339
+ ):
340
+ setattr(typ, "__eq__", Mapping[Any, Any].__eq__)
341
+ # Equal maps are different objects, so an identity hash would break
342
+ # hash(a) == hash(b) for a == b. A class derived from Mapping is
343
+ # unhashable for the same reason.
344
+ setattr(typ, "__hash__", None)
345
+
346
+ if (
347
+ typ.__ne__ == object.__ne__
348
+ or typ.__ne__ == Object.__ne__
349
+ or sys.version_info < (3, 12)
350
+ ):
351
+ setattr(typ, "__ne__", Mapping[Any, Any].__ne__)
352
+
353
+ _register(Mapping, typ)
354
+
355
+
356
+ def mixin_mutable_mapping(typ: type) -> None:
357
+ """
358
+ Adds missing Python mapping methods to types that implement IMap and
359
+ registers the type as a MutableMapping.
360
+ """
361
+ mixin_mapping(typ)
362
+
363
+ # mixin methods
364
+ if not hasattr(typ, "clear"):
365
+ setattr(typ, "clear", MutableMapping[Any, Any].clear)
366
+
367
+ if not hasattr(typ, "pop"):
368
+ setattr(typ, "pop", MutableMapping[Any, Any].pop)
369
+ # private-name-mangled attribute :-(
370
+ setattr(
371
+ typ,
372
+ "_MutableMapping__marker",
373
+ getattr(MutableMapping, "_MutableMapping__marker"),
374
+ )
375
+
376
+ if not hasattr(typ, "popitem"):
377
+ setattr(typ, "popitem", _mutable_mapping_popitem)
378
+
379
+ if not hasattr(typ, "setdefault"):
380
+ setattr(typ, "setdefault", MutableMapping[Any, Any].setdefault)
381
+
382
+ if not hasattr(typ, "update"):
383
+ setattr(typ, "update", MutableMapping[Any, Any].update)
384
+
385
+ _register(MutableMapping, typ)
386
+
387
+
388
+ T = TypeVar("T")
389
+
390
+
391
+ # MyPy wants covariant T but Pylance wants invariant. Invariant seems correct.
392
+ class AsyncOp(Protocol[T]): # type: ignore [misc]
393
+ """
394
+ Protocol that matches the four async interfaces.
395
+ """
396
+
397
+ def cancel(self) -> None: ...
398
+ @property
399
+ def status(self) -> "AsyncStatus": ...
400
+ def get_results(self) -> T: ...
401
+ @property
402
+ def completed(self) -> Callable[[Self, "AsyncStatus"], None]: ...
403
+ @completed.setter
404
+ def completed(self, value: Callable[[Self, "AsyncStatus"], None]) -> None: ...
405
+
406
+
407
+ async def wrap_async(op: AsyncOp[T]) -> T:
408
+ """
409
+ What ``await`` of an async operation runs.
410
+
411
+ An operation that has finished already is answered from
412
+ ``get_results()``. Otherwise the completed handler wakes the coroutine,
413
+ and the status, which can read ``COMPLETED`` before the handler has run,
414
+ is not asked again.
415
+
416
+ Cancelling the task asks WinRT to cancel the operation and goes on
417
+ waiting, so that nothing is left running behind a task that has moved on,
418
+ and the cancellation is raised once the operation has finished. Cancelling
419
+ the task again while it waits for that gives up waiting, and if the
420
+ operation then fails, the error goes to the loop's exception handler, as
421
+ an error that nothing retrieved from a future does.
422
+ """
423
+ from winrt.windows.foundation import AsyncStatus
424
+
425
+ if op.status != AsyncStatus.STARTED:
426
+ return op.get_results()
427
+
428
+ loop = asyncio.get_running_loop()
429
+ event = asyncio.Event()
430
+ abandoned = False
431
+
432
+ def report(finished: AsyncOp[T]) -> None:
433
+ try:
434
+ finished.get_results()
435
+ except Exception as error:
436
+ loop.call_exception_handler(
437
+ {
438
+ "message": "async operation failed after the task "
439
+ "awaiting it gave up waiting for it",
440
+ "exception": error,
441
+ "operation": finished,
442
+ }
443
+ )
444
+
445
+ def deliver(finished: AsyncOp[T], status: "AsyncStatus") -> None:
446
+ if not abandoned:
447
+ event.set()
448
+ elif status == AsyncStatus.ERROR:
449
+ report(finished)
450
+
451
+ # WinRT keeps the handler for as long as the operation exists, and the
452
+ # event reaches this coroutine and so the operation, through the task
453
+ # waiting for it. The handler lets go of what it delivers to when it runs,
454
+ # which breaks that cycle even when there is no loop left to deliver on.
455
+ pending: Callable[[AsyncOp[T], AsyncStatus], None] | None = deliver
456
+
457
+ def completed(finished: AsyncOp[T], status: "AsyncStatus") -> None:
458
+ nonlocal pending
459
+ delivery, pending = pending, None
460
+
461
+ if delivery is None:
462
+ return
463
+
464
+ try:
465
+ loop.call_soon_threadsafe(delivery, finished, status)
466
+ except RuntimeError:
467
+ # The loop is closed. A task left waiting is reported by asyncio
468
+ # when it is freed, so only an error that nothing will wait for
469
+ # is reported here, which a closed loop can still be asked to do.
470
+ if abandoned and status == AsyncStatus.ERROR:
471
+ report(finished)
472
+
473
+ op.completed = completed
474
+
475
+ try:
476
+ await event.wait()
477
+ except asyncio.CancelledError:
478
+ op.cancel()
479
+
480
+ try:
481
+ await event.wait()
482
+ except asyncio.CancelledError:
483
+ abandoned = True
484
+ raise
485
+
486
+ raise
487
+
488
+ return op.get_results()
@@ -0,0 +1,25 @@
1
+ from typing import NewType
2
+
3
+ from typing_extensions import CapsuleType
4
+
5
+ from winrt._winrt import (
6
+ as_interface,
7
+ get_activation_factory,
8
+ hresult_error,
9
+ initialize_with_window,
10
+ wrap_interface,
11
+ )
12
+
13
+ __all__ = [
14
+ "InterfaceCapsule",
15
+ "as_interface",
16
+ "get_activation_factory",
17
+ "hresult_error",
18
+ "initialize_with_window",
19
+ "wrap_interface",
20
+ ]
21
+
22
+ # A capsule named "winrt.interface" that holds one reference to a COM interface,
23
+ # which its destructor releases. It is how a WinRT object crosses between the
24
+ # runtime and a compiled interop module, which share no C ABI.
25
+ InterfaceCapsule = NewType("InterfaceCapsule", CapsuleType)
winrt/runtime/py.typed ADDED
File without changes
@@ -0,0 +1,191 @@
1
+ from typing import TYPE_CHECKING, Annotated, Any, Protocol, TypeAlias, runtime_checkable
2
+ import warnings
3
+
4
+ from typing_extensions import Buffer as _Buffer, deprecated
5
+
6
+ from winrt._winrt import (
7
+ Array,
8
+ Object,
9
+ Object_Static,
10
+ box_boolean,
11
+ box_char16,
12
+ box_date_time,
13
+ box_double,
14
+ box_guid,
15
+ box_int8,
16
+ box_int16,
17
+ box_int32,
18
+ box_int64,
19
+ box_single,
20
+ box_string,
21
+ box_time_span,
22
+ box_uint8,
23
+ box_uint16,
24
+ box_uint32,
25
+ box_uint64,
26
+ unbox_boolean,
27
+ unbox_char16,
28
+ unbox_date_time,
29
+ unbox_double,
30
+ unbox_guid,
31
+ unbox_int8,
32
+ unbox_int16,
33
+ unbox_int32,
34
+ unbox_int64,
35
+ unbox_single,
36
+ unbox_string,
37
+ unbox_time_span,
38
+ unbox_uint8,
39
+ unbox_uint16,
40
+ unbox_uint32,
41
+ unbox_uint64,
42
+ )
43
+ import winrt.runtime._internals
44
+
45
+
46
+ class BufferFormat(str):
47
+ """
48
+ The `PEP 3118`_ buffer format of a WinRT fundamental type.
49
+
50
+ This is what :attr:`memoryview.format` reports for an :class:`Array` of
51
+ that type and what :class:`Array` accepts in place of the type.
52
+
53
+ .. _PEP 3118: https://peps.python.org/pep-3118/
54
+ """
55
+
56
+ __slots__ = ()
57
+
58
+ _annotation_kind_ = "buffer_format"
59
+
60
+
61
+ class StructFormat(str):
62
+ """
63
+ The :mod:`struct` module format of a WinRT fundamental type.
64
+
65
+ It is the same character as the buffer format for every type but
66
+ ``Char16``, where it is ``"H"``, because :mod:`struct` has no ``"u"``
67
+ format at all.
68
+ """
69
+
70
+ __slots__ = ()
71
+
72
+ _annotation_kind_ = "struct_format"
73
+
74
+
75
+ class WinrtSignature(str):
76
+ """
77
+ The WinRT type signature of a WinRT fundamental type.
78
+
79
+ The signature of a parameterized type is composed from the signatures of
80
+ its type arguments, and its interface identifier is hashed from that.
81
+ """
82
+
83
+ __slots__ = ()
84
+
85
+ _annotation_kind_ = "winrt_signature"
86
+
87
+
88
+ # The fundamental types that no Python type names on its own, each annotated
89
+ # with one spelling of what it is per kind of format. A consumer finds the one
90
+ # it wants by isinstance over typing.get_args(), never by position.
91
+ Int8 = Annotated[int, BufferFormat("b"), StructFormat("b"), WinrtSignature("i1")]
92
+ UInt8 = Annotated[int, BufferFormat("B"), StructFormat("B"), WinrtSignature("u1")]
93
+ Int16 = Annotated[int, BufferFormat("h"), StructFormat("h"), WinrtSignature("i2")]
94
+ UInt16 = Annotated[int, BufferFormat("H"), StructFormat("H"), WinrtSignature("u2")]
95
+ Int32 = Annotated[int, BufferFormat("i"), StructFormat("i"), WinrtSignature("i4")]
96
+ UInt32 = Annotated[int, BufferFormat("I"), StructFormat("I"), WinrtSignature("u4")]
97
+ Int64 = Annotated[int, BufferFormat("q"), StructFormat("q"), WinrtSignature("i8")]
98
+ UInt64 = Annotated[int, BufferFormat("Q"), StructFormat("Q"), WinrtSignature("u8")]
99
+ Single = Annotated[float, BufferFormat("f"), StructFormat("f"), WinrtSignature("f4")]
100
+ Double = Annotated[float, BufferFormat("d"), StructFormat("d"), WinrtSignature("f8")]
101
+ Char16 = Annotated[str, BufferFormat("u"), StructFormat("H"), WinrtSignature("c2")]
102
+
103
+ winrt.runtime._internals.mixin_sequence(Array)
104
+
105
+ # What an IBuffer or an array parameter takes besides an Array: any buffer,
106
+ # named for whether WinRT reads it or writes into it, as typeshed's aliases of
107
+ # the same names are.
108
+ ReadableBuffer: TypeAlias = _Buffer
109
+ WriteableBuffer: TypeAlias = _Buffer
110
+
111
+ # PEP 702 deprecates a class or a function, not an alias, so the type checkers
112
+ # see a deprecated copy of typeshed's collections.abc.Buffer, and the real one
113
+ # is what __getattr__() hands out at run time.
114
+ if TYPE_CHECKING:
115
+
116
+ @deprecated(
117
+ "Use collections.abc.Buffer instead, "
118
+ "or typing_extensions.Buffer before Python 3.12"
119
+ )
120
+ @runtime_checkable
121
+ class Buffer(Protocol):
122
+ def __buffer__(self, flags: int, /) -> memoryview: ...
123
+
124
+ else:
125
+
126
+ def __getattr__(name: str) -> Any:
127
+ if name == "Buffer":
128
+ warnings.warn(
129
+ "winrt.system.Buffer is deprecated: use collections.abc.Buffer, "
130
+ "or typing_extensions.Buffer before Python 3.12",
131
+ DeprecationWarning,
132
+ stacklevel=2,
133
+ )
134
+ return _Buffer
135
+
136
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
137
+
138
+
139
+ __all__ = [
140
+ "BufferFormat",
141
+ "StructFormat",
142
+ "WinrtSignature",
143
+ "Int8",
144
+ "UInt8",
145
+ "Int16",
146
+ "UInt16",
147
+ "Int32",
148
+ "UInt32",
149
+ "Int64",
150
+ "UInt64",
151
+ "Single",
152
+ "Double",
153
+ "Char16",
154
+ "Object",
155
+ "Object_Static",
156
+ "Array",
157
+ "ReadableBuffer",
158
+ "WriteableBuffer",
159
+ "box_boolean",
160
+ "box_int8",
161
+ "box_uint8",
162
+ "box_int16",
163
+ "box_uint16",
164
+ "box_int32",
165
+ "box_uint32",
166
+ "box_int64",
167
+ "box_uint64",
168
+ "box_single",
169
+ "box_double",
170
+ "box_char16",
171
+ "box_string",
172
+ "box_guid",
173
+ "box_date_time",
174
+ "box_time_span",
175
+ "unbox_boolean",
176
+ "unbox_int8",
177
+ "unbox_uint8",
178
+ "unbox_int16",
179
+ "unbox_uint16",
180
+ "unbox_int32",
181
+ "unbox_uint32",
182
+ "unbox_int64",
183
+ "unbox_uint64",
184
+ "unbox_single",
185
+ "unbox_double",
186
+ "unbox_char16",
187
+ "unbox_string",
188
+ "unbox_guid",
189
+ "unbox_date_time",
190
+ "unbox_time_span",
191
+ ]
@@ -0,0 +1,47 @@
1
+ """Common HRESULT error codes."""
2
+
3
+ from winrt.windows.foundation import HResult
4
+
5
+ # https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
6
+ _ERROR_FILE_NOT_FOUND = 2
7
+
8
+ # https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299-
9
+ _ERROR_CANCELLED = 1223
10
+
11
+
12
+ # https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-hresult_facility
13
+ _FACILITY_WIN32 = 7
14
+
15
+
16
+ # https://learn.microsoft.com/en-us/windows/win32/api/winerror/nf-winerror-hresult_from_win32
17
+ def _HRESULT_FROM_WIN32(error_code: int) -> HResult:
18
+ x = HResult(error_code)
19
+ return (
20
+ x
21
+ if x <= 0
22
+ else HResult((x & 0x0000FFFF) | (_FACILITY_WIN32 << 16) | 0x80000000)
23
+ )
24
+
25
+
26
+ # common errors from CppWinRT
27
+ S_OK = HResult(0)
28
+ E_FAIL = HResult(0x80004005)
29
+ E_ACCESSDENIED = HResult(0x80070005)
30
+ E_NOTIMPL = HResult(0x80004001)
31
+ E_INVALIDARG = HResult(0x80070057)
32
+ E_BOUNDS = HResult(0x8000000B)
33
+ E_NOINTERFACE = HResult(0x80004002)
34
+ E_CHANGED_STATE = HResult(0x8000000C)
35
+ E_ILLEGAL_METHOD_CALL = HResult(0x8000000E)
36
+ E_ILLEGAL_STATE_CHANGE = HResult(0x8000000D)
37
+ E_ILLEGAL_DELEGATE_ASSIGNMENT = HResult(0x80000018)
38
+ E_OUTOFMEMORY = HResult(0x8007000E)
39
+ CLASS_E_CLASSNOTAVAILABLE = HResult(0x80040111)
40
+ CO_E_NOTINITIALIZED = HResult(0x800401F0)
41
+ REGDB_E_CLASSNOTREG = HResult(0x80040154)
42
+ RPC_E_WRONG_THREAD = HResult(0x8001010E)
43
+ WIN32_ERROR_FILE_NOT_FOUND = _HRESULT_FROM_WIN32(_ERROR_FILE_NOT_FOUND)
44
+ WIN32_ERROR_CANCELLED = _HRESULT_FROM_WIN32(_ERROR_CANCELLED)
45
+
46
+ # Errors defined by PyWinRT
47
+ PYWINRT_E_UNRAISABLE_PYTHON_EXCEPTION = HResult(0xA0EE4005)
winrt/system/py.typed ADDED
File without changes
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.4
2
+ Name: winrt-runtime
3
+ Version: 4.0.0
4
+ Summary: The runtime that every PyWinRT projection package runs on
5
+ License-Expression: MIT
6
+ Project-URL: Documentation, https://pywinrt.readthedocs.io
7
+ Project-URL: Repository, https://github.com/pywinrt/pywinrt
8
+ Project-URL: Changelog, https://github.com/pywinrt/pywinrt/blob/main/runtime/CHANGELOG.md
9
+ Classifier: Operating System :: Microsoft :: Windows
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Programming Language :: Python :: 3.15
16
+ Classifier: Programming Language :: Python :: Implementation :: CPython
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: typing_extensions>=4.12.2
24
+ Dynamic: license-file
25
+
26
+ # winrt-runtime
27
+
28
+ This package provides the PyWinRT runtime including the `winrt.system` module.
29
+
30
+ Every PyWinRT package requires it, so pip installs it with any of them. Each
31
+ WinRT namespace is a package of its own, so install the package of each
32
+ namespace your code imports from, such as `winrt-Windows.Foundation`.
33
+
34
+ ## For interop modules
35
+
36
+ Compiled code outside the runtime, such as the interop packages, exchanges
37
+ WinRT objects with it through the Python functions of `winrt.runtime.interop`
38
+ rather than a C ABI: `as_interface()` gives an interface of a projected object
39
+ as an interface pointer capsule, `wrap_interface()` makes a projected object of
40
+ one, and `hresult_error()` builds the exception that a failed call raises. An interface pointer capsule is named `"winrt.interface"`
41
+ and holds one reference, which its destructor releases.
@@ -0,0 +1,18 @@
1
+ winrt/_winrt.cp315-win32.pyd,sha256=qPb_-b7rZYMByWIHCUayYzoLWGoklUBcv1gbBYpB998,489984
2
+ winrt/_winrt.pyi,sha256=3lFW6xIHTrSPUjYp7CLIJx7vvCuNeHiN6RJa8gkqS20,6444
3
+ winrt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ winrt/__pyinstaller/__init__.py,sha256=rmXUl7CBERuK6iPwf_hIrpM67iJMGKds-ugl9XB5xb8,336
5
+ winrt/__pyinstaller/hook-winrt.py,sha256=wIsqk5iXLgIO3ktYqmoEhd3tatD0ODY_wcM3RbDrLj0,3201
6
+ winrt/runtime/__init__.py,sha256=XDwoFBCKJWVWHYDEQh6t5EhOkd776ThHllH93bUWuKo,648
7
+ winrt/runtime/_internals.py,sha256=f0lbSO6sBk5XHf80m8YknjMjHmCRz6PWJn1siLOdziQ,16328
8
+ winrt/runtime/interop.py,sha256=91zDKvOCPJzSWg8FtBYcdXMTBq16kOTvZqZEYFemtYA,658
9
+ winrt/runtime/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ winrt/system/__init__.py,sha256=szmgICmY0yBtzUYc_vYWnMKKvQvDXYqQUdm1uf_O8Ss,5103
11
+ winrt/system/hresult.py,sha256=J_CKmHtqTL4JFv-JTpdSTAMeHHAm_UjFPNJ5ulgZXxE,1579
12
+ winrt/system/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ winrt_runtime-4.0.0.dist-info/licenses/LICENSE,sha256=dyVKOMqPV0fimbzMhqN3zpg6K6Y2OlekwrdfiZTBm8M,1225
14
+ winrt_runtime-4.0.0.dist-info/METADATA,sha256=ZL6UORpX-KV0eesu2fHTRmhw2y6XG76dZwM_UldFizo,1963
15
+ winrt_runtime-4.0.0.dist-info/WHEEL,sha256=hw69xxiYuOcOqid9WoScsymTbZ3eDs5HQ4gUZZtdDhs,97
16
+ winrt_runtime-4.0.0.dist-info/entry_points.txt,sha256=9q8Xbd5-xvYTUwc1m7ddw7ln0lBVYxnGjmB8ot_uCWc,62
17
+ winrt_runtime-4.0.0.dist-info/top_level.txt,sha256=BzwQb4dZRt0NxCXi10ARjWsox7Asmtf_lXrw_KR-D_E,6
18
+ winrt_runtime-4.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: false
4
+ Tag: cp315-cp315-win32
5
+
@@ -0,0 +1,2 @@
1
+ [pyinstaller40]
2
+ hook-dirs = winrt.__pyinstaller:get_hook_dirs
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation. All rights reserved.
4
+ Copyright (c) 2021-2026 David Lechner <david@pybricks.com>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE
@@ -0,0 +1 @@
1
+ winrt