hmr 0.5.3__py3-none-any.whl → 0.6.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hmr
3
- Version: 0.5.3
3
+ Version: 0.6.0
4
4
  Summary: Hot Module Reload for Python
5
5
  Project-URL: repository, https://github.com/promplate/pyth-on-line/tree/reactivity
6
6
  Requires-Python: >=3.12
@@ -0,0 +1,15 @@
1
+ hmr-0.6.0.dist-info/METADATA,sha256=AQEgb94qk_NRTRAap3w-eie4GVIebx3ZPzUPWrrN_98,1999
2
+ hmr-0.6.0.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
+ hmr-0.6.0.dist-info/entry_points.txt,sha256=g_T0uJ43WgsdG14kkkdaBQuIL0HO-m1qvtjXMP6d060,59
4
+ reactivity/__init__.py,sha256=pX-RUzkezCC1x4eOWGxNhXbwrbvBLP_3pQuZr9eZz1Y,300
5
+ reactivity/context.py,sha256=Iuq1uXYJjQeizOucocu56ObGy5O_sb7Q-mXeKJzAwMA,1239
6
+ reactivity/functional.py,sha256=jJLEq88w5ag2cXuD1T118uEjnEg37_mqvWmFkb47KVY,1300
7
+ reactivity/helpers.py,sha256=MoIU6UmvPDC31HW5mQn2kFKJZNjrzioLXXEyYQMHUuw,5820
8
+ reactivity/hmr/__init__.py,sha256=S5ZIHqCRpevdzWuhS0aCua_S8F0LkK0YNg6IgeTScFQ,177
9
+ reactivity/hmr/__main__.py,sha256=uIcyjR5gMFIXH_3hS0B3SD00RirVf7GIct-uItx675o,64
10
+ reactivity/hmr/api.py,sha256=ypS_LyzMH1JbN5cSwamAJ0HEcHMOY7BOIINuJmWJwo8,2283
11
+ reactivity/hmr/core.py,sha256=OMgjdnvv6QWUmDmJxInuT93RwWuwNSicHTdgF0k4vL4,11835
12
+ reactivity/hmr/hooks.py,sha256=jIFpe4CNxfaS9RcR4OIodx_sOZlnJ_IA1T1RtHPXhwU,945
13
+ reactivity/hmr/utils.py,sha256=h9m7iRXlvsLTrHoXV9gEVbhz3XsPK4KgnStYoCAWE5I,1616
14
+ reactivity/primitives.py,sha256=z69PqQxizN2sbursmpKW5SlWshlZZzdLgFH9u8E5eZc,6857
15
+ hmr-0.6.0.dist-info/RECORD,,
reactivity/context.py ADDED
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable
4
+ from contextlib import contextmanager
5
+ from functools import partial
6
+ from typing import TYPE_CHECKING, NamedTuple
7
+
8
+ if TYPE_CHECKING:
9
+ from .primitives import BaseComputation, Batch
10
+
11
+
12
+ class Context(NamedTuple):
13
+ current_computations: list[BaseComputation]
14
+ batches: list[Batch]
15
+
16
+ def schedule_callbacks(self, callbacks: Iterable[BaseComputation]):
17
+ self.batches[-1].callbacks.update(callbacks)
18
+
19
+ @contextmanager
20
+ def enter(self, computation: BaseComputation):
21
+ computation.dispose()
22
+ self.current_computations.append(computation)
23
+ try:
24
+ yield
25
+ finally:
26
+ last = self.current_computations.pop()
27
+ assert last is computation # sanity check
28
+
29
+ @property
30
+ def batch(self):
31
+ from .primitives import Batch
32
+
33
+ return partial(Batch, context=self)
34
+
35
+ @property
36
+ def signal(self):
37
+ from .primitives import Signal
38
+
39
+ return partial(Signal, context=self)
40
+
41
+ @property
42
+ def effect(self):
43
+ from .primitives import Effect
44
+
45
+ return partial(Effect, context=self)
46
+
47
+
48
+ def new_context():
49
+ return Context([], [])
50
+
51
+
52
+ default_context = new_context()
reactivity/helpers.py CHANGED
@@ -3,23 +3,21 @@ from collections.abc import Callable, Mapping, MutableMapping
3
3
  from typing import Self, overload
4
4
  from weakref import WeakKeyDictionary
5
5
 
6
+ from .context import Context
6
7
  from .primitives import BaseComputation, Batch, Derived, Signal, Subscribable
7
8
 
8
9
 
9
10
  class Memoized[T](Subscribable, BaseComputation[T]):
10
- def __init__(self, fn: Callable[[], T]):
11
- super().__init__()
11
+ def __init__(self, fn: Callable[[], T], *, context: Context | None = None):
12
+ super().__init__(context=context)
12
13
  self.fn = fn
13
14
  self.is_stale = True
14
15
  self.cached_value: T
15
16
 
16
17
  def recompute(self):
17
- self._before()
18
- try:
18
+ with self._enter():
19
19
  self.cached_value = self.fn()
20
20
  self.is_stale = False
21
- finally:
22
- self._after()
23
21
 
24
22
  def trigger(self):
25
23
  self.invalidate()
@@ -38,10 +36,11 @@ class Memoized[T](Subscribable, BaseComputation[T]):
38
36
 
39
37
 
40
38
  class MemoizedProperty[T, I]:
41
- def __init__(self, method: Callable[[I], T]):
39
+ def __init__(self, method: Callable[[I], T], *, context: Context | None = None):
42
40
  super().__init__()
43
41
  self.method = method
44
42
  self.map = WeakKeyDictionary[I, Memoized[T]]()
43
+ self.context = context
45
44
 
46
45
  @overload
47
46
  def __get__(self, instance: None, owner: type[I]) -> Self: ...
@@ -53,15 +52,16 @@ class MemoizedProperty[T, I]:
53
52
  return self
54
53
  if func := self.map.get(instance):
55
54
  return func()
56
- self.map[instance] = func = Memoized(self.method.__get__(instance, owner))
55
+ self.map[instance] = func = Memoized(self.method.__get__(instance, owner), context=self.context)
57
56
  return func()
58
57
 
59
58
 
60
59
  class MemoizedMethod[T, I]:
61
- def __init__(self, method: Callable[[I], T]):
60
+ def __init__(self, method: Callable[[I], T], *, context: Context | None = None):
62
61
  super().__init__()
63
62
  self.method = method
64
63
  self.map = WeakKeyDictionary[I, Memoized[T]]()
64
+ self.context = context
65
65
 
66
66
  @overload
67
67
  def __get__(self, instance: None, owner: type[I]) -> Self: ...
@@ -73,7 +73,7 @@ class MemoizedMethod[T, I]:
73
73
  return self
74
74
  if memo := self.map.get(instance):
75
75
  return memo
76
- self.map[instance] = memo = Memoized(self.method.__get__(instance, owner))
76
+ self.map[instance] = memo = Memoized(self.method.__get__(instance, owner), context=self.context)
77
77
  return memo
78
78
 
79
79
 
@@ -86,9 +86,9 @@ class Reactive[K, V](Subscribable, MutableMapping[K, V]):
86
86
  def _null(self):
87
87
  return Signal(self.UNSET, self._check_equality)
88
88
 
89
- def __init__(self, initial: Mapping[K, V] | None = None, check_equality=True):
90
- super().__init__()
91
- self._signals = defaultdict[K, Signal[V]](self._null) if initial is None else defaultdict(self._null, {k: Signal(v, check_equality) for k, v in initial.items()})
89
+ def __init__(self, initial: Mapping[K, V] | None = None, check_equality=True, *, context: Context | None = None):
90
+ super().__init__(context=context)
91
+ self._signals = defaultdict[K, Signal[V]](self._null) if initial is None else defaultdict(self._null, {k: Signal(v, check_equality, context=context) for k, v in initial.items()})
92
92
  self._check_equality = check_equality
93
93
 
94
94
  def __getitem__(self, key: K):
@@ -98,7 +98,7 @@ class Reactive[K, V](Subscribable, MutableMapping[K, V]):
98
98
  return value
99
99
 
100
100
  def __setitem__(self, key: K, value: V):
101
- with Batch(force_flush=False):
101
+ with Batch(force_flush=False, context=self.context):
102
102
  if self._signals[key].set(value):
103
103
  self.notify()
104
104
 
@@ -106,7 +106,7 @@ class Reactive[K, V](Subscribable, MutableMapping[K, V]):
106
106
  state = self._signals[key]
107
107
  if state.get(track=False) is self.UNSET:
108
108
  raise KeyError(key)
109
- with Batch(force_flush=False):
109
+ with Batch(force_flush=False, context=self.context):
110
110
  state.set(self.UNSET)
111
111
  self.notify()
112
112
 
@@ -131,10 +131,11 @@ class Reactive[K, V](Subscribable, MutableMapping[K, V]):
131
131
 
132
132
 
133
133
  class DerivedProperty[T, I]:
134
- def __init__(self, method: Callable[[I], T]):
134
+ def __init__(self, method: Callable[[I], T], *, context: Context | None = None):
135
135
  super().__init__()
136
136
  self.method = method
137
137
  self.map = WeakKeyDictionary[I, Derived[T]]()
138
+ self.context = context
138
139
 
139
140
  @overload
140
141
  def __get__(self, instance: None, owner: type[I]) -> Self: ...
@@ -146,16 +147,17 @@ class DerivedProperty[T, I]:
146
147
  return self
147
148
  if func := self.map.get(instance):
148
149
  return func()
149
- self.map[instance] = func = Derived(self.method.__get__(instance, owner))
150
+ self.map[instance] = func = Derived(self.method.__get__(instance, owner), context=self.context)
150
151
  return func()
151
152
 
152
153
 
153
154
  class DerivedMethod[T, I]:
154
- def __init__(self, method: Callable[[I], T], check_equality=True):
155
+ def __init__(self, method: Callable[[I], T], check_equality=True, *, context: Context | None = None):
155
156
  super().__init__()
156
157
  self.method = method
157
158
  self.check_equality = check_equality
158
159
  self.map = WeakKeyDictionary[I, Derived[T]]()
160
+ self.context = context
159
161
 
160
162
  @overload
161
163
  def __get__(self, instance: None, owner: type[I]) -> Self: ...
@@ -168,5 +170,5 @@ class DerivedMethod[T, I]:
168
170
  if func := self.map.get(instance):
169
171
  return func
170
172
 
171
- self.map[instance] = func = Derived(self.method.__get__(instance, owner), self.check_equality)
173
+ self.map[instance] = func = Derived(self.method.__get__(instance, owner), self.check_equality, context=self.context)
172
174
  return func
reactivity/hmr/api.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import sys
2
2
 
3
- from .core import AsyncReloader, BaseReloader, SyncReloader, create_effect
3
+ from .core import HMR_CONTEXT, AsyncReloader, BaseReloader, SyncReloader
4
4
  from .hooks import call_post_reload_hooks, call_pre_reload_hooks
5
5
 
6
6
 
@@ -9,7 +9,7 @@ class LifecycleMixin(BaseReloader):
9
9
  self._original_main_module = sys.modules["__main__"]
10
10
  sys.modules["__main__"] = self.entry_module
11
11
  call_pre_reload_hooks()
12
- self.effect = create_effect(self.run_entry_file)
12
+ self.effect = HMR_CONTEXT.effect(self.run_entry_file)
13
13
  call_post_reload_hooks()
14
14
 
15
15
  def clean_up(self):
reactivity/hmr/core.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import sys
2
2
  from collections.abc import Iterable, MutableMapping, Sequence
3
3
  from contextlib import suppress
4
- from functools import cached_property
4
+ from functools import cached_property, partial
5
5
  from importlib.abc import Loader, MetaPathFinder
6
6
  from importlib.machinery import ModuleSpec
7
7
  from importlib.util import spec_from_loader
@@ -12,8 +12,8 @@ from types import ModuleType, TracebackType
12
12
  from typing import Any, Self
13
13
  from weakref import WeakValueDictionary
14
14
 
15
- from .. import Reactive, batch
16
- from ..functional import create_effect
15
+ from .. import Reactive
16
+ from ..context import new_context
17
17
  from ..helpers import DerivedMethod
18
18
  from ..primitives import BaseDerived, Derived, Signal
19
19
  from .hooks import call_post_reload_hooks, call_pre_reload_hooks
@@ -36,14 +36,17 @@ class Name(Signal, BaseDerived):
36
36
  pass
37
37
 
38
38
 
39
+ HMR_CONTEXT = new_context()
40
+
41
+
39
42
  class NamespaceProxy(Reactive[str, Any]):
40
43
  def __init__(self, initial: MutableMapping, module: "ReactiveModule", check_equality=True):
41
- super().__init__(initial, check_equality)
44
+ super().__init__(initial, check_equality, context=HMR_CONTEXT)
42
45
  self._original = initial
43
46
  self.module = module
44
47
 
45
48
  def _null(self):
46
- self.module.load.subscribers.add(signal := Name(self.UNSET, self._check_equality))
49
+ self.module.load.subscribers.add(signal := Name(self.UNSET, self._check_equality, context=HMR_CONTEXT))
47
50
  signal.dependencies.add(self.module.load)
48
51
  return signal
49
52
 
@@ -87,7 +90,7 @@ class ReactiveModule(ModuleType):
87
90
  return self.__file
88
91
  raise AttributeError("file")
89
92
 
90
- @DerivedMethod
93
+ @partial(DerivedMethod, context=HMR_CONTEXT)
91
94
  def __load(self):
92
95
  try:
93
96
  code = compile(self.__file.read_text("utf-8"), str(self.__file), "exec", dont_inherit=True)
@@ -253,7 +256,7 @@ class BaseReloader:
253
256
 
254
257
  call_pre_reload_hooks()
255
258
 
256
- with batch():
259
+ with HMR_CONTEXT.batch():
257
260
  for type, file in events:
258
261
  if type is not Change.deleted:
259
262
  path = Path(file).resolve()
@@ -297,7 +300,7 @@ class SyncReloader(BaseReloader):
297
300
 
298
301
  def keep_watching_until_interrupt(self):
299
302
  call_pre_reload_hooks()
300
- with suppress(KeyboardInterrupt), create_effect(self.run_entry_file):
303
+ with suppress(KeyboardInterrupt), HMR_CONTEXT.effect(self.run_entry_file):
301
304
  call_post_reload_hooks()
302
305
  self.start_watching()
303
306
 
@@ -322,7 +325,7 @@ class AsyncReloader(BaseReloader):
322
325
 
323
326
  async def keep_watching_until_interrupt(self):
324
327
  call_pre_reload_hooks()
325
- with suppress(KeyboardInterrupt), create_effect(self.run_entry_file):
328
+ with suppress(KeyboardInterrupt), HMR_CONTEXT.effect(self.run_entry_file):
326
329
  call_post_reload_hooks()
327
330
  await self.start_watching()
328
331
 
@@ -341,4 +344,4 @@ def cli():
341
344
  reloader.keep_watching_until_interrupt()
342
345
 
343
346
 
344
- __version__ = "0.5.3"
347
+ __version__ = "0.6.0"
reactivity/primitives.py CHANGED
@@ -1,7 +1,9 @@
1
- from collections.abc import Callable, Iterable
1
+ from collections.abc import Callable
2
2
  from typing import Any, Self, overload
3
3
  from weakref import WeakKeyDictionary, WeakSet
4
4
 
5
+ from .context import Context, default_context
6
+
5
7
 
6
8
  def _equal(a, b):
7
9
  if a is b:
@@ -22,43 +24,40 @@ def _equal(a, b):
22
24
 
23
25
 
24
26
  class Subscribable:
25
- def __init__(self):
27
+ def __init__(self, *, context: Context | None = None):
26
28
  super().__init__()
27
29
  self.subscribers = set[BaseComputation]()
30
+ self.context = context or default_context
28
31
 
29
32
  def track(self):
30
- if not _current_computations:
33
+ if not self.context.current_computations:
31
34
  return
32
- last = _current_computations[-1]
35
+ last = self.context.current_computations[-1]
33
36
  if last is not self:
34
37
  self.subscribers.add(last)
35
38
  last.dependencies.add(self)
36
39
 
37
40
  def notify(self):
38
- if _batches:
39
- schedule_callbacks(self.subscribers)
41
+ if self.context.batches:
42
+ self.context.schedule_callbacks(self.subscribers)
40
43
  else:
41
- with Batch(force_flush=False):
42
- schedule_callbacks(self.subscribers)
44
+ with Batch(force_flush=False, context=self.context):
45
+ self.context.schedule_callbacks(self.subscribers)
43
46
 
44
47
 
45
48
  class BaseComputation[T]:
46
- def __init__(self):
49
+ def __init__(self, *, context: Context | None = None):
47
50
  super().__init__()
48
51
  self.dependencies = WeakSet[Subscribable]()
52
+ self.context = context or default_context
49
53
 
50
54
  def dispose(self):
51
55
  for dep in self.dependencies:
52
56
  dep.subscribers.remove(self)
53
57
  self.dependencies.clear()
54
58
 
55
- def _before(self):
56
- self.dispose()
57
- _current_computations.append(self)
58
-
59
- def _after(self):
60
- last = _current_computations.pop()
61
- assert last is self # sanity check
59
+ def _enter(self):
60
+ return self.context.enter(self)
62
61
 
63
62
  def __enter__(self):
64
63
  return self
@@ -72,12 +71,9 @@ class BaseComputation[T]:
72
71
  return self.trigger()
73
72
 
74
73
 
75
- _current_computations: list[BaseComputation] = []
76
-
77
-
78
74
  class Signal[T](Subscribable):
79
- def __init__(self, initial_value: T = None, check_equality=True):
80
- super().__init__()
75
+ def __init__(self, initial_value: T = None, check_equality=True, *, context: Context | None = None):
76
+ super().__init__(context=context)
81
77
  self._value: T = initial_value
82
78
  self._check_equality = check_equality
83
79
 
@@ -95,8 +91,8 @@ class Signal[T](Subscribable):
95
91
 
96
92
 
97
93
  class State[T](Signal[T]):
98
- def __init__(self, initial_value: T = None, check_equality=True):
99
- super().__init__(initial_value, check_equality)
94
+ def __init__(self, initial_value: T = None, check_equality=True, *, context: Context | None = None):
95
+ super().__init__(initial_value, check_equality, context=context)
100
96
  self._value = initial_value
101
97
  self._check_equality = check_equality
102
98
  self.map = WeakKeyDictionary[Any, Signal[T]]()
@@ -112,20 +108,20 @@ class State[T](Signal[T]):
112
108
  try:
113
109
  return self.map[instance].get()
114
110
  except KeyError:
115
- self.map[instance] = state = Signal(self._value, self._check_equality)
111
+ self.map[instance] = state = Signal(self._value, self._check_equality, context=self.context)
116
112
  return state.get()
117
113
 
118
114
  def __set__(self, instance, value: T):
119
115
  try:
120
116
  state = self.map[instance]
121
117
  except KeyError:
122
- self.map[instance] = state = Signal(self._value, self._check_equality)
118
+ self.map[instance] = state = Signal(self._value, self._check_equality, context=self.context)
123
119
  state.set(value)
124
120
 
125
121
 
126
122
  class Effect[T](BaseComputation[T]):
127
- def __init__(self, fn: Callable[[], T], call_immediately=True):
128
- super().__init__()
123
+ def __init__(self, fn: Callable[[], T], call_immediately=True, *, context: Context | None = None):
124
+ super().__init__(context=context)
129
125
 
130
126
  self._fn = fn
131
127
 
@@ -133,17 +129,15 @@ class Effect[T](BaseComputation[T]):
133
129
  self()
134
130
 
135
131
  def trigger(self):
136
- self._before()
137
- try:
132
+ with self._enter():
138
133
  return self._fn()
139
- finally:
140
- self._after()
141
134
 
142
135
 
143
136
  class Batch:
144
- def __init__(self, force_flush=True):
137
+ def __init__(self, force_flush=True, *, context: Context | None = None):
145
138
  self.callbacks = set[BaseComputation]()
146
139
  self.force_flush = force_flush
140
+ self.context = context or default_context
147
141
 
148
142
  def flush(self):
149
143
  triggered = set()
@@ -157,30 +151,23 @@ class Batch:
157
151
  triggered.add(computation)
158
152
 
159
153
  def __enter__(self):
160
- _batches.append(self)
154
+ self.context.batches.append(self)
161
155
 
162
156
  def __exit__(self, *_):
163
- if self.force_flush or len(_batches) == 1:
157
+ if self.force_flush or len(self.context.batches) == 1:
164
158
  try:
165
159
  self.flush()
166
160
  finally:
167
- last = _batches.pop()
161
+ last = self.context.batches.pop()
168
162
  else:
169
- last = _batches.pop()
170
- schedule_callbacks(self.callbacks)
163
+ last = self.context.batches.pop()
164
+ self.context.schedule_callbacks(self.callbacks)
171
165
  assert last is self
172
166
 
173
167
 
174
- _batches: list[Batch] = []
175
-
176
-
177
- def schedule_callbacks(callbacks: Iterable[BaseComputation]):
178
- _batches[-1].callbacks.update(callbacks)
179
-
180
-
181
168
  class BaseDerived[T](Subscribable, BaseComputation[T]):
182
- def __init__(self):
183
- super().__init__()
169
+ def __init__(self, *, context: Context | None = None):
170
+ super().__init__(context=context)
184
171
  self.dirty = True
185
172
 
186
173
  def _sync_dirty_deps(self):
@@ -192,15 +179,14 @@ class BaseDerived[T](Subscribable, BaseComputation[T]):
192
179
  class Derived[T](BaseDerived[T]):
193
180
  UNSET: T = object() # type: ignore
194
181
 
195
- def __init__(self, fn: Callable[[], T], check_equality=True):
196
- super().__init__()
182
+ def __init__(self, fn: Callable[[], T], check_equality=True, *, context: Context | None = None):
183
+ super().__init__(context=context)
197
184
  self.fn = fn
198
185
  self._check_equality = check_equality
199
186
  self._value = self.UNSET
200
187
 
201
188
  def recompute(self):
202
- self._before()
203
- try:
189
+ with self._enter():
204
190
  value = self.fn()
205
191
  self.dirty = False
206
192
  if self._check_equality:
@@ -211,8 +197,6 @@ class Derived[T](BaseDerived[T]):
211
197
  return
212
198
  self._value = value
213
199
  self.notify()
214
- finally:
215
- self._after()
216
200
 
217
201
  def __call__(self):
218
202
  self.track()
@@ -1,14 +0,0 @@
1
- hmr-0.5.3.dist-info/METADATA,sha256=Y3kB1iJBhlnFuwz18jp1wn98jNXwBo_UtXOuj4OpR6Q,1999
2
- hmr-0.5.3.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
- hmr-0.5.3.dist-info/entry_points.txt,sha256=g_T0uJ43WgsdG14kkkdaBQuIL0HO-m1qvtjXMP6d060,59
4
- reactivity/__init__.py,sha256=pX-RUzkezCC1x4eOWGxNhXbwrbvBLP_3pQuZr9eZz1Y,300
5
- reactivity/functional.py,sha256=jJLEq88w5ag2cXuD1T118uEjnEg37_mqvWmFkb47KVY,1300
6
- reactivity/helpers.py,sha256=rcrCXy1mmlei-if_BN4nSgS2IG9kBj-jq1YRwEfcITo,5329
7
- reactivity/hmr/__init__.py,sha256=S5ZIHqCRpevdzWuhS0aCua_S8F0LkK0YNg6IgeTScFQ,177
8
- reactivity/hmr/__main__.py,sha256=uIcyjR5gMFIXH_3hS0B3SD00RirVf7GIct-uItx675o,64
9
- reactivity/hmr/api.py,sha256=sKDQV7uKRVoDifTZKrLQGZP-fzgYbdVjfEOC6ki4NKY,2280
10
- reactivity/hmr/core.py,sha256=_H4PvJdNe328AlA84WkGxYJHehJBDvS5yqwyIRywCWo,11714
11
- reactivity/hmr/hooks.py,sha256=jIFpe4CNxfaS9RcR4OIodx_sOZlnJ_IA1T1RtHPXhwU,945
12
- reactivity/hmr/utils.py,sha256=h9m7iRXlvsLTrHoXV9gEVbhz3XsPK4KgnStYoCAWE5I,1616
13
- reactivity/primitives.py,sha256=alFH1W7y2UHgXI3Vlk8GFdIlcFTcQ3Q9cpz2Y1vDZuQ,6553
14
- hmr-0.5.3.dist-info/RECORD,,
File without changes