fastquadtree 1.2.3__cp38-abi3-win_amd64.whl → 1.3.0__cp38-abi3-win_amd64.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.

Potentially problematic release.


This version of fastquadtree might be problematic. Click here for more details.

@@ -48,6 +48,7 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
48
48
  "_bounds",
49
49
  "_capacity",
50
50
  "_count",
51
+ "_dtype",
51
52
  "_max_depth",
52
53
  "_native",
53
54
  "_next_id",
@@ -62,7 +63,7 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
62
63
  """Create the native engine instance."""
63
64
 
64
65
  @classmethod
65
- def _new_native_from_bytes(cls, data: bytes) -> Any:
66
+ def _new_native_from_bytes(cls, data: bytes, dtype: str) -> Any:
66
67
  """Create the native engine instance from serialized bytes."""
67
68
 
68
69
  @staticmethod
@@ -79,10 +80,12 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
79
80
  *,
80
81
  max_depth: int | None = None,
81
82
  track_objects: bool = False,
83
+ dtype: str = "f32",
82
84
  ):
83
85
  self._bounds = bounds
84
86
  self._max_depth = max_depth
85
87
  self._capacity = capacity
88
+ self._dtype = dtype
86
89
  self._native = self._new_native(bounds, capacity, max_depth)
87
90
 
88
91
  self._track_objects = bool(track_objects)
@@ -138,12 +141,13 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
138
141
  return pickle.dumps(self.to_dict())
139
142
 
140
143
  @classmethod
141
- def from_bytes(cls, data: bytes) -> Self:
144
+ def from_bytes(cls, data: bytes, dtype: str = "f32") -> Self:
142
145
  """
143
- Deserialize a quadtree from bytes.
146
+ Deserialize a quadtree from bytes. Specifiy the dtype if the original tree that was serialized used a non-default dtype.
144
147
 
145
148
  Args:
146
149
  data: Bytes representing the serialized quadtree from `to_bytes()`.
150
+ dtype: The data type used in the native engine ('f32', 'f64', 'i32', 'i64') when saved to bytes.
147
151
 
148
152
  Returns:
149
153
  A new quadtree instance with the same state as when serialized.
@@ -160,7 +164,15 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
160
164
  store_dict = in_dict["store"]
161
165
 
162
166
  qt = cls.__new__(cls) # type: ignore[call-arg]
163
- qt._native = cls._new_native_from_bytes(core_bytes)
167
+ try:
168
+ qt._native = cls._new_native_from_bytes(core_bytes, dtype=dtype)
169
+ except ValueError as ve:
170
+ raise ValueError(
171
+ "Failed to deserialize quadtree native core. "
172
+ "This may be due to a dtype mismatch. "
173
+ "Ensure the dtype used in from_bytes() matches the original tree. "
174
+ "Error details: " + str(ve)
175
+ ) from ve
164
176
 
165
177
  if store_dict is not None:
166
178
  qt._store = ObjStore.from_dict(store_dict, qt._make_item)
fastquadtree/_native.pyd CHANGED
Binary file
@@ -5,10 +5,17 @@ from typing import Any, Literal, Tuple, overload
5
5
 
6
6
  from ._base_quadtree import Bounds, _BaseQuadTree
7
7
  from ._item import Point, PointItem
8
- from ._native import QuadTree as _RustQuadTree # native point tree
8
+ from ._native import QuadTree as QuadTreeF32, QuadTreeF64, QuadTreeI32, QuadTreeI64
9
9
 
10
10
  _IdCoord = Tuple[int, float, float]
11
11
 
12
+ DTYPE_MAP = {
13
+ "f32": QuadTreeF32,
14
+ "f64": QuadTreeF64,
15
+ "i32": QuadTreeI32,
16
+ "i64": QuadTreeI64,
17
+ }
18
+
12
19
 
13
20
  class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
14
21
  """
@@ -29,6 +36,7 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
29
36
  capacity: Max number of points per node before splitting.
30
37
  max_depth: Optional max tree depth. If omitted, engine decides.
31
38
  track_objects: Enable id <-> object mapping inside Python.
39
+ dtype: Data type for coordinates and ids in the native engine. Default is 'f32'. Options are 'f32', 'f64', 'i32', 'i64'.
32
40
 
33
41
  Raises:
34
42
  ValueError: If parameters are invalid or inserts are out of bounds.
@@ -41,12 +49,14 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
41
49
  *,
42
50
  max_depth: int | None = None,
43
51
  track_objects: bool = False,
52
+ dtype: str = "f32",
44
53
  ):
45
54
  super().__init__(
46
55
  bounds,
47
56
  capacity,
48
57
  max_depth=max_depth,
49
58
  track_objects=track_objects,
59
+ dtype=dtype,
50
60
  )
51
61
 
52
62
  @overload
@@ -148,14 +158,19 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
148
158
  return out
149
159
 
150
160
  def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
151
- if max_depth is None:
152
- return _RustQuadTree(bounds, capacity)
153
- return _RustQuadTree(bounds, capacity, max_depth=max_depth)
161
+ """Create the native engine instance."""
162
+ rust_cls = DTYPE_MAP.get(self._dtype)
163
+ if rust_cls is None:
164
+ raise ValueError(f"Unsupported dtype: {self._dtype}")
165
+ return rust_cls(bounds, capacity, max_depth)
154
166
 
155
167
  @classmethod
156
- def _new_native_from_bytes(cls, data: bytes) -> Any:
168
+ def _new_native_from_bytes(cls, data: bytes, dtype: str = "f32") -> Any:
157
169
  """Create a new native engine instance from serialized bytes."""
158
- return _RustQuadTree.from_bytes(data)
170
+ rust_cls = DTYPE_MAP.get(dtype)
171
+ if rust_cls is None:
172
+ raise ValueError(f"Unsupported dtype: {dtype}")
173
+ return rust_cls.from_bytes(data)
159
174
 
160
175
  @staticmethod
161
176
  def _make_item(id_: int, geom: Point, obj: Any | None) -> PointItem:
@@ -5,10 +5,21 @@ from typing import Any, Literal, Tuple, overload
5
5
 
6
6
  from ._base_quadtree import Bounds, _BaseQuadTree
7
7
  from ._item import RectItem
8
- from ._native import RectQuadTree as _RustRectQuadTree # native rect tree
8
+ from ._native import (
9
+ RectQuadTree as RectQuadTreeF32,
10
+ RectQuadTreeF64,
11
+ RectQuadTreeI32,
12
+ RectQuadTreeI64,
13
+ )
9
14
 
10
15
  _IdRect = Tuple[int, float, float, float, float]
11
- Point = Tuple[float, float] # only for type hints in docstrings
16
+
17
+ DTYPE_MAP = {
18
+ "f32": RectQuadTreeF32,
19
+ "f64": RectQuadTreeF64,
20
+ "i32": RectQuadTreeI32,
21
+ "i64": RectQuadTreeI64,
22
+ }
12
23
 
13
24
 
14
25
  class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
@@ -30,6 +41,7 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
30
41
  capacity: Max number of points per node before splitting.
31
42
  max_depth: Optional max tree depth. If omitted, engine decides.
32
43
  track_objects: Enable id <-> object mapping inside Python.
44
+ dtype: Data type for coordinates and ids in the native engine. Default is 'f32'. Options are 'f32', 'f64', 'i32', 'i64'.
33
45
 
34
46
  Raises:
35
47
  ValueError: If parameters are invalid or inserts are out of bounds.
@@ -42,12 +54,14 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
42
54
  *,
43
55
  max_depth: int | None = None,
44
56
  track_objects: bool = False,
57
+ dtype: str = "f32",
45
58
  ):
46
59
  super().__init__(
47
60
  bounds,
48
61
  capacity,
49
62
  max_depth=max_depth,
50
63
  track_objects=track_objects,
64
+ dtype=dtype,
51
65
  )
52
66
 
53
67
  @overload
@@ -84,14 +98,19 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
84
98
  return self._store.get_many_by_ids(self._native.query_ids(rect))
85
99
 
86
100
  def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
87
- if max_depth is None:
88
- return _RustRectQuadTree(bounds, capacity)
89
- return _RustRectQuadTree(bounds, capacity, max_depth=max_depth)
101
+ """Create the native engine instance."""
102
+ rust_cls = DTYPE_MAP.get(self._dtype)
103
+ if rust_cls is None:
104
+ raise ValueError(f"Unsupported dtype: {self._dtype}")
105
+ return rust_cls(bounds, capacity, max_depth)
90
106
 
91
107
  @classmethod
92
- def _new_native_from_bytes(cls, data: bytes) -> Any:
108
+ def _new_native_from_bytes(cls, data: bytes, dtype: str = "f32") -> Any:
93
109
  """Create a new native engine instance from serialized bytes."""
94
- return _RustRectQuadTree.from_bytes(data)
110
+ rust_cls = DTYPE_MAP.get(dtype)
111
+ if rust_cls is None:
112
+ raise ValueError(f"Unsupported dtype: {dtype}")
113
+ return rust_cls.from_bytes(data)
95
114
 
96
115
  @staticmethod
97
116
  def _make_item(id_: int, geom: Bounds, obj: Any | None) -> RectItem:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastquadtree
3
- Version: 1.2.3
3
+ Version: 1.3.0
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3 :: Only
6
6
  Classifier: Programming Language :: Rust
@@ -26,6 +26,7 @@ Requires-Dist: mkdocs-minify-plugin ; extra == 'dev'
26
26
  Requires-Dist: maturin>=1.5 ; extra == 'dev'
27
27
  Requires-Dist: pyqtree==1.0.0 ; extra == 'dev'
28
28
  Requires-Dist: numpy ; extra == 'dev'
29
+ Requires-Dist: pre-commit ; extra == 'dev'
29
30
  Provides-Extra: dev
30
31
  License-File: LICENSE
31
32
  Summary: Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search.
@@ -73,6 +74,7 @@ Rust-optimized quadtree with a clean Python API
73
74
  - Fast KNN and range queries
74
75
  - Optional object tracking for id ↔ object mapping
75
76
  - Fast [serialization](https://elan456.github.io/fastquadtree/benchmark/#serialization-vs-rebuild) to/from bytes
77
+ - Support for multiple data types (f32, f64, i32, i64) for coordinates
76
78
  - [100% test coverage](https://codecov.io/gh/Elan456/fastquadtree) and CI on GitHub Actions
77
79
  - Offers a drop-in [pyqtree shim](https://elan456.github.io/fastquadtree/benchmark/#pyqtree-drop-in-shim-performance-gains) that is 6.567x faster while keeping the same API
78
80
 
@@ -0,0 +1,13 @@
1
+ fastquadtree-1.3.0.dist-info/METADATA,sha256=_I1G4rPdB-3ZjizUq7MhU9WKQKoquKoNOS_mTPvYeeM,9908
2
+ fastquadtree-1.3.0.dist-info/WHEEL,sha256=CG8OzNtm0LMpJ2zhrjswlO8N-965OeMLklsQAG-nMvQ,94
3
+ fastquadtree-1.3.0.dist-info/licenses/LICENSE,sha256=46IVFhoCIwMo-ocq4olyEB1eBvvtaKic5yGLeKXnDuc,1092
4
+ fastquadtree/__init__.py,sha256=jy7uimnd7QDllmNOgnRByKom1aONIKOWhCvCJxndsnM,200
5
+ fastquadtree/_base_quadtree.py,sha256=GCFn8YR-ViB0n1n8vYzcy15iDUR7D2HzRqp1uPHn9NE,16426
6
+ fastquadtree/_item.py,sha256=hlA71tvmLUQey42VokaZ7AmorIA8yZoGlvZWW9G4l4k,2496
7
+ fastquadtree/_native.pyd,sha256=kPC2Er1AMbJohtS9S4nq5738BxmSead-2szXN96Svlk,548352
8
+ fastquadtree/_obj_store.py,sha256=e164LT01nU5KqPX0udMzcJtpONAohDMEw-c9zEqh7uo,6723
9
+ fastquadtree/point_quadtree.py,sha256=8BDH4RNspH4Y-Vz9PSQH3y_Z4z5Oq5Cmcq9xnwVV6nk,6358
10
+ fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ fastquadtree/pyqtree.py,sha256=Evu-MKHKrs_xNVWChukD4hJLyIc-u7iuQ4hA_zvJtu4,6246
12
+ fastquadtree/rect_quadtree.py,sha256=-R0eLbjnGsPPfj5v2vDjdSIzGcmNcX9tVFDkd6J8Iqo,4121
13
+ fastquadtree-1.3.0.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- fastquadtree-1.2.3.dist-info/METADATA,sha256=_fEVrhcT8naqmksDN1xcWbxWuhsAZayCOoZuQexLg-g,9793
2
- fastquadtree-1.2.3.dist-info/WHEEL,sha256=CG8OzNtm0LMpJ2zhrjswlO8N-965OeMLklsQAG-nMvQ,94
3
- fastquadtree-1.2.3.dist-info/licenses/LICENSE,sha256=46IVFhoCIwMo-ocq4olyEB1eBvvtaKic5yGLeKXnDuc,1092
4
- fastquadtree/__init__.py,sha256=jy7uimnd7QDllmNOgnRByKom1aONIKOWhCvCJxndsnM,200
5
- fastquadtree/_base_quadtree.py,sha256=2y80MqTbY8oFQtsWPlWjwgsqSeN1x5lZJ6s47cBDcQ8,15751
6
- fastquadtree/_item.py,sha256=hlA71tvmLUQey42VokaZ7AmorIA8yZoGlvZWW9G4l4k,2496
7
- fastquadtree/_native.pyd,sha256=BOzIkWmmPtWIJdH-NYtTqi6gPGEOO-KpDRTEfcTG0Hc,338944
8
- fastquadtree/_obj_store.py,sha256=e164LT01nU5KqPX0udMzcJtpONAohDMEw-c9zEqh7uo,6723
9
- fastquadtree/point_quadtree.py,sha256=t0qiKMCCmmlvVVEIsouj3L-yixHdUbnQgVs8wFODrdA,5794
10
- fastquadtree/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- fastquadtree/pyqtree.py,sha256=Evu-MKHKrs_xNVWChukD4hJLyIc-u7iuQ4hA_zvJtu4,6246
12
- fastquadtree/rect_quadtree.py,sha256=JN_2j3DfSENnKha7mJOE7l98S1aKrywJg8PVCZdNA6E,3580
13
- fastquadtree-1.2.3.dist-info/RECORD,,