PersistentObjects 0.2.1__tar.gz → 0.2.2__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.4
2
2
  Name: PersistentObjects
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: JSON-backed attribute-persistent object with namespace support
5
5
  Author: Tornado300
6
6
  License-Expression: MIT
@@ -52,9 +52,9 @@ def _decode_hook(obj):
52
52
 
53
53
 
54
54
  class _PersistentState:
55
- _instances = {}
55
+ _instances: dict[str, "_PersistentState"] = {}
56
56
 
57
- def __new__(cls, path):
57
+ def __new__(cls, path: str) -> "_PersistentState":
58
58
  path = os.path.abspath(path)
59
59
 
60
60
  if path in cls._instances:
@@ -69,12 +69,12 @@ class _PersistentState:
69
69
  if hasattr(self, "_initialized"):
70
70
  return
71
71
 
72
- self._initialized = True
73
- self._path = os.path.abspath(path)
74
- self._lock = threading.Lock()
75
- self._data = {}
76
- self._defaults = {}
77
- self._types = {}
72
+ self._initialized: bool = True
73
+ self._path: str = os.path.abspath(path)
74
+ self._lock: threading.Lock = threading.Lock()
75
+ self._data: dict[str, Any] = {}
76
+ self._defaults: dict[str, Any] = {}
77
+ self._types: dict[str, Any] = {}
78
78
  self._load()
79
79
 
80
80
  def _load(self) -> None:
@@ -91,7 +91,7 @@ class _PersistentState:
91
91
  json.dump(_encode(self._data), f, indent=2)
92
92
  os.replace(tmp, self._path)
93
93
 
94
- def __getattr__(self, name) -> Any:
94
+ def __getattr__(self, name: str) -> "Any | _Namespace":
95
95
  if name.startswith("_"):
96
96
  raise AttributeError(f"Cannot access private attribute '{name}'")
97
97
  if name.endswith("_"):
@@ -167,10 +167,10 @@ class _PersistentState:
167
167
 
168
168
 
169
169
  class _Namespace:
170
- _instances: dict = {}
170
+ _instances: dict[tuple[int, tuple[str, ...]], "_Namespace"] = {}
171
171
 
172
172
  def __new__(cls, root: _PersistentState, *path: str) -> "_Namespace":
173
- instance_key = (id(root), path)
173
+ instance_key: tuple[int, tuple[str, ...]] = (id(root), path)
174
174
 
175
175
  if instance_key in cls._instances:
176
176
  return cls._instances[instance_key]
@@ -183,13 +183,13 @@ class _Namespace:
183
183
  if hasattr(self, "_initialized"):
184
184
  return
185
185
 
186
- self._initialized = True
187
- self._root = root
188
- self._path = path
189
- self._defaults: dict = {}
190
- self._types: dict = {}
186
+ self._initialized: bool = True
187
+ self._root: _PersistentState = root
188
+ self._path: tuple[str, ...] = path
189
+ self._defaults: dict[str, Any] = {}
190
+ self._types: dict[str, Any] = {}
191
191
 
192
- def _get_bucket(self, create: bool = False) -> dict:
192
+ def _get_bucket(self, create: bool = False) -> dict[str, Any]:
193
193
  """Navigate the path into root._data, returning the nested dict."""
194
194
  data = self._root._data
195
195
  for key in self._path:
@@ -199,7 +199,7 @@ class _Namespace:
199
199
  data = data[key]
200
200
  return data
201
201
 
202
- def __getattr__(self, name: str) -> Any:
202
+ def __getattr__(self, name: str) -> "Any | _Namespace":
203
203
  if name.startswith("_"):
204
204
  raise AttributeError(name)
205
205
  if name.endswith("_"):
@@ -265,6 +265,40 @@ class _Namespace:
265
265
  path = ".".join(self._path)
266
266
  return f"Namespace({path!r}, {data})"
267
267
 
268
+ # Arithmetic/comparison dunders so Pyright accepts `Any | _Namespace` in expressions.
269
+ # These are never called at runtime (values go through __getattr__, not _Namespace).
270
+ def __add__(self, other: Any) -> Any: return NotImplemented
271
+ def __radd__(self, other: Any) -> Any: return NotImplemented
272
+ def __sub__(self, other: Any) -> Any: return NotImplemented
273
+ def __rsub__(self, other: Any) -> Any: return NotImplemented
274
+ def __mul__(self, other: Any) -> Any: return NotImplemented
275
+ def __rmul__(self, other: Any) -> Any: return NotImplemented
276
+ def __truediv__(self, other: Any) -> Any: return NotImplemented
277
+ def __rtruediv__(self, other: Any) -> Any: return NotImplemented
278
+ def __floordiv__(self, other: Any) -> Any: return NotImplemented
279
+ def __rfloordiv__(self, other: Any) -> Any: return NotImplemented
280
+ def __mod__(self, other: Any) -> Any: return NotImplemented
281
+ def __rmod__(self, other: Any) -> Any: return NotImplemented
282
+ def __pow__(self, other: Any) -> Any: return NotImplemented
283
+ def __rpow__(self, other: Any) -> Any: return NotImplemented
284
+ def __neg__(self) -> Any: return NotImplemented
285
+ def __pos__(self) -> Any: return NotImplemented
286
+ def __abs__(self) -> Any: return NotImplemented
287
+ def __lt__(self, other: Any) -> bool: return NotImplemented # type: ignore[return-value]
288
+ def __le__(self, other: Any) -> bool: return NotImplemented # type: ignore[return-value]
289
+ def __gt__(self, other: Any) -> bool: return NotImplemented # type: ignore[return-value]
290
+ def __ge__(self, other: Any) -> bool: return NotImplemented # type: ignore[return-value]
291
+ def __contains__(self, item: Any) -> bool: return NotImplemented # type: ignore[return-value]
292
+ def __iter__(self) -> Any: return NotImplemented
293
+ def __len__(self) -> int: return NotImplemented # type: ignore[return-value]
294
+ def __getitem__(self, key: Any) -> Any: return NotImplemented
295
+ def __and__(self, other: Any) -> Any: return NotImplemented
296
+ def __or__(self, other: Any) -> Any: return NotImplemented
297
+ def __xor__(self, other: Any) -> Any: return NotImplemented
298
+ def __invert__(self) -> Any: return NotImplemented
299
+ def __int__(self) -> int: raise TypeError("cannot convert Namespace to int")
300
+ def __float__(self) -> float: raise TypeError("cannot convert Namespace to float")
301
+
268
302
  def namespace(self, name: str) -> "_Namespace":
269
303
  """Return a nested sub-namespace."""
270
304
  with self._root._lock:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PersistentObjects
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: JSON-backed attribute-persistent object with namespace support
5
5
  Author: Tornado300
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "PersistentObjects"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "JSON-backed attribute-persistent object with namespace support"
9
9
  authors = [
10
10
  { name="Tornado300" }