hmr 0.1.2__py3-none-any.whl → 0.2.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.
- {hmr-0.1.2.dist-info → hmr-0.2.0.dist-info}/METADATA +2 -2
- hmr-0.2.0.dist-info/RECORD +9 -0
- reactivity/helpers.py +12 -15
- reactivity/hmr.py +3 -2
- reactivity/primitives.py +36 -18
- hmr-0.1.2.dist-info/RECORD +0 -9
- {hmr-0.1.2.dist-info → hmr-0.2.0.dist-info}/WHEEL +0 -0
- {hmr-0.1.2.dist-info → hmr-0.2.0.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: hmr
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.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
|
7
|
-
Requires-Dist: watchfiles<2,>=0.21
|
7
|
+
Requires-Dist: watchfiles<2,>=0.21; sys_platform != "emscripten"
|
8
8
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
hmr-0.2.0.dist-info/METADATA,sha256=EOVgm-SYoDvhCdf7X3stdnfoOwt4JiJz4dU-MH5qp4A,258
|
2
|
+
hmr-0.2.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
3
|
+
hmr-0.2.0.dist-info/entry_points.txt,sha256=g_T0uJ43WgsdG14kkkdaBQuIL0HO-m1qvtjXMP6d060,59
|
4
|
+
reactivity/__init__.py,sha256=pX-RUzkezCC1x4eOWGxNhXbwrbvBLP_3pQuZr9eZz1Y,300
|
5
|
+
reactivity/functional.py,sha256=U06vshcVhZ0sb218gcmHtEhfgTNAGtQ7zyvPz2w5qKM,1292
|
6
|
+
reactivity/helpers.py,sha256=7gwsIKKrjEahSz9G9oR4s1LdYXQTCIMO0k4UGXGla9Y,3714
|
7
|
+
reactivity/hmr.py,sha256=CeJSXPeDA-wc_tE_JC0gXfFgeaGsCEvmVbbsCYJtGok,9603
|
8
|
+
reactivity/primitives.py,sha256=DR2waJbzhVKOioHXMliE4FIsxQUq7DZA0umPrlvchA4,4217
|
9
|
+
hmr-0.2.0.dist-info/RECORD,,
|
reactivity/helpers.py
CHANGED
@@ -13,32 +13,29 @@ class Memoized[T](Subscribable, BaseComputation[T]):
|
|
13
13
|
self.fn = fn
|
14
14
|
self.is_stale = True
|
15
15
|
self.cached_value: T
|
16
|
-
|
16
|
+
|
17
|
+
def recompute(self):
|
18
|
+
self._before()
|
19
|
+
try:
|
20
|
+
self.cached_value = self.fn()
|
21
|
+
self.is_stale = False
|
22
|
+
finally:
|
23
|
+
self._after()
|
17
24
|
|
18
25
|
def trigger(self):
|
19
|
-
self.
|
20
|
-
if self._recompute:
|
21
|
-
self._recompute = False
|
22
|
-
self._before()
|
23
|
-
try:
|
24
|
-
self.cached_value = self.fn()
|
25
|
-
self.is_stale = False
|
26
|
-
finally:
|
27
|
-
self._after()
|
28
|
-
else:
|
29
|
-
self.invalidate()
|
26
|
+
self.invalidate()
|
30
27
|
|
31
28
|
def __call__(self):
|
29
|
+
self.track()
|
32
30
|
if self.is_stale:
|
33
|
-
self.
|
34
|
-
self.trigger()
|
35
|
-
assert not self._recompute
|
31
|
+
self.recompute()
|
36
32
|
return self.cached_value
|
37
33
|
|
38
34
|
def invalidate(self):
|
39
35
|
if not self.is_stale:
|
40
36
|
del self.cached_value
|
41
37
|
self.is_stale = True
|
38
|
+
self.notify()
|
42
39
|
|
43
40
|
|
44
41
|
class MemoizedProperty[T, I]:
|
reactivity/hmr.py
CHANGED
@@ -278,9 +278,10 @@ def cli():
|
|
278
278
|
print("\n Usage: hmr <entry file>, just like python <entry file>\n")
|
279
279
|
exit(1)
|
280
280
|
entry = sys.argv[-1]
|
281
|
-
|
281
|
+
if not (path := Path(entry)).is_file():
|
282
|
+
raise FileNotFoundError(path.resolve())
|
282
283
|
sys.path.insert(0, ".")
|
283
284
|
SyncReloader(entry, excludes={".venv"}).keep_watching_until_interrupt()
|
284
285
|
|
285
286
|
|
286
|
-
__version__ = "0.
|
287
|
+
__version__ = "0.2.0"
|
reactivity/primitives.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from collections.abc import Callable
|
1
|
+
from collections.abc import Callable, Iterable
|
2
2
|
from typing import Any, Self, overload
|
3
3
|
from weakref import WeakKeyDictionary, WeakSet
|
4
4
|
|
@@ -9,17 +9,19 @@ class Subscribable:
|
|
9
9
|
self.subscribers = set[BaseComputation]()
|
10
10
|
|
11
11
|
def track(self):
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
if not _current_computations:
|
13
|
+
return
|
14
|
+
last = _current_computations[-1]
|
15
|
+
if last is not self:
|
16
|
+
self.subscribers.add(last)
|
17
|
+
last.dependencies.add(self)
|
16
18
|
|
17
19
|
def notify(self):
|
18
20
|
if _batches:
|
19
|
-
|
21
|
+
schedule_callbacks(self.subscribers)
|
20
22
|
else:
|
21
|
-
|
22
|
-
|
23
|
+
with Batch(force_flush=False):
|
24
|
+
schedule_callbacks(self.subscribers)
|
23
25
|
|
24
26
|
|
25
27
|
class BaseComputation[T]:
|
@@ -46,9 +48,9 @@ class BaseComputation[T]:
|
|
46
48
|
def __exit__(self, *_):
|
47
49
|
self.dispose()
|
48
50
|
|
49
|
-
def trigger(self) ->
|
51
|
+
def trigger(self) -> Any: ...
|
50
52
|
|
51
|
-
def __call__(self):
|
53
|
+
def __call__(self) -> T:
|
52
54
|
return self.trigger()
|
53
55
|
|
54
56
|
|
@@ -119,22 +121,38 @@ class Effect[T](BaseComputation[T]):
|
|
119
121
|
|
120
122
|
|
121
123
|
class Batch:
|
122
|
-
def __init__(self):
|
123
|
-
self.callbacks
|
124
|
+
def __init__(self, force_flush=True):
|
125
|
+
self.callbacks = set[BaseComputation]()
|
126
|
+
self.force_flush = force_flush
|
124
127
|
|
125
128
|
def flush(self):
|
126
|
-
|
127
|
-
self.callbacks
|
128
|
-
|
129
|
-
|
129
|
+
triggered = set()
|
130
|
+
while self.callbacks:
|
131
|
+
callbacks = self.callbacks - triggered
|
132
|
+
self.callbacks.clear()
|
133
|
+
for computation in callbacks:
|
134
|
+
if computation in self.callbacks:
|
135
|
+
continue # skip if re-added during callback
|
136
|
+
computation.trigger()
|
137
|
+
triggered.add(computation)
|
130
138
|
|
131
139
|
def __enter__(self):
|
132
140
|
_batches.append(self)
|
133
141
|
|
134
142
|
def __exit__(self, *_):
|
135
|
-
|
143
|
+
if self.force_flush or len(_batches) == 1:
|
144
|
+
try:
|
145
|
+
self.flush()
|
146
|
+
finally:
|
147
|
+
last = _batches.pop()
|
148
|
+
else:
|
149
|
+
last = _batches.pop()
|
150
|
+
schedule_callbacks(self.callbacks)
|
136
151
|
assert last is self
|
137
|
-
self.flush()
|
138
152
|
|
139
153
|
|
140
154
|
_batches: list[Batch] = []
|
155
|
+
|
156
|
+
|
157
|
+
def schedule_callbacks(callbacks: Iterable[BaseComputation]):
|
158
|
+
_batches[-1].callbacks.update(callbacks)
|
hmr-0.1.2.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
hmr-0.1.2.dist-info/METADATA,sha256=tHSOaU8XTf-WF85Hg7r6Fimk-g6WZZa3jJeurid7yno,228
|
2
|
-
hmr-0.1.2.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
3
|
-
hmr-0.1.2.dist-info/entry_points.txt,sha256=g_T0uJ43WgsdG14kkkdaBQuIL0HO-m1qvtjXMP6d060,59
|
4
|
-
reactivity/__init__.py,sha256=pX-RUzkezCC1x4eOWGxNhXbwrbvBLP_3pQuZr9eZz1Y,300
|
5
|
-
reactivity/functional.py,sha256=U06vshcVhZ0sb218gcmHtEhfgTNAGtQ7zyvPz2w5qKM,1292
|
6
|
-
reactivity/helpers.py,sha256=1KmMCO6lqluHlMsjGQQ9UJZBtbFppjFZnmi9RhowRHo,3872
|
7
|
-
reactivity/hmr.py,sha256=lUqHeB_5LlrHMUSWXRvSRGoaMkFAm3ONQNxm5OCk0Uw,9570
|
8
|
-
reactivity/primitives.py,sha256=lw4G3GpANRGK5dKw11eYc2-nlOJ1uCO3f3MiLa41jG8,3588
|
9
|
-
hmr-0.1.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|