pumpkin-api-py 0.1.0__py3-none-any.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.
- componentize_py_async_support/__init__.py +570 -0
- componentize_py_async_support/futures.py +149 -0
- componentize_py_async_support/streams.py +345 -0
- componentize_py_runtime.pyi +40 -0
- componentize_py_types.py +32 -0
- poll_loop.py +440 -0
- pumpkin_api/__init__.py +41 -0
- pumpkin_api/build.py +68 -0
- pumpkin_api/impl.py +355 -0
- pumpkin_api/wit/advancement.wit +41 -0
- pumpkin_api/wit/attributes.wit +56 -0
- pumpkin_api/wit/bedrock-packets.wit +1709 -0
- pumpkin_api/wit/biomes.wit +72 -0
- pumpkin_api/wit/block-entity.wit +423 -0
- pumpkin_api/wit/boss-bar.wit +83 -0
- pumpkin_api/wit/command.wit +244 -0
- pumpkin_api/wit/common.wit +261 -0
- pumpkin_api/wit/context.wit +61 -0
- pumpkin_api/wit/damage-types.wit +57 -0
- pumpkin_api/wit/data-components.wit +117 -0
- pumpkin_api/wit/datapack.wit +54 -0
- pumpkin_api/wit/display.wit +171 -0
- pumpkin_api/wit/enchantments.wit +102 -0
- pumpkin_api/wit/entity-statuses.wit +68 -0
- pumpkin_api/wit/entity-types.wit +164 -0
- pumpkin_api/wit/entity.wit +1 -0
- pumpkin_api/wit/event.wit +2435 -0
- pumpkin_api/wit/forms.wit +51 -0
- pumpkin_api/wit/game-events.wit +67 -0
- pumpkin_api/wit/game-rules.wit +69 -0
- pumpkin_api/wit/gui.wit +39 -0
- pumpkin_api/wit/i18n.wit +21 -0
- pumpkin_api/wit/inventory.wit +78 -0
- pumpkin_api/wit/ipc.wit +7 -0
- pumpkin_api/wit/item-stack.wit +104 -0
- pumpkin_api/wit/java-dialogs.wit +155 -0
- pumpkin_api/wit/java-packets.wit +1838 -0
- pumpkin_api/wit/log.wit +14 -0
- pumpkin_api/wit/metadata.wit +19 -0
- pumpkin_api/wit/particles.wit +131 -0
- pumpkin_api/wit/permission.wit +46 -0
- pumpkin_api/wit/player.wit +1432 -0
- pumpkin_api/wit/plugin.wit +121 -0
- pumpkin_api/wit/potions.wit +52 -0
- pumpkin_api/wit/recipe.wit +88 -0
- pumpkin_api/wit/scheduler.wit +24 -0
- pumpkin_api/wit/scoreboard.wit +111 -0
- pumpkin_api/wit/screens.wit +31 -0
- pumpkin_api/wit/server.wit +286 -0
- pumpkin_api/wit/sounds.wit +1987 -0
- pumpkin_api/wit/statistics.wit +94 -0
- pumpkin_api/wit/status-effect.wit +54 -0
- pumpkin_api/wit/text.wit +68 -0
- pumpkin_api/wit/uuid.wit +16 -0
- pumpkin_api/wit/world.wit +1050 -0
- pumpkin_api_py-0.1.0.dist-info/METADATA +53 -0
- pumpkin_api_py-0.1.0.dist-info/RECORD +108 -0
- pumpkin_api_py-0.1.0.dist-info/WHEEL +4 -0
- pumpkin_api_py-0.1.0.dist-info/entry_points.txt +2 -0
- pumpkin_api_py-0.1.0.dist-info/licenses/LICENSE-APACHE +176 -0
- pumpkin_api_py-0.1.0.dist-info/licenses/LICENSE-MIT +21 -0
- wit_world/__init__.py +114 -0
- wit_world/exports/__init__.py +19 -0
- wit_world/exports/metadata.py +24 -0
- wit_world/imports/__init__.py +0 -0
- wit_world/imports/advancement.py +56 -0
- wit_world/imports/attributes.py +66 -0
- wit_world/imports/bedrock_packets.py +2413 -0
- wit_world/imports/biomes.py +81 -0
- wit_world/imports/block_entity.py +1353 -0
- wit_world/imports/boss_bar.py +137 -0
- wit_world/imports/command.py +705 -0
- wit_world/imports/common.py +335 -0
- wit_world/imports/context.py +91 -0
- wit_world/imports/damage_types.py +66 -0
- wit_world/imports/data_components.py +126 -0
- wit_world/imports/datapack.py +124 -0
- wit_world/imports/display.py +295 -0
- wit_world/imports/enchantments.py +129 -0
- wit_world/imports/entity_statuses.py +77 -0
- wit_world/imports/entity_types.py +173 -0
- wit_world/imports/event.py +3558 -0
- wit_world/imports/forms.py +98 -0
- wit_world/imports/game_events.py +76 -0
- wit_world/imports/game_rules.py +88 -0
- wit_world/imports/gui.py +81 -0
- wit_world/imports/i18n.py +35 -0
- wit_world/imports/inventory.py +159 -0
- wit_world/imports/ipc.py +20 -0
- wit_world/imports/item_stack.py +206 -0
- wit_world/imports/java_dialogs.py +208 -0
- wit_world/imports/java_packets.py +3560 -0
- wit_world/imports/logging.py +30 -0
- wit_world/imports/particles.py +140 -0
- wit_world/imports/permission.py +71 -0
- wit_world/imports/player.py +1753 -0
- wit_world/imports/potions.py +61 -0
- wit_world/imports/recipe.py +120 -0
- wit_world/imports/scheduler.py +44 -0
- wit_world/imports/scoreboard.py +167 -0
- wit_world/imports/screens.py +40 -0
- wit_world/imports/server.py +493 -0
- wit_world/imports/sounds.py +1996 -0
- wit_world/imports/statistics.py +103 -0
- wit_world/imports/status_effect.py +63 -0
- wit_world/imports/text.py +156 -0
- wit_world/imports/uuid.py +36 -0
- wit_world/imports/world.py +1640 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import componentize_py_runtime
|
|
2
|
+
import componentize_py_async_support
|
|
3
|
+
import weakref
|
|
4
|
+
|
|
5
|
+
from typing import TypeVar, Generic, cast, Self, Any, Callable
|
|
6
|
+
from types import TracebackType
|
|
7
|
+
from componentize_py_async_support import _ReturnCode
|
|
8
|
+
|
|
9
|
+
T = TypeVar('T')
|
|
10
|
+
|
|
11
|
+
class FutureReader(Generic[T]):
|
|
12
|
+
"""Represents the readable end of a Component Model `future`.
|
|
13
|
+
|
|
14
|
+
Each object of this type should be closed promptly using either context
|
|
15
|
+
management (e.g. a `with` statement) or by calling `read` in order to notify
|
|
16
|
+
the owner of the writable end of the `future` that the readable end has been
|
|
17
|
+
closed. If the object becomes unreachable without being closed, it will be
|
|
18
|
+
closed via finalization.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
def __init__(self, type_: int, handle: int):
|
|
22
|
+
"""Constructor for internal use by generated code.
|
|
23
|
+
|
|
24
|
+
Application code should not call this directly. Instead,
|
|
25
|
+
`componentize-py` will generate a constructor function for each unique
|
|
26
|
+
`future` type used by the target world. Each such function will return
|
|
27
|
+
a (`FutureReader`, `FutureWriter`) pair and use this constructor behind
|
|
28
|
+
the scenes.
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
self.type_ = type_
|
|
32
|
+
self.handle: int | None = handle
|
|
33
|
+
self.finalizer = weakref.finalize(self, componentize_py_runtime.future_drop_readable, type_, handle)
|
|
34
|
+
|
|
35
|
+
async def read(self) -> T:
|
|
36
|
+
"""Asynchronously read the value sent to this `future`.
|
|
37
|
+
|
|
38
|
+
The awaitable returned by this function will resolve when a value has
|
|
39
|
+
been delivered to the `future`.
|
|
40
|
+
|
|
41
|
+
Calling this function consumes the target object; any attempt to call
|
|
42
|
+
`read` more than once will raise an `AssertionError`.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
self.finalizer.detach()
|
|
47
|
+
handle = self.handle
|
|
48
|
+
self.handle = None
|
|
49
|
+
if handle is not None:
|
|
50
|
+
result = await componentize_py_async_support.await_result(
|
|
51
|
+
componentize_py_runtime.future_read(self.type_, handle)
|
|
52
|
+
)
|
|
53
|
+
componentize_py_runtime.future_drop_readable(self.type_, handle)
|
|
54
|
+
return cast(T, result)
|
|
55
|
+
else:
|
|
56
|
+
raise AssertionError
|
|
57
|
+
|
|
58
|
+
def __enter__(self) -> Self:
|
|
59
|
+
return self
|
|
60
|
+
|
|
61
|
+
def __exit__(self,
|
|
62
|
+
exc_type: type[BaseException] | None,
|
|
63
|
+
exc_value: BaseException | None,
|
|
64
|
+
traceback: TracebackType | None) -> bool | None:
|
|
65
|
+
if self.handle is not None:
|
|
66
|
+
self.finalizer.detach()
|
|
67
|
+
handle = self.handle
|
|
68
|
+
self.handle = None
|
|
69
|
+
componentize_py_runtime.future_drop_readable(self.type_, handle)
|
|
70
|
+
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
async def _write(type_: int, handle: int, value: Any) -> None:
|
|
74
|
+
await componentize_py_async_support.await_result(
|
|
75
|
+
componentize_py_runtime.future_write(type_, handle, value)
|
|
76
|
+
)
|
|
77
|
+
componentize_py_runtime.future_drop_writable(type_, handle)
|
|
78
|
+
|
|
79
|
+
def _write_default(type_: int, handle: int, default: Callable[[], Any]) -> None:
|
|
80
|
+
componentize_py_async_support.spawn(_write(type_, handle, default()))
|
|
81
|
+
|
|
82
|
+
class FutureWriter(Generic[T]):
|
|
83
|
+
"""Represents the writable end of a Component Model `future`.
|
|
84
|
+
|
|
85
|
+
Each object of this type should be closed promptly using either context
|
|
86
|
+
management (e.g. a `with` statement) or by calling `write` in order to send
|
|
87
|
+
a value to the readable end of the `future. If the object becomes
|
|
88
|
+
unreachable without being closed, it will be closed via finalization after
|
|
89
|
+
sending the default value which was specified during construction.
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
def __init__(self, type_: int, handle: int, default: Callable[[], T]):
|
|
93
|
+
"""Constructor for internal use by generated code.
|
|
94
|
+
|
|
95
|
+
Application code should not call this directly. Instead,
|
|
96
|
+
`componentize-py` will generate a constructor function for each unique
|
|
97
|
+
`future` type used by the target world. Each such function will return
|
|
98
|
+
a (`FutureReader`, `FutureWriter`) pair and use this constructor behind
|
|
99
|
+
the scenes.
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
self.type_ = type_
|
|
103
|
+
self.handle: int | None = handle
|
|
104
|
+
self.default = default
|
|
105
|
+
self.finalizer = weakref.finalize(self, _write_default, type_, handle, default)
|
|
106
|
+
|
|
107
|
+
async def write(self, value: T) -> bool:
|
|
108
|
+
"""Asynchronously write a value to the `future`.
|
|
109
|
+
|
|
110
|
+
The awaitable returned by this function will resolve once either the
|
|
111
|
+
value has been delivered to the readable end of the `future` or the
|
|
112
|
+
readable end has been closed.
|
|
113
|
+
|
|
114
|
+
Calling this function consumes the target object; any attempt to call
|
|
115
|
+
`write` more than once will raise an `AssertionError`.
|
|
116
|
+
|
|
117
|
+
"""
|
|
118
|
+
self.finalizer.detach()
|
|
119
|
+
handle = self.handle
|
|
120
|
+
self.handle = None
|
|
121
|
+
if handle is not None:
|
|
122
|
+
code, _ = await componentize_py_async_support.await_result(
|
|
123
|
+
componentize_py_runtime.future_write(self.type_, handle, value)
|
|
124
|
+
)
|
|
125
|
+
componentize_py_runtime.future_drop_writable(self.type_, handle)
|
|
126
|
+
match code:
|
|
127
|
+
case _ReturnCode.COMPLETED:
|
|
128
|
+
return True
|
|
129
|
+
case _ReturnCode.DROPPED:
|
|
130
|
+
return False
|
|
131
|
+
case _ReturnCode.CANCELLED:
|
|
132
|
+
# todo
|
|
133
|
+
raise NotImplementedError
|
|
134
|
+
case _:
|
|
135
|
+
raise AssertionError
|
|
136
|
+
else:
|
|
137
|
+
raise AssertionError
|
|
138
|
+
|
|
139
|
+
def __enter__(self) -> Self:
|
|
140
|
+
return self
|
|
141
|
+
|
|
142
|
+
def __exit__(self,
|
|
143
|
+
exc_type: type[BaseException] | None,
|
|
144
|
+
exc_value: BaseException | None,
|
|
145
|
+
traceback: TracebackType | None) -> bool | None:
|
|
146
|
+
if self.handle is not None:
|
|
147
|
+
componentize_py_async_support.spawn(self.write(self.default()))
|
|
148
|
+
|
|
149
|
+
return None
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import componentize_py_runtime
|
|
2
|
+
import componentize_py_async_support
|
|
3
|
+
import weakref
|
|
4
|
+
|
|
5
|
+
from typing import TypeVar, Generic, Self, cast
|
|
6
|
+
from types import TracebackType
|
|
7
|
+
from componentize_py_async_support import _ReturnCode
|
|
8
|
+
|
|
9
|
+
class ByteStreamReader:
|
|
10
|
+
"""Represents the readable end of a Component Model `stream<u8>`.
|
|
11
|
+
|
|
12
|
+
Each object of this type should be closed promptly using context management
|
|
13
|
+
(e.g. a `with` statement) in order to notify the owner of the writable end
|
|
14
|
+
of the `stream` that the readable end has been closed. If the object
|
|
15
|
+
becomes unreachable without being closed, it will be closed via
|
|
16
|
+
finalization.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
def __init__(self, type_: int, handle: int):
|
|
20
|
+
"""Constructor for internal use by generated code.
|
|
21
|
+
|
|
22
|
+
Application code should not call this directly. Instead,
|
|
23
|
+
`componentize-py` will generate `byte_stream` function if the target
|
|
24
|
+
world uses the `stream<u8>` type. That function will return a
|
|
25
|
+
(`ByteStreamReader`, `ByteStreamWriter`) pair and use this constructor
|
|
26
|
+
behind the scenes.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
self.writer_dropped = False
|
|
30
|
+
self.type_ = type_
|
|
31
|
+
self.handle: int | None = handle
|
|
32
|
+
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_readable, type_, handle)
|
|
33
|
+
|
|
34
|
+
async def read(self, max_count: int) -> bytes:
|
|
35
|
+
"""Asynchronously read up to `max_count` bytes sent to this `stream`.
|
|
36
|
+
|
|
37
|
+
The awaitable returned by this function will resolve when either at
|
|
38
|
+
least one byte has been delivered to the `stream` or the writable end
|
|
39
|
+
has been closed (in which case the `writer_dropped` field will be set to
|
|
40
|
+
`True`).
|
|
41
|
+
|
|
42
|
+
Only one `read` operation is allowed at a time for a given object. Any
|
|
43
|
+
attempt to start a second read while the first is still in progress will
|
|
44
|
+
raise an `AssertionError`.
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
if self.writer_dropped:
|
|
48
|
+
return bytes()
|
|
49
|
+
|
|
50
|
+
handle = self.handle
|
|
51
|
+
self.handle = None
|
|
52
|
+
code, values = await self._read(max_count, handle)
|
|
53
|
+
self.handle = handle
|
|
54
|
+
|
|
55
|
+
if code == _ReturnCode.DROPPED:
|
|
56
|
+
self.writer_dropped = True
|
|
57
|
+
|
|
58
|
+
return values
|
|
59
|
+
|
|
60
|
+
async def _read(self, max_count: int, handle: int | None) -> tuple[int, bytes]:
|
|
61
|
+
if handle is not None:
|
|
62
|
+
return cast(tuple[int, bytes], await componentize_py_async_support.await_result(
|
|
63
|
+
componentize_py_runtime.stream_read(self.type_, handle, max_count)
|
|
64
|
+
))
|
|
65
|
+
else:
|
|
66
|
+
raise AssertionError
|
|
67
|
+
|
|
68
|
+
def __enter__(self) -> Self:
|
|
69
|
+
return self
|
|
70
|
+
|
|
71
|
+
def __exit__(self,
|
|
72
|
+
exc_type: type[BaseException] | None,
|
|
73
|
+
exc_value: BaseException | None,
|
|
74
|
+
traceback: TracebackType | None) -> bool | None:
|
|
75
|
+
self.finalizer.detach()
|
|
76
|
+
handle = self.handle
|
|
77
|
+
self.handle = None
|
|
78
|
+
if handle is not None:
|
|
79
|
+
componentize_py_runtime.stream_drop_readable(self.type_, handle)
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
class ByteStreamWriter:
|
|
83
|
+
"""Represents the writable end of a Component Model `stream<u8>`.
|
|
84
|
+
|
|
85
|
+
Each object of this type should be closed promptly using context management
|
|
86
|
+
(e.g. a `with` statement) in order to notify the owner of the readable end
|
|
87
|
+
of the `stream` that the writable end has been closed. If the object
|
|
88
|
+
becomes unreachable without being closed, it will be closed via
|
|
89
|
+
finalization.
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
def __init__(self, type_: int, handle: int):
|
|
93
|
+
"""Constructor for internal use by generated code.
|
|
94
|
+
|
|
95
|
+
Application code should not call this directly. Instead,
|
|
96
|
+
`componentize-py` will generate `byte_stream` function if the target
|
|
97
|
+
world uses the `stream<u8>` type. That function will return a
|
|
98
|
+
(`ByteStreamReader`, `ByteStreamWriter`) pair and use this constructor
|
|
99
|
+
behind the scenes.
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
self.reader_dropped = False
|
|
103
|
+
self.type_ = type_
|
|
104
|
+
self.handle: int | None = handle
|
|
105
|
+
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_writable, type_, handle)
|
|
106
|
+
|
|
107
|
+
async def write(self, source: bytes) -> int:
|
|
108
|
+
"""Asynchronously write (some of) the specified bytes to the `stream`.
|
|
109
|
+
|
|
110
|
+
The awaitable returned by this function will resolve when either at
|
|
111
|
+
least one byte has been delivered to the `stream` or the readable end
|
|
112
|
+
has been closed (in which case the `reader_dropped` field will be set to
|
|
113
|
+
`True`).
|
|
114
|
+
|
|
115
|
+
The return value is the total number of bytes delivered (which may be
|
|
116
|
+
less than `len(source)`). See also `write_all`, which attempts to write
|
|
117
|
+
the entire buffer before returning.
|
|
118
|
+
|
|
119
|
+
Only one `write` operation is allowed at a time for a given object. Any
|
|
120
|
+
attempt to start a second write while the first is still in progress
|
|
121
|
+
will raise an `AssertionError`.
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
if self.reader_dropped:
|
|
125
|
+
return 0
|
|
126
|
+
|
|
127
|
+
handle = self.handle
|
|
128
|
+
self.handle = None
|
|
129
|
+
code, count = await self._write(source, handle)
|
|
130
|
+
self.handle = handle
|
|
131
|
+
|
|
132
|
+
if code == _ReturnCode.DROPPED:
|
|
133
|
+
self.reader_dropped = True
|
|
134
|
+
|
|
135
|
+
return count
|
|
136
|
+
|
|
137
|
+
async def _write(self, source: bytes, handle: int | None) -> tuple[int, int]:
|
|
138
|
+
if handle is not None:
|
|
139
|
+
return await componentize_py_async_support.await_result(
|
|
140
|
+
componentize_py_runtime.stream_write(self.type_, handle, source)
|
|
141
|
+
)
|
|
142
|
+
else:
|
|
143
|
+
raise AssertionError
|
|
144
|
+
|
|
145
|
+
async def write_all(self, source: bytes) -> int:
|
|
146
|
+
"""Asynchronously write the specified bytes to the `stream`.
|
|
147
|
+
|
|
148
|
+
This calls `write` in a loop until either the entire buffer has been
|
|
149
|
+
delivered or the readable end of the `stream` has been closed. The
|
|
150
|
+
return value is the total number of bytes delivered (which may be less
|
|
151
|
+
than `len(source)`).
|
|
152
|
+
|
|
153
|
+
"""
|
|
154
|
+
total = 0
|
|
155
|
+
|
|
156
|
+
while len(source) > 0 and not self.reader_dropped:
|
|
157
|
+
count = await self.write(source)
|
|
158
|
+
source = source[count:]
|
|
159
|
+
total += count
|
|
160
|
+
|
|
161
|
+
return total
|
|
162
|
+
|
|
163
|
+
def __enter__(self) -> Self:
|
|
164
|
+
return self
|
|
165
|
+
|
|
166
|
+
def __exit__(self,
|
|
167
|
+
exc_type: type[BaseException] | None,
|
|
168
|
+
exc_value: BaseException | None,
|
|
169
|
+
traceback: TracebackType | None) -> bool | None:
|
|
170
|
+
self.finalizer.detach()
|
|
171
|
+
handle = self.handle
|
|
172
|
+
self.handle = None
|
|
173
|
+
if handle is not None:
|
|
174
|
+
componentize_py_runtime.stream_drop_writable(self.type_, handle)
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
T = TypeVar('T')
|
|
178
|
+
|
|
179
|
+
class StreamReader(Generic[T]):
|
|
180
|
+
"""Represents the readable end of a Component Model `stream`.
|
|
181
|
+
|
|
182
|
+
Each object of this type should be closed promptly using context management
|
|
183
|
+
(e.g. a `with` statement) in order to notify the owner of the writable end
|
|
184
|
+
of the `stream` that the readable end has been closed. If the object
|
|
185
|
+
becomes unreachable without being closed, it will be closed via
|
|
186
|
+
finalization.
|
|
187
|
+
|
|
188
|
+
"""
|
|
189
|
+
def __init__(self, type_: int, handle: int):
|
|
190
|
+
"""Constructor for internal use by generated code.
|
|
191
|
+
|
|
192
|
+
Application code should not call this directly. Instead,
|
|
193
|
+
`componentize-py` will generate a constructor function for each unique
|
|
194
|
+
`stream` type used by the target world. Each such function will return
|
|
195
|
+
a (`StreamReader`, `StreamWriter`) pair and use this constructor behind
|
|
196
|
+
the scenes.
|
|
197
|
+
|
|
198
|
+
"""
|
|
199
|
+
self.writer_dropped = False
|
|
200
|
+
self.type_ = type_
|
|
201
|
+
self.handle: int | None = handle
|
|
202
|
+
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_readable, type_, handle)
|
|
203
|
+
|
|
204
|
+
async def read(self, max_count: int) -> list[T]:
|
|
205
|
+
"""Asynchronously read up to `max_count` items sent to this `stream`.
|
|
206
|
+
|
|
207
|
+
The awaitable returned by this function will resolve when either at
|
|
208
|
+
least one item has been delivered to the `stream` or the writable end
|
|
209
|
+
has been closed (in which case the `writer_dropped` field will be set to
|
|
210
|
+
`True`).
|
|
211
|
+
|
|
212
|
+
Only one `read` operation is allowed at a time for a given object. Any
|
|
213
|
+
attempt to start a second read while the first is still in progress will
|
|
214
|
+
raise an `AssertionError`.
|
|
215
|
+
|
|
216
|
+
"""
|
|
217
|
+
if self.writer_dropped:
|
|
218
|
+
return []
|
|
219
|
+
|
|
220
|
+
handle = self.handle
|
|
221
|
+
self.handle = None
|
|
222
|
+
code, values = await self._read(max_count, handle)
|
|
223
|
+
self.handle = handle
|
|
224
|
+
|
|
225
|
+
if code == _ReturnCode.DROPPED:
|
|
226
|
+
self.writer_dropped = True
|
|
227
|
+
|
|
228
|
+
return values
|
|
229
|
+
|
|
230
|
+
async def _read(self, max_count: int, handle: int | None) -> tuple[int, list[T]]:
|
|
231
|
+
if handle is not None:
|
|
232
|
+
return cast(tuple[int, list[T]], await componentize_py_async_support.await_result(
|
|
233
|
+
componentize_py_runtime.stream_read(self.type_, handle, max_count)
|
|
234
|
+
))
|
|
235
|
+
else:
|
|
236
|
+
raise AssertionError
|
|
237
|
+
|
|
238
|
+
def __enter__(self) -> Self:
|
|
239
|
+
return self
|
|
240
|
+
|
|
241
|
+
def __exit__(self,
|
|
242
|
+
exc_type: type[BaseException] | None,
|
|
243
|
+
exc_value: BaseException | None,
|
|
244
|
+
traceback: TracebackType | None) -> bool | None:
|
|
245
|
+
self.finalizer.detach()
|
|
246
|
+
handle = self.handle
|
|
247
|
+
self.handle = None
|
|
248
|
+
if handle is not None:
|
|
249
|
+
componentize_py_runtime.stream_drop_readable(self.type_, handle)
|
|
250
|
+
return None
|
|
251
|
+
|
|
252
|
+
class StreamWriter(Generic[T]):
|
|
253
|
+
"""Represents the writable end of a Component Model `stream`.
|
|
254
|
+
|
|
255
|
+
Each object of this type should be closed promptly using context management
|
|
256
|
+
(e.g. a `with` statement) in order to notify the owner of the readable end
|
|
257
|
+
of the `stream` that the writable end has been closed. If the object
|
|
258
|
+
becomes unreachable without being closed, it will be closed via
|
|
259
|
+
finalization.
|
|
260
|
+
|
|
261
|
+
"""
|
|
262
|
+
def __init__(self, type_: int, handle: int):
|
|
263
|
+
"""Constructor for internal use by generated code.
|
|
264
|
+
|
|
265
|
+
Application code should not call this directly. Instead,
|
|
266
|
+
`componentize-py` will generate a constructor function for each unique
|
|
267
|
+
`stream` type used by the target world. Each such function will return
|
|
268
|
+
a (`StreamReader`, `StreamWriter`) pair and use this constructor behind
|
|
269
|
+
the scenes.
|
|
270
|
+
|
|
271
|
+
"""
|
|
272
|
+
self.reader_dropped = False
|
|
273
|
+
self.type_ = type_
|
|
274
|
+
self.handle: int | None = handle
|
|
275
|
+
self.finalizer = weakref.finalize(self, componentize_py_runtime.stream_drop_writable, type_, handle)
|
|
276
|
+
|
|
277
|
+
async def write(self, source: list[T]) -> int:
|
|
278
|
+
"""Asynchronously write (some of) the specified itmes to the `stream`.
|
|
279
|
+
|
|
280
|
+
The awaitable returned by this function will resolve when either at
|
|
281
|
+
least one item has been delivered to the `stream` or the readable end
|
|
282
|
+
has been closed (in which case the `reader_dropped` field will be set to
|
|
283
|
+
`True`).
|
|
284
|
+
|
|
285
|
+
The return value is the total number of items delivered (which may be
|
|
286
|
+
less than `len(source)`). See also `write_all`, which attempts to write
|
|
287
|
+
the entire buffer before returning.
|
|
288
|
+
|
|
289
|
+
Only one `write` operation is allowed at a time for a given object. Any
|
|
290
|
+
attempt to start a second write while the first is still in progress will
|
|
291
|
+
raise an `AssertionError`.
|
|
292
|
+
|
|
293
|
+
"""
|
|
294
|
+
if self.reader_dropped:
|
|
295
|
+
return 0
|
|
296
|
+
|
|
297
|
+
handle = self.handle
|
|
298
|
+
self.handle = None
|
|
299
|
+
code, count = await self._write(source, handle)
|
|
300
|
+
self.handle = handle
|
|
301
|
+
|
|
302
|
+
if code == _ReturnCode.DROPPED:
|
|
303
|
+
self.reader_dropped = True
|
|
304
|
+
|
|
305
|
+
return count
|
|
306
|
+
|
|
307
|
+
async def _write(self, source: list[T], handle: int | None) -> tuple[int, int]:
|
|
308
|
+
if handle is not None:
|
|
309
|
+
return await componentize_py_async_support.await_result(
|
|
310
|
+
componentize_py_runtime.stream_write(self.type_, handle, source)
|
|
311
|
+
)
|
|
312
|
+
else:
|
|
313
|
+
raise AssertionError
|
|
314
|
+
|
|
315
|
+
async def write_all(self, source: list[T]) -> int:
|
|
316
|
+
"""Asynchronously write the specified items to the `stream`.
|
|
317
|
+
|
|
318
|
+
This calls `write` in a loop until either the entire buffer has been
|
|
319
|
+
delivered or the readable end of the `stream` has been closed. The
|
|
320
|
+
return value is the total number of items delivered (which may be less
|
|
321
|
+
than `len(source)`).
|
|
322
|
+
|
|
323
|
+
"""
|
|
324
|
+
total = 0
|
|
325
|
+
|
|
326
|
+
while len(source) > 0 and not self.reader_dropped:
|
|
327
|
+
count = await self.write(source)
|
|
328
|
+
source = source[count:]
|
|
329
|
+
total += count
|
|
330
|
+
|
|
331
|
+
return total
|
|
332
|
+
|
|
333
|
+
def __enter__(self) -> Self:
|
|
334
|
+
return self
|
|
335
|
+
|
|
336
|
+
def __exit__(self,
|
|
337
|
+
exc_type: type[BaseException] | None,
|
|
338
|
+
exc_value: BaseException | None,
|
|
339
|
+
traceback: TracebackType | None) -> bool | None:
|
|
340
|
+
self.finalizer.detach()
|
|
341
|
+
handle = self.handle
|
|
342
|
+
self.handle = None
|
|
343
|
+
if handle is not None:
|
|
344
|
+
componentize_py_runtime.stream_drop_writable(self.type_, handle)
|
|
345
|
+
return None
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Internal functions used by generated code to interact with the
|
|
2
|
+
`componentize-py` runtime.
|
|
3
|
+
|
|
4
|
+
These are not meant to be called directly by application code.
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
from typing import Any
|
|
8
|
+
from componentize_py_types import Result
|
|
9
|
+
|
|
10
|
+
def call_task_return(index: int, borrows: int, result: Any) -> None: ...
|
|
11
|
+
|
|
12
|
+
def waitable_set_drop(set: int) -> None: ...
|
|
13
|
+
|
|
14
|
+
def context_set(value: Any) -> None: ...
|
|
15
|
+
|
|
16
|
+
def context_get() -> Any: ...
|
|
17
|
+
|
|
18
|
+
def waitable_join(waitable: int, set: int) -> None: ...
|
|
19
|
+
|
|
20
|
+
def subtask_drop(task: int) -> None: ...
|
|
21
|
+
|
|
22
|
+
def waitable_set_new() -> int: ...
|
|
23
|
+
|
|
24
|
+
def promise_get_result(event: int, promise: int) -> Any: ...
|
|
25
|
+
|
|
26
|
+
def future_read(ty: int, future: int) -> Result[Any, tuple[int, int]]: ...
|
|
27
|
+
|
|
28
|
+
def future_write(ty: int, future: int, value: Any) -> Result[tuple[int, int], tuple[int, int]]: ...
|
|
29
|
+
|
|
30
|
+
def future_drop_readable(ty: int, future: int) -> None: ...
|
|
31
|
+
|
|
32
|
+
def future_drop_writable(ty: int, future: int) -> None: ...
|
|
33
|
+
|
|
34
|
+
def stream_read(ty: int, stream: int, max_count: int) -> Result[tuple[int, bytes | list[Any]], tuple[int, int]]: ...
|
|
35
|
+
|
|
36
|
+
def stream_write(ty: int, stream: int, values: bytes | list[Any]) -> Result[tuple[int, int], tuple[int, int]]: ...
|
|
37
|
+
|
|
38
|
+
def stream_drop_readable(ty: int, stream: int) -> None: ...
|
|
39
|
+
|
|
40
|
+
def stream_drop_writable(ty: int, stream: int) -> None: ...
|
componentize_py_types.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import TypeVar, Generic, Union
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
S = TypeVar('S')
|
|
5
|
+
@dataclass
|
|
6
|
+
class Some(Generic[S]):
|
|
7
|
+
"""Represents the "present" (i.e. non-absent) case of an optional value.
|
|
8
|
+
|
|
9
|
+
This is used to disambiguate values of a nested ComponentModel `option` type
|
|
10
|
+
(e.g. `option<option<T>>` or similar). Non-nested `option` values are
|
|
11
|
+
represented using `typing.Optional`, i.e. nullable types.
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
value: S
|
|
15
|
+
|
|
16
|
+
T = TypeVar('T')
|
|
17
|
+
@dataclass
|
|
18
|
+
class Ok(Generic[T]):
|
|
19
|
+
"""Represents the success case of a Component Model `result` value."""
|
|
20
|
+
value: T
|
|
21
|
+
|
|
22
|
+
E = TypeVar('E')
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class Err(Generic[E], Exception):
|
|
25
|
+
"""Represents the failure case of a Component Model `result` value."""
|
|
26
|
+
value: E
|
|
27
|
+
|
|
28
|
+
Result = Union[Ok[T], Err[E]]
|
|
29
|
+
"""Represents a Component Model `result` value, i.e. a variant type representing
|
|
30
|
+
either success payload or failure payload.
|
|
31
|
+
|
|
32
|
+
"""
|