sonolus.py 0.10.2__py3-none-any.whl → 0.10.3__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.

Potentially problematic release.


This version of sonolus.py might be problematic. Click here for more details.

sonolus/build/cli.py CHANGED
@@ -14,7 +14,7 @@ from sonolus.build.dev_server import run_server
14
14
  from sonolus.build.engine import no_gil, package_engine, validate_engine
15
15
  from sonolus.build.level import package_level_data
16
16
  from sonolus.build.project import build_project_to_collection, get_project_schema
17
- from sonolus.script.internal.context import ProjectContextState
17
+ from sonolus.script.internal.context import ProjectContextState, RuntimeChecks
18
18
  from sonolus.script.internal.error import CompilationError
19
19
  from sonolus.script.project import BuildConfig, Project
20
20
 
@@ -128,9 +128,20 @@ def get_config(args: argparse.Namespace) -> BuildConfig:
128
128
  build_watch=build_watch,
129
129
  build_preview=build_preview,
130
130
  build_tutorial=build_tutorial,
131
+ runtime_checks=get_runtime_checks(args),
131
132
  )
132
133
 
133
134
 
135
+ def get_runtime_checks(args: argparse.Namespace) -> RuntimeChecks:
136
+ if hasattr(args, "runtime_checks") and args.runtime_checks:
137
+ return {
138
+ "none": RuntimeChecks.NONE,
139
+ "terminate": RuntimeChecks.TERMINATE,
140
+ "notify": RuntimeChecks.NOTIFY_AND_TERMINATE,
141
+ }[args.runtime_checks]
142
+ return RuntimeChecks.NOTIFY_AND_TERMINATE if args.command == "dev" else RuntimeChecks.NONE
143
+
144
+
134
145
  def main():
135
146
  parser = argparse.ArgumentParser(description="Sonolus project build and development tools")
136
147
  subparsers = parser.add_subparsers(dest="command", required=True)
@@ -147,6 +158,12 @@ def main():
147
158
  "-O2", "--optimize-standard", action="store_true", help="Use standard optimization passes"
148
159
  )
149
160
 
161
+ parser.add_argument(
162
+ "--runtime-checks",
163
+ choices=["none", "terminate", "notify"],
164
+ help="Runtime error checking mode (default: none for build, notify for dev)",
165
+ )
166
+
150
167
  build_components = parser.add_argument_group("build components")
151
168
  build_components.add_argument("--play", action="store_true", help="Build play component")
152
169
  build_components.add_argument("--watch", action="store_true", help="Build watch component")
@@ -117,7 +117,7 @@ class RebuildCommand:
117
117
  print("Rebuilding...")
118
118
  try:
119
119
  start_time = perf_counter()
120
- server_state.project_state = ProjectContextState(dev=True)
120
+ server_state.project_state = ProjectContextState.from_build_config(server_state.config)
121
121
  server_state.project = project_module.project
122
122
  build_collection(
123
123
  server_state.project,
@@ -260,7 +260,7 @@ def run_server(
260
260
  from sonolus.build.cli import build_collection
261
261
 
262
262
  cache = CompileCache()
263
- project_state = ProjectContextState(dev=True)
263
+ project_state = ProjectContextState.from_build_config(config)
264
264
 
265
265
  start_time = perf_counter()
266
266
  build_collection(project, build_dir, config, cache=cache, project_state=project_state)
sonolus/build/engine.py CHANGED
@@ -76,7 +76,7 @@ def package_engine(
76
76
 
77
77
  config = config or BuildConfig()
78
78
  if project_state is None:
79
- project_state = ProjectContextState()
79
+ project_state = ProjectContextState.from_build_config(config)
80
80
  configuration = build_engine_configuration(engine.options, engine.ui)
81
81
  if no_gil():
82
82
  # process_cpu_count is available in Python 3.13+
@@ -209,9 +209,11 @@ def package_engine(
209
209
  def validate_engine(
210
210
  engine: EngineData,
211
211
  config: BuildConfig | None = None,
212
+ project_state: ProjectContextState | None = None,
212
213
  ):
213
214
  config = config or BuildConfig()
214
- project_state = ProjectContextState()
215
+ if project_state is None:
216
+ project_state = ProjectContextState.from_build_config(config)
215
217
 
216
218
  play_mode = engine.play if config.build_play else empty_play_mode()
217
219
  watch_mode = engine.watch if config.build_watch else empty_watch_mode()
@@ -183,7 +183,7 @@ class VarArray[T, Capacity](Record, ArrayLike[T]):
183
183
  assert self._size + len(values) <= len(self._array), "Array is full"
184
184
  i = 0
185
185
  while i < len(values):
186
- self._array.set_unchecked(self._size + i, values[i])
186
+ self._array.set_unchecked(self._size + i, values.get_unchecked(i))
187
187
  i += 1
188
188
  self._size += len(values)
189
189
 
sonolus/script/debug.py CHANGED
@@ -1,13 +1,13 @@
1
1
  from collections.abc import Callable, Sequence
2
2
  from contextvars import ContextVar
3
- from typing import Any, Literal, Never
3
+ from typing import Any, Literal, Never, assert_never
4
4
 
5
5
  from sonolus.backend.mode import Mode
6
6
  from sonolus.backend.ops import Op
7
7
  from sonolus.backend.optimize.flow import cfg_to_mermaid
8
8
  from sonolus.backend.optimize.passes import CompilerPass, OptimizerConfig, run_passes
9
9
  from sonolus.backend.optimize.simplify import RenumberVars
10
- from sonolus.script.internal.context import ModeContextState, ProjectContextState, ctx, set_ctx
10
+ from sonolus.script.internal.context import ModeContextState, ProjectContextState, RuntimeChecks, ctx, set_ctx
11
11
  from sonolus.script.internal.impl import meta_fn, validate_value
12
12
  from sonolus.script.internal.native import native_function
13
13
  from sonolus.script.internal.simulation_context import SimulationContext
@@ -18,12 +18,12 @@ debug_log_callback = ContextVar[Callable[[Num], None]]("debug_log_callback")
18
18
 
19
19
  @meta_fn
20
20
  def error(message: str | None = None) -> Never: # type: ignore
21
- """Raise an error, and if in a dev build, log a message and pause the game.
21
+ """Raise an error, and if runtime checks are set to notify, log a message and pause the game.
22
22
 
23
- This function is used to raise an error during runtime.
24
- When this happens, the game will pause in debug mode. The current callback will also immediately return 0.
23
+ This function is used to raise an error during runtime and terminate the current callback.
25
24
 
26
- In non-dev builds, this function will terminate the current callback silently.
25
+ If runtime checks are set to notify (default in dev), this function will log a message and pause the game
26
+ before terminating.
27
27
 
28
28
  Args:
29
29
  message: The message to log.
@@ -32,9 +32,14 @@ def error(message: str | None = None) -> Never: # type: ignore
32
32
  if not isinstance(message, str):
33
33
  raise ValueError("Expected a string")
34
34
  if ctx():
35
- if ctx().project_state.dev:
36
- debug_log(ctx().map_debug_message(message))
37
- debug_pause()
35
+ match ctx().project_state.runtime_checks:
36
+ case RuntimeChecks.NOTIFY_AND_TERMINATE:
37
+ debug_log(ctx().map_debug_message(message))
38
+ debug_pause()
39
+ case RuntimeChecks.TERMINATE | RuntimeChecks.NONE:
40
+ pass
41
+ case _ as unreachable:
42
+ assert_never(unreachable)
38
43
  terminate()
39
44
  else:
40
45
  raise RuntimeError(message)
@@ -79,9 +84,9 @@ def debug_pause():
79
84
 
80
85
  @meta_fn
81
86
  def notify(message: str):
82
- """Log a code that can be decoded by the dev server and pause the game if in debug mode and in a dev build.
87
+ """Log a code that can be decoded by the dev server and pause the game if runtime checks are set to notify.
83
88
 
84
- Does nothing if not a dev build.
89
+ If runtime checks are not set to notify, this function will do nothing.
85
90
 
86
91
  Args:
87
92
  message: The message to log.
@@ -90,7 +95,7 @@ def notify(message: str):
90
95
  if not isinstance(message, str):
91
96
  raise ValueError("Expected a string")
92
97
  if ctx():
93
- if ctx().project_state.dev:
98
+ if ctx().project_state.runtime_checks == RuntimeChecks.NOTIFY_AND_TERMINATE:
94
99
  debug_log(ctx().map_debug_message(message))
95
100
  debug_pause()
96
101
  else:
@@ -134,7 +139,7 @@ def require(value: int | float | bool, message: str | None = None):
134
139
 
135
140
  @meta_fn
136
141
  def assert_true(value: int | float | bool, message: str | None = None):
137
- if ctx() and not ctx().project_state.dev:
142
+ if ctx() and ctx().project_state.runtime_checks == RuntimeChecks.NONE:
138
143
  return
139
144
  require(value, message)
140
145
 
@@ -4,8 +4,9 @@ from collections.abc import Iterable, Sequence
4
4
  from contextlib import contextmanager
5
5
  from contextvars import ContextVar
6
6
  from dataclasses import dataclass
7
+ from enum import Enum
7
8
  from threading import Lock
8
- from typing import Any, Literal, Self
9
+ from typing import TYPE_CHECKING, Any, Literal, Self
9
10
 
10
11
  from sonolus.backend.blocks import BlockData, PlayBlock
11
12
  from sonolus.backend.ir import IRConst, IRExpr, IRStmt
@@ -15,6 +16,9 @@ from sonolus.backend.place import Block, BlockPlace, TempBlock
15
16
  from sonolus.script.globals import _GlobalInfo, _GlobalPlaceholder
16
17
  from sonolus.script.internal.value import Value
17
18
 
19
+ if TYPE_CHECKING:
20
+ from sonolus.script.project import BuildConfig
21
+
18
22
  _compiler_internal_ = True
19
23
 
20
24
  context_var: ContextVar[Context | None] = ContextVar("context_var", default=None) # type: ignore
@@ -39,25 +43,53 @@ _disabled_debug_config = DebugConfig(
39
43
  debug_var = ContextVar("debug_var", default=_disabled_debug_config)
40
44
 
41
45
 
46
+ class RuntimeChecks(Enum):
47
+ """Runtime error checking modes."""
48
+
49
+ NONE = "none"
50
+ """No runtime checks."""
51
+
52
+ TERMINATE = "terminate"
53
+ """Terminate on errors."""
54
+
55
+ NOTIFY_AND_TERMINATE = "notify_and_terminate"
56
+ """Log, debug pause, and terminate on errors."""
57
+
58
+
42
59
  class ProjectContextState:
43
60
  rom: ReadOnlyMemory
44
61
  const_mappings: dict[Any, int]
45
62
  debug_str_mappings: dict[str, int]
46
63
  lock: Lock
47
- dev: bool
64
+ runtime_checks: RuntimeChecks
48
65
 
49
66
  def __init__(
50
67
  self,
51
68
  rom: ReadOnlyMemory | None = None,
52
69
  const_mappings: dict[Any, int] | None = None,
53
70
  debug_str_mappings: dict[str, int] | None = None,
54
- dev: bool = False,
71
+ runtime_checks: RuntimeChecks = RuntimeChecks.NONE,
55
72
  ):
56
73
  self.rom = ReadOnlyMemory() if rom is None else rom
57
74
  self.const_mappings = {} if const_mappings is None else const_mappings
58
75
  self.debug_str_mappings = {} if debug_str_mappings is None else debug_str_mappings
59
76
  self.lock = Lock()
60
- self.dev = dev
77
+ self.runtime_checks = runtime_checks
78
+
79
+ @classmethod
80
+ def from_build_config(
81
+ cls,
82
+ config: BuildConfig,
83
+ rom: ReadOnlyMemory | None = None,
84
+ const_mappings: dict[Any, int] | None = None,
85
+ debug_str_mappings: dict[str, int] | None = None,
86
+ ) -> Self:
87
+ return cls(
88
+ rom=rom,
89
+ const_mappings=const_mappings,
90
+ debug_str_mappings=debug_str_mappings,
91
+ runtime_checks=config.runtime_checks,
92
+ )
61
93
 
62
94
 
63
95
  class ModeContextState:
sonolus/script/project.py CHANGED
@@ -10,6 +10,7 @@ from sonolus.backend.optimize import optimize
10
10
  from sonolus.backend.optimize.passes import CompilerPass
11
11
  from sonolus.script.archetype import ArchetypeSchema
12
12
  from sonolus.script.engine import Engine
13
+ from sonolus.script.internal.context import RuntimeChecks
13
14
  from sonolus.script.level import ExternalLevelData, Level, LevelData
14
15
 
15
16
 
@@ -66,7 +67,7 @@ class Project:
66
67
  from sonolus.build.cli import run_server
67
68
 
68
69
  if config is None:
69
- config = BuildConfig()
70
+ config = BuildConfig(runtime_checks=RuntimeChecks.NOTIFY_AND_TERMINATE)
70
71
 
71
72
  run_server(
72
73
  Path(build_dir) / "site",
@@ -145,3 +146,6 @@ class BuildConfig:
145
146
 
146
147
  override_resource_level_engines: bool = True
147
148
  """Whether to override any levels included in resources to use the engine of this project."""
149
+
150
+ runtime_checks: RuntimeChecks = RuntimeChecks.NONE
151
+ """Runtime error checking mode."""
sonolus/script/stream.py CHANGED
@@ -6,6 +6,7 @@ from typing import cast, dataclass_transform
6
6
  from sonolus.backend.ir import IRConst, IRExpr, IRInstr, IRPureInstr
7
7
  from sonolus.backend.mode import Mode
8
8
  from sonolus.backend.ops import Op
9
+ from sonolus.script.array_like import check_positive_index
9
10
  from sonolus.script.internal.context import ctx
10
11
  from sonolus.script.internal.descriptor import SonolusDescriptor
11
12
  from sonolus.script.internal.impl import meta_fn
@@ -508,7 +509,7 @@ class StreamGroup[T, Size](Record):
508
509
  def __getitem__(self, index: int) -> Stream[T]:
509
510
  """Get the stream at the given index."""
510
511
  _check_can_read_or_write_stream()
511
- assert index in self
512
+ check_positive_index(index, self.size())
512
513
  # Size 0 elements still need 1 stream to preserve the key.
513
514
  t = self.type_var_value(T)
514
515
  return Stream[t](max(1, sizeof(self.element_type())) * index + self.offset)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sonolus.py
3
- Version: 0.10.2
3
+ Version: 0.10.3
4
4
  Summary: Sonolus engine development in Python
5
5
  Project-URL: Documentation, https://sonolus.py.qwewqa.xyz/
6
6
  Project-URL: Repository, https://github.com/qwewqa/sonolus.py
@@ -26,11 +26,11 @@ sonolus/backend/optimize/passes.py,sha256=YyFKy6qCwcR_Ua2_SXpcBODfvBbm_ygVYcqloO
26
26
  sonolus/backend/optimize/simplify.py,sha256=wvhixe0SfditrGMh0nX0Wt0JR00JqAmz4BKBzMoBAVI,14701
27
27
  sonolus/backend/optimize/ssa.py,sha256=raQO0furQQRPYb8iIBKfNrJlj-_5wqtI4EWNfLZ8QFo,10834
28
28
  sonolus/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- sonolus/build/cli.py,sha256=GQHzXGj55pqz84AnOKa21t74Nrbt7gUKfQe88gXIKtI,9357
29
+ sonolus/build/cli.py,sha256=t6oK0SGU6fkxXVbGu6OuRIHDKD6u4SqXAShdPtatZ-8,10060
30
30
  sonolus/build/collection.py,sha256=6hniAzriPWBKUeGDkXabNXpbdHiHnqiK9shs6U1OExM,12748
31
31
  sonolus/build/compile.py,sha256=KOmncDKmGfgzC_FWB_LTxAl0s9w4wnaDe-luACMlCVs,8397
32
- sonolus/build/dev_server.py,sha256=EOnIgAkFZAKiCwhFqDyKMLkJfYtGdjlacqYWZ2F2mAU,9891
33
- sonolus/build/engine.py,sha256=No_q4O6PRMwxEPHvSlbaBKVe5CXJswWFZdR3xgfIuI8,14672
32
+ sonolus/build/dev_server.py,sha256=tn6xzW2PqsKyc7k9p5hRzoFn4gavIWQwpF0MBcGIPnU,9936
33
+ sonolus/build/engine.py,sha256=jMymxbBXu-ekv71uU8TF2KbFaHs3yGjyJAztd1SoRDs,14808
34
34
  sonolus/build/level.py,sha256=KLqUAtxIuIqrzeFURJA97rdqjA5pcvYSmwNZQhElaMQ,702
35
35
  sonolus/build/node.py,sha256=gnX71RYDUOK_gYMpinQi-bLWO4csqcfiG5gFmhxzSec,1330
36
36
  sonolus/build/project.py,sha256=Uuz82QtTNFdklrVJ_i7EPp8hSjyOxLU1xAeOloa6G00,8579
@@ -39,8 +39,8 @@ sonolus/script/archetype.py,sha256=ck_LR8z0ipVq3T9b735VwvQI2mxVUyjHylr4BFagXT8,4
39
39
  sonolus/script/array.py,sha256=0ZUI0alrwKztpQOpZodZPSPafu5cGwaiffBGQbY19LQ,13316
40
40
  sonolus/script/array_like.py,sha256=E6S4TW2muXgcyVkhUASQVt7JSYUkpvdJPgHz6YiSHNo,14708
41
41
  sonolus/script/bucket.py,sha256=yIod3DgX7Hv7RLe-4Cn81FcydvbkbdMt26FzpRj7oUI,7794
42
- sonolus/script/containers.py,sha256=qKIyTs5Q_UpQggR6s0AfgWQAvPv-IM2DW9s951koKSc,19303
43
- sonolus/script/debug.py,sha256=YOq06q5ahWI-uEG5naonOBWF62Qn_Af7JSV_Ra8Zr6E,7415
42
+ sonolus/script/containers.py,sha256=Zomn9H0QJjWNAcbe17fj1c4zbM4D0s3vlIY1R0zf8rg,19317
43
+ sonolus/script/debug.py,sha256=-Xbt1wYCwCgQOyRFdG73A8LxJLIw9qLs1N6B5FLbZYQ,7790
44
44
  sonolus/script/easing.py,sha256=2FUJI_nfp990P_armCcRqHm2329O985glJAhSC6tnxs,11379
45
45
  sonolus/script/effect.py,sha256=aOxhBmX6I8vUS-bE53YFNBEN3wwdmpraqZjLeCqbgIY,7920
46
46
  sonolus/script/engine.py,sha256=etI9dJsQ7V9YZICVNZg54WqpLijPxG8eTPHiV-_EiG8,10687
@@ -56,12 +56,12 @@ sonolus/script/options.py,sha256=05y_4j2kr8fzct5FLqmSp5ZAjnq6-slmNgtsh4fVEpg,945
56
56
  sonolus/script/particle.py,sha256=BuBM7fvLAj79upLf9yI4FyZhVUK7-H2dFj0D7UiYS7I,10458
57
57
  sonolus/script/pointer.py,sha256=FoOfyD93r0G5d_2BaKfeOT9SqkOP3hq6sqtOs_Rb0c8,1511
58
58
  sonolus/script/printing.py,sha256=mNYu9QWiacBBGZrnePZQMVwbbguoelUps9GiOK_aVRU,2096
59
- sonolus/script/project.py,sha256=4svmMWYihF7olmYSMS5uoSjlnzbd7Ip2zTRY86oL1L8,4629
59
+ sonolus/script/project.py,sha256=YouKKm6Z9PpwbO9aSA2syZqFv_j1DShVGlENUT565Js,4831
60
60
  sonolus/script/quad.py,sha256=8lZ_5-eWeqePldNGBkNZTuOgS_IRb41URgGwSW4h2T0,14445
61
61
  sonolus/script/record.py,sha256=BrQ8k-O4WX9FT_EfoRmNnKC1BZM9gWydZ4R4swh3chc,13051
62
62
  sonolus/script/runtime.py,sha256=TjxcfIIPRH6oxlEjWfLHDj1oo7fPfwTBdwETfnhN7h4,33331
63
63
  sonolus/script/sprite.py,sha256=d_wqUn7oMbkLZMdvnyDZVBykycTtiwegcarWXMcZMUI,18408
64
- sonolus/script/stream.py,sha256=Fu02SNjH8j1FQ9_7ncacR9uRIhoWtAZR-sTi8qBT7rA,24707
64
+ sonolus/script/stream.py,sha256=mamVG7umEsb51D9Kh6xifhDB7QSDBQHU7xWhJIsQvYY,24786
65
65
  sonolus/script/text.py,sha256=wxujIgKYcCfl2AD2_Im8g3vh0lDEHYwTSRZg9wsBPEU,13402
66
66
  sonolus/script/timing.py,sha256=DklMvuxcFg3MzXsecUo6Yhdk7pScOJ7STwXvAiTvLKM,3067
67
67
  sonolus/script/transform.py,sha256=4aS7-NNzX0v9KMXZ4gIGOaU1Cd-ok7DO_OvIBca0mGU,21418
@@ -72,7 +72,7 @@ sonolus/script/internal/__init__.py,sha256=T6rzLoiOUaiSQtaHMZ88SNO-ijSjSSv33TKtU
72
72
  sonolus/script/internal/builtin_impls.py,sha256=tpNbaH6fLICd8TYj9Hf_wrPSWk3RkhmSPVN9nqOuqj4,13372
73
73
  sonolus/script/internal/callbacks.py,sha256=vWzJG8uiJoEtsNnbeZPqOHogCwoLpz2D1MnHY2wVV8s,2801
74
74
  sonolus/script/internal/constant.py,sha256=3ycbGkDJVUwcrCZ96vLjAoAARgsvaqDM8rJ_YCrLrvo,4289
75
- sonolus/script/internal/context.py,sha256=C0VMHBRppsnwPDVPc03Lpz7tO9djQMB5ELdtpFPMdsk,18779
75
+ sonolus/script/internal/context.py,sha256=56pPjiPy8ZaxY3t5iEufsOMEj6BSy31G-5SoYqS6tPo,19694
76
76
  sonolus/script/internal/descriptor.py,sha256=XRFey-EjiAm_--KsNl-8N0Mi_iyQwlPh68gDp0pKf3E,392
77
77
  sonolus/script/internal/dict_impl.py,sha256=alu_wKGSk1kZajNf64qbe7t71shEzD4N5xNIATH8Swo,1885
78
78
  sonolus/script/internal/error.py,sha256=ZNnsvQVQAnFKzcvsm6-sste2lo-tP5pPI8sD7XlAZWc,490
@@ -87,8 +87,8 @@ sonolus/script/internal/simulation_context.py,sha256=LGxLTvxbqBIhoe1R-SfwGajNIDw
87
87
  sonolus/script/internal/transient.py,sha256=y2AWABqF1aoaP6H4_2u4MMpNioC4OsZQCtPyNI0txqo,1634
88
88
  sonolus/script/internal/tuple_impl.py,sha256=DPNdmmRmupU8Ah4_XKq6-PdT336l4nt15_uCJKQGkkk,3587
89
89
  sonolus/script/internal/value.py,sha256=OngrCdmY_h6mV2Zgwqhuo4eYFad0kTk6263UAxctZcY,6963
90
- sonolus_py-0.10.2.dist-info/METADATA,sha256=07hKS146L3Ck4bScU9kbuWDHtIrExXvCIlygmvfxCbE,554
91
- sonolus_py-0.10.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- sonolus_py-0.10.2.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
93
- sonolus_py-0.10.2.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
94
- sonolus_py-0.10.2.dist-info/RECORD,,
90
+ sonolus_py-0.10.3.dist-info/METADATA,sha256=EWdFrM6pQ7bZHXSFjPqFHb22IJCR8wwuSoX46zS6MRU,554
91
+ sonolus_py-0.10.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ sonolus_py-0.10.3.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
93
+ sonolus_py-0.10.3.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
94
+ sonolus_py-0.10.3.dist-info/RECORD,,