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

@@ -1126,8 +1126,6 @@ class Visitor(ast.NodeVisitor):
1126
1126
  if first_param_name is not None:
1127
1127
  first_param_value = self.get_name(first_param_name)
1128
1128
  args = (validate_value(class_value), validate_value(first_param_value))
1129
- else:
1130
- args = (validate_value(class_value),)
1131
1129
  return self.handle_call(node, fn, *args, **kwargs)
1132
1130
 
1133
1131
  def visit_FormattedValue(self, node):
sonolus/build/compile.py CHANGED
@@ -74,10 +74,12 @@ def compile_mode(
74
74
  return cb_info.name, node_index
75
75
 
76
76
  all_futures = {}
77
- archetype_entries = []
77
+ base_archetype_entries = {}
78
78
 
79
79
  if archetypes is not None:
80
- for archetype in archetypes:
80
+ base_archetypes = {getattr(a, "_derived_base_", a) for a in archetypes}
81
+
82
+ for archetype in base_archetypes:
81
83
  archetype._init_fields()
82
84
 
83
85
  archetype_data = {
@@ -109,7 +111,7 @@ def compile_mode(
109
111
  cb_name, result_data = process_callback(cb_info, cb, archetype)
110
112
  archetype_data[cb_name] = result_data
111
113
 
112
- archetype_entries.append(archetype_data)
114
+ base_archetype_entries[archetype] = archetype_data
113
115
 
114
116
  if global_callbacks is not None and thread_pool is not None:
115
117
  for cb_info, cb in global_callbacks:
@@ -129,7 +131,10 @@ def compile_mode(
129
131
  results[cb_name] = node_index
130
132
 
131
133
  if archetypes is not None:
132
- results["archetypes"] = archetype_entries
134
+ results["archetypes"] = [
135
+ {**base_archetype_entries[getattr(a, "_derived_base_", a)], "name": a.name, "hasInput": a.is_scored}
136
+ for a in archetypes
137
+ ]
133
138
 
134
139
  results["nodes"] = nodes.get()
135
140
  return results
@@ -183,6 +183,68 @@ class _ArchetypeField(SonolusDescriptor):
183
183
  target._copy_from_(value)
184
184
 
185
185
 
186
+ class _NameDescriptor(SonolusDescriptor):
187
+ def __init__(self, name: str):
188
+ self.name = name
189
+
190
+ def __get__(self, instance, owner):
191
+ if instance is None:
192
+ return self.name
193
+ elif ctx():
194
+ raise RuntimeError("Cannot access archetype name in from self in a callback, use ArchetypeClass.name")
195
+ else:
196
+ return self.name
197
+
198
+ def __set__(self, instance, value):
199
+ raise AttributeError("Archetype name is read-only and cannot be set")
200
+
201
+
202
+ class _IsScoredDescriptor(SonolusDescriptor):
203
+ def __init__(self, value: bool):
204
+ self.value = value
205
+
206
+ def __get__(self, instance, owner):
207
+ if instance is None:
208
+ return self.value
209
+ elif ctx():
210
+ raise RuntimeError("Cannot access is_scored from self in a callback, use ArchetypeClass.is_scored")
211
+ else:
212
+ return self.value
213
+
214
+ def __set__(self, instance, value):
215
+ raise AttributeError("is_scored is read-only and cannot be set")
216
+
217
+
218
+ class _IdDescriptor(SonolusDescriptor):
219
+ def __get__(self, instance, owner):
220
+ if not ctx():
221
+ raise RuntimeError("Archetype id is only available during compilation")
222
+ if instance is None:
223
+ result = ctx().global_state.archetypes.get(owner)
224
+ if result is None:
225
+ raise RuntimeError("Archetype is not registered")
226
+ return result
227
+ else:
228
+ return instance._info.archetype_id
229
+
230
+ def __set__(self, instance, value):
231
+ raise AttributeError("Archetype id is read-only and cannot be set")
232
+
233
+
234
+ class _KeyDescriptor(SonolusDescriptor):
235
+ def __init__(self, value: int | float):
236
+ self.value = value
237
+
238
+ def __get__(self, instance, owner):
239
+ if instance is not None and ctx():
240
+ return ctx().global_state.keys[instance.id]
241
+ else:
242
+ return self.value
243
+
244
+ def __set__(self, instance, value):
245
+ raise AttributeError("Archetype key is read-only and cannot be set")
246
+
247
+
186
248
  def imported(*, name: str | None = None) -> Any:
187
249
  """Declare a field as imported.
188
250
 
@@ -387,6 +449,28 @@ class _BaseArchetype:
387
449
 
388
450
  _data_: _ArchetypeData
389
451
 
452
+ id: int = 0
453
+ """The id of the archetype or entity.
454
+
455
+ If accessed on an entity, always returns the runtime archetype id of the entity, even if it doesn't match the type
456
+ that was used to access it.
457
+
458
+ E.g. if an entity of archetype `A` is accessed via [`EntityRef[B]`][sonolus.script.archetype.EntityRef], the id will
459
+ still be the id of `A`.
460
+ """
461
+
462
+ key: int | float = -1
463
+ """An optional key for the archetype.
464
+
465
+ May be useful to identify an archetype in an inheritance hierarchy without needing to check id.
466
+
467
+ If accessed on an entity, always returns the runtime key of the entity, even if it doesn't match the type
468
+ that was used to access it.
469
+
470
+ E.g. if an entity of archetype `A` is accessed via [`EntityRef[B]`][sonolus.script.archetype.EntityRef], the key
471
+ will still be the key of `A`.
472
+ """
473
+
390
474
  name: ClassVar[str | None] = None
391
475
  """The name of the archetype.
392
476
 
@@ -433,17 +517,7 @@ class _BaseArchetype:
433
517
  def is_at(cls, index: int) -> bool:
434
518
  if not ctx():
435
519
  raise RuntimeError("is_at is only available during compilation")
436
- return entity_info_at(index).archetype_id == cls.id()
437
-
438
- @classmethod
439
- @meta_fn
440
- def id(cls) -> int:
441
- if not ctx():
442
- raise RuntimeError("Archetype id is only available during compilation")
443
- result = ctx().global_state.archetypes.get(cls)
444
- if result is None:
445
- raise RuntimeError("Archetype is not registered")
446
- return result
520
+ return entity_info_at(index).archetype_id == cls.id
447
521
 
448
522
  @classmethod
449
523
  @meta_fn
@@ -465,7 +539,7 @@ class _BaseArchetype:
465
539
  cls._init_fields()
466
540
  if not ctx():
467
541
  raise RuntimeError("Spawn is only allowed within a callback")
468
- archetype_id = cls.id()
542
+ archetype_id = cls.id
469
543
  bound = cls._spawn_signature_.bind_partial(**kwargs)
470
544
  bound.apply_defaults()
471
545
  data = []
@@ -497,7 +571,7 @@ class _BaseArchetype:
497
571
  return entries
498
572
 
499
573
  def __init_subclass__(cls, **kwargs):
500
- if cls.__module__ == _BaseArchetype.__module__:
574
+ if cls.__module__ == _BaseArchetype.__module__ and not getattr(cls, "_is_derived_", False):
501
575
  if cls._supported_callbacks_ is None:
502
576
  raise TypeError("Cannot directly subclass Archetype, use the Archetype subclass for your mode")
503
577
  cls._default_callbacks_ = {getattr(cls, cb_info.py_name) for cb_info in cls._supported_callbacks_.values()}
@@ -511,6 +585,11 @@ class _BaseArchetype:
511
585
  continue
512
586
  cls._callbacks_.append(cb)
513
587
  cls._field_init_done = False
588
+ cls.id = _IdDescriptor()
589
+ cls._key_ = cls.key
590
+ cls.key = _KeyDescriptor(cls.key)
591
+ cls.name = _NameDescriptor(cls.name)
592
+ cls.is_scored = _IsScoredDescriptor(cls.is_scored)
514
593
 
515
594
  @classmethod
516
595
  def _init_fields(cls):
@@ -521,7 +600,19 @@ class _BaseArchetype:
521
600
  if hasattr(mro_entry, "_field_init_done"):
522
601
  mro_entry._init_fields()
523
602
  field_specifiers = get_field_specifiers(
524
- cls, skip={"name", "is_scored", "_callbacks_", "_field_init_done"}
603
+ cls,
604
+ skip={
605
+ "id",
606
+ "key",
607
+ "name",
608
+ "is_scored",
609
+ "_key_",
610
+ "_derived_base_",
611
+ "_is_derived_",
612
+ "_default_callbacks_",
613
+ "_callbacks_",
614
+ "_field_init_done",
615
+ },
525
616
  ).items()
526
617
  if not hasattr(cls, "_imported_fields_"):
527
618
  cls._imported_fields_ = {}
@@ -656,6 +747,41 @@ class _BaseArchetype:
656
747
  def _post_init_fields(cls):
657
748
  pass
658
749
 
750
+ @classmethod
751
+ def derive[T](cls: type[T], name: str, is_scored: bool, key: int | float | None = None) -> type[T]:
752
+ """Derive a new archetype class from this archetype.
753
+
754
+ Roughly equivalent to returning:
755
+ ```python
756
+ class Derived(cls):
757
+ name = <name>
758
+ is_scored = <is_scored>
759
+ key = <key> # Only set if key is not None
760
+ ```
761
+
762
+ This is used to create a new archetype with the same fields and callbacks, but with a different name and
763
+ whether it is scored. Compared to manually subclassing, this method also enables faster compilation when
764
+ the same base archetype has multiple derived archetypes by compiling callbacks only once for the base archetype.
765
+
766
+ Args:
767
+ name: The name of the new archetype.
768
+ is_scored: Whether the new archetype is scored.
769
+ key: A key that can be accessed via the `key` property of the new archetype.
770
+
771
+ Returns:
772
+ A new archetype class with the same fields and callbacks as this archetype, but with the given name and
773
+ whether it is scored.
774
+ """
775
+ if getattr(cls, "_is_derived_", False):
776
+ raise RuntimeError("Cannot derive from a derived archetype")
777
+ cls_dict = {"name": name, "is_scored": is_scored, "_is_derived_": True, "_derived_base_": cls}
778
+ if key is not None:
779
+ if not isinstance(key, (int, float)):
780
+ raise TypeError(f"Key must be an int or float, got {type(key)}")
781
+ cls_dict["key"] = key
782
+ new_cls = type(name, (cls,), cls_dict)
783
+ return new_cls
784
+
659
785
 
660
786
  class PlayArchetype(_BaseArchetype):
661
787
  """Base class for play mode archetypes.
@@ -807,7 +933,7 @@ class PlayArchetype(_BaseArchetype):
807
933
  raise RuntimeError("Calling life is only allowed within a callback")
808
934
  match self._data_:
809
935
  case _ArchetypeSelfData() | _ArchetypeReferenceData():
810
- return _deref(ctx().blocks.ArchetypeLife, self.id() * ArchetypeLife._size_(), ArchetypeLife)
936
+ return _deref(ctx().blocks.ArchetypeLife, self.id * ArchetypeLife._size_(), ArchetypeLife)
811
937
  case _:
812
938
  raise RuntimeError("Life is not available in level data")
813
939
 
@@ -826,6 +952,26 @@ class PlayArchetype(_BaseArchetype):
826
952
  case _:
827
953
  raise RuntimeError("Result is only accessible from the entity itself")
828
954
 
955
+ @classmethod
956
+ def update_life(
957
+ cls,
958
+ perfect_increment: int | None = None,
959
+ great_increment: int | None = None,
960
+ good_increment: int | None = None,
961
+ miss_increment: int | None = None,
962
+ ):
963
+ """Update the life of this archetype.
964
+
965
+ Values default to 0.
966
+
967
+ Args:
968
+ perfect_increment: The increment for perfect life.
969
+ great_increment: The increment for great life.
970
+ good_increment: The increment for good life.
971
+ miss_increment: The increment for miss life.
972
+ """
973
+ archetype_life_of(cls).update(perfect_increment, great_increment, good_increment, miss_increment)
974
+
829
975
 
830
976
  class WatchArchetype(_BaseArchetype):
831
977
  """Base class for watch mode archetypes.
@@ -920,7 +1066,7 @@ class WatchArchetype(_BaseArchetype):
920
1066
  raise RuntimeError("Calling life is only allowed within a callback")
921
1067
  match self._data_:
922
1068
  case _ArchetypeSelfData() | _ArchetypeReferenceData():
923
- return _deref(ctx().blocks.ArchetypeLife, self.id() * ArchetypeLife._size_(), ArchetypeLife)
1069
+ return _deref(ctx().blocks.ArchetypeLife, self.id * ArchetypeLife._size_(), ArchetypeLife)
924
1070
  case _:
925
1071
  raise RuntimeError("Life is not available in level data")
926
1072
 
@@ -944,6 +1090,26 @@ class WatchArchetype(_BaseArchetype):
944
1090
  if cls._exported_fields_:
945
1091
  raise RuntimeError("Watch archetypes cannot have exported fields")
946
1092
 
1093
+ @classmethod
1094
+ def update_life(
1095
+ cls,
1096
+ perfect_increment: int | None = None,
1097
+ great_increment: int | None = None,
1098
+ good_increment: int | None = None,
1099
+ miss_increment: int | None = None,
1100
+ ):
1101
+ """Update the life of this archetype.
1102
+
1103
+ Values default to 0.
1104
+
1105
+ Args:
1106
+ perfect_increment: The increment for perfect life.
1107
+ great_increment: The increment for great life.
1108
+ good_increment: The increment for good life.
1109
+ miss_increment: The increment for miss life.
1110
+ """
1111
+ archetype_life_of(cls).update(perfect_increment, great_increment, good_increment, miss_increment)
1112
+
947
1113
 
948
1114
  class PreviewArchetype(_BaseArchetype):
949
1115
  """Base class for preview mode archetypes.
@@ -1032,7 +1198,7 @@ def archetype_life_of(archetype: type[_BaseArchetype] | _BaseArchetype) -> Arche
1032
1198
  raise RuntimeError("Calling archetype_life_of is only allowed within a callback")
1033
1199
  match ctx().global_state.mode:
1034
1200
  case Mode.PLAY | Mode.WATCH:
1035
- return _deref(ctx().blocks.ArchetypeLife, archetype.id() * ArchetypeLife._size_(), ArchetypeLife)
1201
+ return _deref(ctx().blocks.ArchetypeLife, archetype.id * ArchetypeLife._size_(), ArchetypeLife)
1036
1202
  case _:
1037
1203
  raise RuntimeError(f"Archetype life is not available in mode '{ctx().global_state.mode}'")
1038
1204
 
@@ -1184,3 +1350,7 @@ class StandardArchetypeName(StrEnum):
1184
1350
 
1185
1351
  TIMESCALE_CHANGE = "#TIMESCALE_CHANGE"
1186
1352
  """Timescale change marker"""
1353
+
1354
+
1355
+ type AnyArchetype = PlayArchetype | WatchArchetype | PreviewArchetype
1356
+ """Union of all archetype types."""
@@ -1,11 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
3
+ 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
7
  from threading import Lock
8
- from typing import Any, Self
8
+ from typing import Any, Literal, Self
9
9
 
10
10
  from sonolus.backend.blocks import BlockData, PlayBlock
11
11
  from sonolus.backend.ir import IRConst, IRExpr, IRStmt
@@ -41,6 +41,7 @@ debug_var = ContextVar("debug_var", default=_disabled_debug_config)
41
41
 
42
42
  class GlobalContextState:
43
43
  archetypes: dict[type, int]
44
+ keys: Sequence[int] | None
44
45
  rom: ReadOnlyMemory
45
46
  const_mappings: dict[Any, int]
46
47
  environment_mappings: dict[_GlobalInfo, int]
@@ -49,7 +50,14 @@ class GlobalContextState:
49
50
  lock: Lock
50
51
 
51
52
  def __init__(self, mode: Mode, archetypes: dict[type, int] | None = None, rom: ReadOnlyMemory | None = None):
53
+ from sonolus.script.array import Array
54
+
52
55
  self.archetypes = archetypes or {}
56
+ self.keys = (
57
+ Array(*((getattr(a, "_key_", -1)) for a in sorted(self.archetypes, key=lambda a: archetypes[a])))
58
+ if archetypes
59
+ else Array[int, Literal[0]]()
60
+ )
53
61
  self.rom = ReadOnlyMemory() if rom is None else rom
54
62
  self.const_mappings = {}
55
63
  self.environment_mappings = {}
@@ -28,4 +28,7 @@ def get_field_specifiers(
28
28
  and not isinstance(value, property)
29
29
  ):
30
30
  raise ValueError(f"Missing annotation for {cls.__name__}.{key}")
31
+ for skipped_key in skip:
32
+ if skipped_key in results:
33
+ del results[skipped_key]
31
34
  return results
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sonolus.py
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: Sonolus engine development in Python
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -11,7 +11,7 @@ sonolus/backend/node.py,sha256=eEzPP14jzWJp2xrZCAaPlNtokxdoqg0bSM7xQiwx1j8,1254
11
11
  sonolus/backend/ops.py,sha256=5weB_vIxbkwCSJuzYZyKUk7vVXsSIEDJYRlvE-2ke8A,10572
12
12
  sonolus/backend/place.py,sha256=7qwV732hZ4WP-9GNN8FQSEKssPJZELip1wLXTWfop7Y,4717
13
13
  sonolus/backend/utils.py,sha256=DDgYUVHh4h_eSY65v2KcxUaLSBYGYS6oHar5gTdV7QU,2356
14
- sonolus/backend/visitor.py,sha256=UAdp3Lg9kFVcFmBfn6rqpE9xM_CWBWlsB2o6OJiFqxQ,63193
14
+ sonolus/backend/visitor.py,sha256=Dz_3w3gvmJraNC2fMMlkYthEmT0AkZfHGFsrracELuo,63121
15
15
  sonolus/backend/optimize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  sonolus/backend/optimize/allocate.py,sha256=CuumoMphkpQlGRNeKLHT4FBGE0XVj5pwhfNdrqiLFSs,7535
17
17
  sonolus/backend/optimize/constant_evaluation.py,sha256=U--9moGsXFzrgweWWwHIiEuuMzwetd1IOjjtrCscoNM,21450
@@ -28,13 +28,13 @@ sonolus/backend/optimize/ssa.py,sha256=raQO0furQQRPYb8iIBKfNrJlj-_5wqtI4EWNfLZ8Q
28
28
  sonolus/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  sonolus/build/cli.py,sha256=-_lTN8zT7nQB2lySM8itAEPVutcEQI-TJ13BcPIfGb4,10113
30
30
  sonolus/build/collection.py,sha256=kOVnpQC_KHAsyTM4nAplSh6QE16CgO-H6PP1GItWm78,12187
31
- sonolus/build/compile.py,sha256=B7w6Uqa4HlZPNklNhhjJoq9ncXMVXLCYabGLxtxWGV4,6521
31
+ sonolus/build/compile.py,sha256=Yex-ZbSZmv9ujyAOVaMcfq-0NnZzFIqtmNYYaplF4Uc,6761
32
32
  sonolus/build/engine.py,sha256=zUl0KfRygqNhIM8BABNJkKG-0zXFwcYwck-5hJy59yk,13338
33
33
  sonolus/build/level.py,sha256=yXsQtnabkJK0vuVmZ_Wr1jx37jFLgInCS7lTlXjkv9Q,706
34
34
  sonolus/build/node.py,sha256=gnX71RYDUOK_gYMpinQi-bLWO4csqcfiG5gFmhxzSec,1330
35
35
  sonolus/build/project.py,sha256=mv2OuzgIDG-E9G4SIRiUDL5XiPCd1i81wVl1p7itFHA,6329
36
36
  sonolus/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- sonolus/script/archetype.py,sha256=HJeKJ_vj7xUYaCAmNdGYO45rhFMSLMwOLyvpKjulfVY,42418
37
+ sonolus/script/archetype.py,sha256=-i7TQMI0_ztNTwd1bXu39q3wSaa70kRlPoNZFUHNbHY,48534
38
38
  sonolus/script/array.py,sha256=9uOUHZIDMyMT9q3APcXJWXWt97yG-AZoRlxwrvSY6SU,12367
39
39
  sonolus/script/array_like.py,sha256=jFOfXkniTLrIK4ER6HO_tUyKn_TvwjyM4B3SDd9cUS8,9678
40
40
  sonolus/script/bucket.py,sha256=VxsSgHidYhY_Y5UXpBZY_tzjQff0TRgNJVj4Al8LVec,7654
@@ -71,13 +71,13 @@ sonolus/script/internal/__init__.py,sha256=T6rzLoiOUaiSQtaHMZ88SNO-ijSjSSv33TKtU
71
71
  sonolus/script/internal/builtin_impls.py,sha256=POmWRyTQa-9mpQ_jATDYlFWo_n0a65vXAgqitkKYzGY,12870
72
72
  sonolus/script/internal/callbacks.py,sha256=vWzJG8uiJoEtsNnbeZPqOHogCwoLpz2D1MnHY2wVV8s,2801
73
73
  sonolus/script/internal/constant.py,sha256=3ycbGkDJVUwcrCZ96vLjAoAARgsvaqDM8rJ_YCrLrvo,4289
74
- sonolus/script/internal/context.py,sha256=qn8xp5BB1C3IaUS8jsSUfkMUJgPzeaIV7K4FY9mHHQo,16903
74
+ sonolus/script/internal/context.py,sha256=JtKyjFlt7t2YwR1qFUGGjzYrE8v0yfsP-7XA196gtaQ,17211
75
75
  sonolus/script/internal/descriptor.py,sha256=XRFey-EjiAm_--KsNl-8N0Mi_iyQwlPh68gDp0pKf3E,392
76
76
  sonolus/script/internal/dict_impl.py,sha256=alu_wKGSk1kZajNf64qbe7t71shEzD4N5xNIATH8Swo,1885
77
77
  sonolus/script/internal/error.py,sha256=ZNnsvQVQAnFKzcvsm6-sste2lo-tP5pPI8sD7XlAZWc,490
78
78
  sonolus/script/internal/generic.py,sha256=F0-cCiRNGTaUJvYlpmkiOsU3Xge_XjoBpBwBhH_qS_s,7577
79
79
  sonolus/script/internal/impl.py,sha256=alcFJs1yDx9ixEOxg-r_1IvWG2arMSUKSc-Eg9nAHOw,3255
80
- sonolus/script/internal/introspection.py,sha256=MfdXo3GFHNZT2-vAKuvsE54V-5TOfbg4vU9dBI6sLqo,1032
80
+ sonolus/script/internal/introspection.py,sha256=guL9_NR2D3OJAnNpeFdyYkO_vVXk-3KQr2-y4YielM0,1133
81
81
  sonolus/script/internal/math_impls.py,sha256=nHSLgA7Tcx7jY1p07mYBCeSRmVx713bwdNayCIcaXSE,2652
82
82
  sonolus/script/internal/native.py,sha256=DQxmzxgLG_UsLpXhIEtBdO7eIeDFprU78UBDC4OZzw0,1597
83
83
  sonolus/script/internal/random.py,sha256=6Ku5edRcDUh7rtqEEYCJz0BQavw69RALsVHS25z50pI,1695
@@ -86,8 +86,8 @@ sonolus/script/internal/simulation_context.py,sha256=LGxLTvxbqBIhoe1R-SfwGajNIDw
86
86
  sonolus/script/internal/transient.py,sha256=y2AWABqF1aoaP6H4_2u4MMpNioC4OsZQCtPyNI0txqo,1634
87
87
  sonolus/script/internal/tuple_impl.py,sha256=DPNdmmRmupU8Ah4_XKq6-PdT336l4nt15_uCJKQGkkk,3587
88
88
  sonolus/script/internal/value.py,sha256=OngrCdmY_h6mV2Zgwqhuo4eYFad0kTk6263UAxctZcY,6963
89
- sonolus_py-0.5.0.dist-info/METADATA,sha256=UCeZWEVfiGWGob4XES8cE9MgkmE44kD_6PJ-dVEQypI,302
90
- sonolus_py-0.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
- sonolus_py-0.5.0.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
92
- sonolus_py-0.5.0.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
93
- sonolus_py-0.5.0.dist-info/RECORD,,
89
+ sonolus_py-0.5.2.dist-info/METADATA,sha256=95TnAW9JgpYR6UNXhEm3rZbHCqKWkUY6cGr93eYo4Wo,302
90
+ sonolus_py-0.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
+ sonolus_py-0.5.2.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
92
+ sonolus_py-0.5.2.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
93
+ sonolus_py-0.5.2.dist-info/RECORD,,