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.
- winrt/__pyinstaller/__init__.py +13 -0
- winrt/__pyinstaller/hook-winrt.py +85 -0
- winrt/_winrt.cp315-win32.pyd +0 -0
- winrt/_winrt.pyi +169 -0
- winrt/py.typed +0 -0
- winrt/runtime/__init__.py +28 -0
- winrt/runtime/_internals.py +488 -0
- winrt/runtime/interop.py +25 -0
- winrt/runtime/py.typed +0 -0
- winrt/system/__init__.py +191 -0
- winrt/system/hresult.py +47 -0
- winrt/system/py.typed +0 -0
- winrt_runtime-4.0.0.dist-info/METADATA +41 -0
- winrt_runtime-4.0.0.dist-info/RECORD +18 -0
- winrt_runtime-4.0.0.dist-info/WHEEL +5 -0
- winrt_runtime-4.0.0.dist-info/entry_points.txt +2 -0
- winrt_runtime-4.0.0.dist-info/licenses/LICENSE +22 -0
- winrt_runtime-4.0.0.dist-info/top_level.txt +1 -0
|
@@ -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()
|
winrt/runtime/interop.py
ADDED
|
@@ -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
|
winrt/system/__init__.py
ADDED
|
@@ -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
|
+
]
|
winrt/system/hresult.py
ADDED
|
@@ -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,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
|