hmr 0.0.3__tar.gz → 0.0.3.1__tar.gz

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.0.3
3
+ Version: 0.0.3.1
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
@@ -6,7 +6,7 @@ description = "Hot Module Reload for Python"
6
6
  dependencies = [
7
7
  "watchfiles>=0.21,<2",
8
8
  ]
9
- version = "0.0.3"
9
+ version = "0.0.3.1"
10
10
 
11
11
  [project.scripts]
12
12
  hmr = "reactivity.hmr:cli"
@@ -0,0 +1,5 @@
1
+ from .functional import batch, create_effect, create_memo, create_signal, memoized_method, memoized_property
2
+ from .helpers import Reactive
3
+ from .primitives import State
4
+
5
+ __all__ = ["Reactive", "State", "batch", "create_effect", "create_memo", "create_signal", "memoized_method", "memoized_property"]
@@ -3,7 +3,7 @@ from functools import wraps
3
3
  from typing import Protocol, overload
4
4
 
5
5
  from .helpers import Memoized, MemoizedMethod, MemoizedProperty
6
- from .primitives import Batch, Derived, Signal
6
+ from .primitives import Batch, Effect, Signal
7
7
 
8
8
 
9
9
  class Getter[T](Protocol):
@@ -19,19 +19,19 @@ def create_signal[T](initial_value: T = None, check_equality=True) -> tuple[Gett
19
19
  return signal.get, signal.set
20
20
 
21
21
 
22
- def create_effect[T](fn: Callable[[], T], auto_run=True):
23
- return Derived(fn, auto_run)
22
+ def create_effect[T](fn: Callable[[], T], call_immediately=True):
23
+ return Effect(fn, call_immediately)
24
24
 
25
25
 
26
26
  def create_memo[T](fn: Callable[[], T]):
27
27
  return Memoized(fn)
28
28
 
29
29
 
30
- def memoized_property[T, Self](method: Callable[[Self], T]):
30
+ def memoized_property[T, I](method: Callable[[I], T]):
31
31
  return MemoizedProperty(method)
32
32
 
33
33
 
34
- def memoized_method[T, Self](method: Callable[[Self], T]):
34
+ def memoized_method[T, I](method: Callable[[I], T]):
35
35
  return MemoizedMethod(method)
36
36
 
37
37
 
@@ -1,5 +1,7 @@
1
+ from collections import defaultdict
1
2
  from collections.abc import Callable, Mapping, MutableMapping
2
3
  from functools import partial
4
+ from typing import Self, overload
3
5
  from weakref import WeakKeyDictionary
4
6
 
5
7
  from .primitives import BaseComputation, Batch, Signal, Subscribable
@@ -36,31 +38,44 @@ class Memoized[T](Subscribable, BaseComputation[T]):
36
38
  self.is_stale = True
37
39
 
38
40
 
39
- class MemoizedProperty[T, Self]:
40
- def __init__(self, method: Callable[[Self], T]):
41
+ class MemoizedProperty[T, I]:
42
+ def __init__(self, method: Callable[[I], T]):
41
43
  super().__init__()
42
44
  self.method = method
43
- self.map = WeakKeyDictionary[Self, Memoized]()
45
+ self.map = WeakKeyDictionary[I, Memoized[T]]()
44
46
 
45
- def __get__(self, instance, owner):
47
+ @overload
48
+ def __get__(self, instance: None, owner: type[I]) -> Self: ...
49
+ @overload
50
+ def __get__(self, instance: I, owner: type[I]) -> T: ...
51
+
52
+ def __get__(self, instance: I | None, owner):
53
+ if instance is None:
54
+ return self
46
55
  if func := self.map.get(instance):
47
56
  return func()
48
57
  self.map[instance] = func = Memoized(partial(self.method, instance))
49
58
  return func()
50
59
 
51
60
 
52
- class MemoizedMethod[T, Self]:
53
- def __init__(self, method: Callable[[Self], T]):
61
+ class MemoizedMethod[T, I]:
62
+ def __init__(self, method: Callable[[I], T]):
54
63
  super().__init__()
55
64
  self.method = method
56
- self.map = WeakKeyDictionary[Self, Memoized]()
65
+ self.map = WeakKeyDictionary[I, Memoized[T]]()
66
+
67
+ @overload
68
+ def __get__(self, instance: None, owner: type[I]) -> Self: ...
69
+ @overload
70
+ def __get__(self, instance: I, owner: type[I]) -> Memoized[T]: ...
57
71
 
58
- def __get__(self, instance, owner):
59
- try:
60
- return self.map[instance]
61
- except KeyError:
62
- self.map[instance] = memo = Memoized(partial(self.method, instance))
72
+ def __get__(self, instance: I | None, owner):
73
+ if instance is None:
74
+ return self
75
+ if memo := self.map.get(instance):
63
76
  return memo
77
+ self.map[instance] = memo = Memoized(partial(self.method, instance))
78
+ return memo
64
79
 
65
80
 
66
81
  class Reactive[K, V](Subscribable, MutableMapping[K, V]):
@@ -69,24 +84,23 @@ class Reactive[K, V](Subscribable, MutableMapping[K, V]):
69
84
  def __hash__(self):
70
85
  return id(self)
71
86
 
72
- def __init__(self, initial: Mapping | None = None, check_equality=True):
87
+ def _null(self):
88
+ return Signal(self.UNSET, self._check_equality)
89
+
90
+ def __init__(self, initial: Mapping[K, V] | None = None, check_equality=True):
73
91
  super().__init__()
74
- self._signals: dict[K, Signal[V]] = {} if initial is None else {k: Signal(v, check_equality) for k, v in initial.items()}
92
+ 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()})
75
93
  self._check_equality = check_equality
76
94
 
77
95
  def __getitem__(self, key: K):
78
- value = self._signals.setdefault(key, Signal(self.UNSET, self._check_equality)).get()
96
+ value = self._signals[key].get()
79
97
  if value is self.UNSET:
80
98
  raise KeyError(key)
81
99
  return value
82
100
 
83
101
  def __setitem__(self, key: K, value: V):
84
102
  with Batch():
85
- try:
86
- self._signals[key].set(value)
87
- except KeyError:
88
- self._signals[key] = Signal(value, self._check_equality)
89
- self._signals[key].set(value)
103
+ self._signals[key].set(value)
90
104
  self.notify()
91
105
 
92
106
  def __delitem__(self, key: K):
@@ -95,7 +109,6 @@ class Reactive[K, V](Subscribable, MutableMapping[K, V]):
95
109
  raise KeyError(key)
96
110
  with Batch():
97
111
  state.set(self.UNSET)
98
- state.notify()
99
112
  self.notify()
100
113
 
101
114
  def __iter__(self):
@@ -58,11 +58,14 @@ class ReactiveModule(ModuleType):
58
58
  return self.__file
59
59
  raise AttributeError("file")
60
60
 
61
+ def __load(self):
62
+ code = compile(self.__file.read_text("utf-8"), str(self.__file), "exec", dont_inherit=True)
63
+ exec(code, self.__namespace, self.__namespace_proxy)
64
+
61
65
  @property
62
66
  def load(self):
63
67
  if is_called_in_this_file():
64
- code = compile(self.__file.read_text("utf-8"), str(self.__file), "exec", dont_inherit=True)
65
- return lambda: exec(code, self.__namespace, self.__namespace_proxy)
68
+ return self.__load
66
69
  raise AttributeError("load")
67
70
 
68
71
  def __dir__(self):
@@ -246,4 +249,4 @@ def cli():
246
249
  SyncReloader(entry, excludes={".venv"}).keep_watching_until_interrupt()
247
250
 
248
251
 
249
- __version__ = "0.0.3"
252
+ __version__ = "0.0.3.1"
@@ -1,5 +1,5 @@
1
1
  from collections.abc import Callable
2
- from typing import Any
2
+ from typing import Any, Self, overload
3
3
  from weakref import WeakKeyDictionary, WeakSet
4
4
 
5
5
 
@@ -79,7 +79,14 @@ class State[T](Signal[T]):
79
79
  self._check_equality = check_equality
80
80
  self.map = WeakKeyDictionary[Any, Signal[T]]()
81
81
 
82
+ @overload
83
+ def __get__(self, instance: None, owner: type) -> Self: ...
84
+ @overload
85
+ def __get__(self, instance: Any, owner: type) -> T: ...
86
+
82
87
  def __get__(self, instance, owner):
88
+ if instance is None:
89
+ return self
83
90
  try:
84
91
  return self.map[instance].get()
85
92
  except KeyError:
@@ -94,13 +101,13 @@ class State[T](Signal[T]):
94
101
  state.set(value)
95
102
 
96
103
 
97
- class Derived[T](BaseComputation[T]):
98
- def __init__(self, fn: Callable[[], T], auto_run=True):
104
+ class Effect[T](BaseComputation[T]):
105
+ def __init__(self, fn: Callable[[], T], call_immediately=True):
99
106
  super().__init__()
100
107
 
101
108
  self._fn = fn
102
109
 
103
- if auto_run:
110
+ if call_immediately:
104
111
  self()
105
112
 
106
113
  def trigger(self):
@@ -1,5 +0,0 @@
1
- from .functional import batch, create_effect, create_memo, create_signal, memoized_method, memoized_property
2
- from .helpers import Reactive
3
- from .primitives import Derived, State
4
-
5
- __all__ = ["Derived", "Reactive", "State", "batch", "create_effect", "create_memo", "create_signal", "memoized_method", "memoized_property"]