hmr 0.2.1__py3-none-any.whl → 0.3.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.2.1
3
+ Version: 0.3.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,12 @@
1
+ hmr-0.3.0.dist-info/METADATA,sha256=PcpVod1MtZSUbVP91KWKD9ioN7qTULhzxHR9vK20ZvA,258
2
+ hmr-0.3.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ hmr-0.3.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/__init__.py,sha256=S5ZIHqCRpevdzWuhS0aCua_S8F0LkK0YNg6IgeTScFQ,177
8
+ reactivity/hmr/core.py,sha256=NfzgqTdFD7wrO_8ogZTSqMmVIRw4Z_hhk5-ONRlunSI,9993
9
+ reactivity/hmr/hooks.py,sha256=-yLr5ktiyqPb1nDbHsgv6-c_ZkziBjNqCU-0PCfXGYU,592
10
+ reactivity/hmr/utils.py,sha256=zgKjz3RhcUDYLoIqZFRVBcPtPWUJA1YphJycyrQx3tk,1464
11
+ reactivity/primitives.py,sha256=DR2waJbzhVKOioHXMliE4FIsxQUq7DZA0umPrlvchA4,4217
12
+ hmr-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ from .core import cli
2
+ from .hooks import post_reload, pre_reload
3
+ from .utils import cache_across_reloads
4
+
5
+ __all__ = ("cache_across_reloads", "cli", "post_reload", "pre_reload")
@@ -7,12 +7,12 @@ from importlib.machinery import ModuleSpec
7
7
  from importlib.util import spec_from_loader
8
8
  from inspect import currentframe
9
9
  from pathlib import Path
10
- from runpy import run_path
11
10
  from site import getsitepackages
12
11
  from types import ModuleType, TracebackType
13
12
  from typing import Any
14
13
 
15
- from . import Reactive, batch, memoized_method
14
+ from .. import Reactive, batch, memoized_method
15
+ from .hooks import call_post_reload_hooks, call_pre_reload_hooks
16
16
 
17
17
 
18
18
  def is_called_in_this_file() -> bool:
@@ -188,13 +188,20 @@ class BaseReloader:
188
188
  self.includes = includes
189
189
  self.excludes = excludes
190
190
  patch_meta_path(includes, excludes)
191
- self.last_globals = {}
192
- self.error_filter = ErrorFilter(__file__, "<frozen runpy>")
191
+ self.error_filter = ErrorFilter(*(str(i) for i in Path(__file__, "../..").resolve().glob("**/*.py")))
193
192
 
194
193
  @memoized_method
195
194
  def run_entry_file(self):
195
+ call_pre_reload_hooks()
196
+
196
197
  with self.error_filter:
197
- self.last_globals = run_path(self.entry, self.last_globals, "__main__")
198
+ if not isinstance(module := sys.modules["__main__"], ReactiveModule):
199
+ namespace = {"__file__": self.entry, "__name__": "__main__"}
200
+ module = sys.modules["__main__"] = ReactiveModule(Path(self.entry), namespace, "__main__")
201
+ module.load.invalidate()
202
+ module.load()
203
+
204
+ call_post_reload_hooks()
198
205
 
199
206
  @property
200
207
  def watch_filter(self):
@@ -285,4 +292,4 @@ def cli():
285
292
  SyncReloader(entry).keep_watching_until_interrupt()
286
293
 
287
294
 
288
- __version__ = "0.2.1"
295
+ __version__ = "0.3.0"
@@ -0,0 +1,25 @@
1
+ from collections.abc import Callable
2
+ from typing import Any
3
+
4
+ pre_reload_hooks: dict[str, Callable[[], Any]] = {}
5
+ post_reload_hooks: dict[str, Callable[[], Any]] = {}
6
+
7
+
8
+ def pre_reload[T](func: Callable[[], T]) -> Callable[[], T]:
9
+ pre_reload_hooks[func.__name__] = func
10
+ return func
11
+
12
+
13
+ def post_reload[T](func: Callable[[], T]) -> Callable[[], T]:
14
+ post_reload_hooks[func.__name__] = func
15
+ return func
16
+
17
+
18
+ def call_pre_reload_hooks():
19
+ for func in pre_reload_hooks.values():
20
+ func()
21
+
22
+
23
+ def call_post_reload_hooks():
24
+ for func in post_reload_hooks.values():
25
+ func()
@@ -0,0 +1,61 @@
1
+ import sys
2
+ from collections import UserDict
3
+ from collections.abc import Callable
4
+ from functools import wraps
5
+ from inspect import getsource
6
+ from types import FunctionType
7
+
8
+ from .. import create_memo
9
+ from .core import NamespaceProxy, ReactiveModule
10
+ from .hooks import post_reload, pre_reload
11
+
12
+ memos: dict[str, Callable] = {}
13
+ functions: dict[str, Callable] = {}
14
+ functions_last: set[str] = set()
15
+
16
+
17
+ @pre_reload
18
+ def swap():
19
+ functions_last.update(functions)
20
+ functions.clear()
21
+
22
+
23
+ @post_reload
24
+ def clear_memos():
25
+ for func in functions_last:
26
+ if func not in functions and func in memos:
27
+ del memos[func]
28
+
29
+
30
+ def cache_across_reloads[T](func: Callable[[], T]) -> Callable[[], T]:
31
+ module = sys.modules[func.__module__]
32
+
33
+ if not isinstance(module, ReactiveModule):
34
+ from functools import cache
35
+
36
+ return cache(func) # type: ignore
37
+
38
+ source = getsource(func)
39
+
40
+ proxy: NamespaceProxy = module._ReactiveModule__namespace_proxy # type: ignore # noqa: SLF001
41
+
42
+ func = FunctionType(func.__code__, DictProxy(proxy), func.__name__, func.__defaults__, func.__closure__)
43
+
44
+ functions[source] = func
45
+
46
+ if source in memos and source in functions_last:
47
+ return memos[source]
48
+
49
+ @wraps(func)
50
+ @create_memo
51
+ def wrapper():
52
+ return functions[source]()
53
+
54
+ memos[source] = wrapper
55
+
56
+ return wrapper
57
+
58
+
59
+ class DictProxy(UserDict, dict): # type: ignore
60
+ def __init__(self, data):
61
+ self.data = data
@@ -1,9 +0,0 @@
1
- hmr-0.2.1.dist-info/METADATA,sha256=QnthYHF5mqiGCrS_KTlsy8klZV8q_ebFLuDJyk68bV0,258
2
- hmr-0.2.1.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- hmr-0.2.1.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=NeluXz7ufmQybqp8BivF-q_tSl2XTPyj8tVvKWz9S1c,9631
8
- reactivity/primitives.py,sha256=DR2waJbzhVKOioHXMliE4FIsxQUq7DZA0umPrlvchA4,4217
9
- hmr-0.2.1.dist-info/RECORD,,
File without changes