plexus-python-common 1.0.48__tar.gz → 1.0.49__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.
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/PKG-INFO +1 -1
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/tagutils.py +95 -27
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/PKG-INFO +1 -1
- plexus_python_common-1.0.49/test/plexus_tests/common/utils/tagutils_test.py +104 -0
- plexus_python_common-1.0.48/test/plexus_tests/common/utils/tagutils_test.py +0 -94
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/.editorconfig +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/.github/workflows/pr.yml +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/.github/workflows/push.yml +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/.gitignore +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/MANIFEST.in +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/README.md +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/VERSION +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/pyproject.toml +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/0-dummy +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/1-dummy +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/2-dummy +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.0.0.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.0.0.vol-0.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.1.1.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.1.1.vol-1.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.2.2.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.2.2.vol-2.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.csv.part0 +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.csv.part1 +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.csv.part2 +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.txt +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/file.bar +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/file.baz +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/file.foo +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils_archive/archive.compressed.zip +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/s3utils_archive/archive.uncompressed.zip +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/setup.cfg +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/setup.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMFile.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMNode.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMTags.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMWay.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/pose.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/proj.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/resources/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/resources/tags/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/resources/tags/universal.tagset.yaml +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/apiutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/bagutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/config.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/datautils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/dockerutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/jsonutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/ormutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/pathutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/s3utils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/sqlutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/strutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/testutils.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/SOURCES.txt +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/requires.txt +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/top_level.txt +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/pose_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/proj_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/datautils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/dockerutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/ormutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/pathutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/s3utils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/strutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/testutils_test.py +0 -0
- {plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/testenv.py +0 -0
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/tagutils.py
RENAMED
|
@@ -36,6 +36,7 @@ __all__ = [
|
|
|
36
36
|
"RichDesc",
|
|
37
37
|
"Tag",
|
|
38
38
|
"Tagset",
|
|
39
|
+
"MutableTagset",
|
|
39
40
|
"populate_tagset",
|
|
40
41
|
"predefined_tagsets",
|
|
41
42
|
"render_tagset_markdown_readme",
|
|
@@ -132,8 +133,13 @@ class Tag(object):
|
|
|
132
133
|
def parent_tag_name(self) -> str | None:
|
|
133
134
|
return head_or_none(self.name.rsplit(":", 1))
|
|
134
135
|
|
|
135
|
-
def populate(
|
|
136
|
-
|
|
136
|
+
def populate(
|
|
137
|
+
self,
|
|
138
|
+
vehicle_name: str,
|
|
139
|
+
begin_dt: datetime.datetime,
|
|
140
|
+
end_dt: datetime.datetime,
|
|
141
|
+
props: JsonType,
|
|
142
|
+
) -> TagRecord:
|
|
137
143
|
return TagRecord(
|
|
138
144
|
vehicle_name=vehicle_name,
|
|
139
145
|
begin_dt=begin_dt,
|
|
@@ -175,11 +181,49 @@ class Tagset(Sequence[Tag], Mapping[str, Tag]):
|
|
|
175
181
|
tag_name = item.name if isinstance(item, Tag) else item
|
|
176
182
|
return self.tags_dict.get(tag_name)
|
|
177
183
|
|
|
184
|
+
def clone(self) -> Self:
|
|
185
|
+
return clone_tagset(self)
|
|
186
|
+
|
|
187
|
+
def mutable(self):
|
|
188
|
+
return clone_mutable_tagset(self)
|
|
189
|
+
|
|
190
|
+
def frozen(self):
|
|
191
|
+
return self.clone()
|
|
192
|
+
|
|
178
193
|
@property
|
|
179
194
|
def tag_names(self) -> list[str]:
|
|
180
195
|
return list(self.tags_dict.keys())
|
|
181
196
|
|
|
182
|
-
def
|
|
197
|
+
def child_tags(self, parent: str | Tag) -> list[Tag]:
|
|
198
|
+
if parent is None:
|
|
199
|
+
return []
|
|
200
|
+
if isinstance(parent, str):
|
|
201
|
+
return self.child_tags(self.get(parent))
|
|
202
|
+
|
|
203
|
+
subtree = dicttree_subtree(self.tags_tree, parent.tag_parts)
|
|
204
|
+
return list(dicttree_children(subtree)) if subtree else []
|
|
205
|
+
|
|
206
|
+
def parent_tags(self, child: str | Tag) -> list[Tag]:
|
|
207
|
+
if child is None:
|
|
208
|
+
return []
|
|
209
|
+
if isinstance(child, str):
|
|
210
|
+
return self.parent_tags(self.get(child))
|
|
211
|
+
|
|
212
|
+
return list(dicttree_lineage(self.tags_tree, child.tag_parts[:-1]))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class MutableTagset(Tagset):
|
|
216
|
+
|
|
217
|
+
def clone(self) -> Self:
|
|
218
|
+
return clone_mutable_tagset(self)
|
|
219
|
+
|
|
220
|
+
def mutable(self):
|
|
221
|
+
return self.clone()
|
|
222
|
+
|
|
223
|
+
def frozen(self):
|
|
224
|
+
return clone_tagset(self)
|
|
225
|
+
|
|
226
|
+
def add(self, tag: Tag) -> Self:
|
|
183
227
|
if tag.name in self.tags_dict:
|
|
184
228
|
raise ValueError(f"duplicate tag name '{tag.name}'")
|
|
185
229
|
|
|
@@ -188,7 +232,9 @@ class Tagset(Sequence[Tag], Mapping[str, Tag]):
|
|
|
188
232
|
|
|
189
233
|
dicttree_add(self.tags_tree, tag.tag_parts, tag, create_prefix=True)
|
|
190
234
|
|
|
191
|
-
|
|
235
|
+
return self
|
|
236
|
+
|
|
237
|
+
def remove(self, tag_name: str) -> Self:
|
|
192
238
|
tag = self.get(tag_name)
|
|
193
239
|
if tag is None:
|
|
194
240
|
raise ValueError(f"tag '{tag_name}' not found")
|
|
@@ -198,22 +244,23 @@ class Tagset(Sequence[Tag], Mapping[str, Tag]):
|
|
|
198
244
|
|
|
199
245
|
dicttree_remove(self.tags_tree, tag.tag_parts, recursive=True)
|
|
200
246
|
|
|
201
|
-
|
|
202
|
-
if parent is None:
|
|
203
|
-
return []
|
|
204
|
-
if isinstance(parent, str):
|
|
205
|
-
return self.child_tags(self.get(parent))
|
|
247
|
+
return self
|
|
206
248
|
|
|
207
|
-
subtree = dicttree_subtree(self.tags_tree, parent.tag_parts)
|
|
208
|
-
return list(dicttree_children(subtree)) if subtree else []
|
|
209
249
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
250
|
+
def clone_tagset(tagset: Tagset) -> Tagset:
|
|
251
|
+
tagset = clone_mutable_tagset(tagset)
|
|
252
|
+
new_tagset = Tagset(namespace=tagset.namespace, desc=tagset.desc)
|
|
253
|
+
new_tagset.tags = tagset.tags
|
|
254
|
+
new_tagset.tags_dict = tagset.tags_dict
|
|
255
|
+
new_tagset.tags_tree = tagset.tags_tree
|
|
256
|
+
return new_tagset
|
|
215
257
|
|
|
216
|
-
|
|
258
|
+
|
|
259
|
+
def clone_mutable_tagset(tagset: Tagset) -> MutableTagset:
|
|
260
|
+
new_tagset = MutableTagset(namespace=tagset.namespace, desc=tagset.desc)
|
|
261
|
+
for tag in tagset.tags:
|
|
262
|
+
new_tagset.add(tag)
|
|
263
|
+
return new_tagset
|
|
217
264
|
|
|
218
265
|
|
|
219
266
|
def populate_tagset(tagset_spec: JsonObject) -> Tagset:
|
|
@@ -268,12 +315,12 @@ def populate_tagset(tagset_spec: JsonObject) -> Tagset:
|
|
|
268
315
|
if tags is None:
|
|
269
316
|
raise ValueError("missing '$tags' in tagset spec")
|
|
270
317
|
|
|
271
|
-
tagset =
|
|
318
|
+
tagset = MutableTagset(namespace=namespace, desc=desc)
|
|
272
319
|
|
|
273
320
|
for tag in validate_and_collect("", tags):
|
|
274
321
|
tagset.add(tag)
|
|
275
322
|
|
|
276
|
-
return tagset
|
|
323
|
+
return tagset.frozen()
|
|
277
324
|
|
|
278
325
|
|
|
279
326
|
@singleton
|
|
@@ -330,25 +377,34 @@ def tag_cache_file_path() -> pathlib.Path:
|
|
|
330
377
|
|
|
331
378
|
|
|
332
379
|
class TagCache(object):
|
|
333
|
-
def __init__(
|
|
380
|
+
def __init__(
|
|
381
|
+
self,
|
|
382
|
+
*,
|
|
383
|
+
file_path: str | os.PathLike[str] | None = None,
|
|
384
|
+
fail_if_exists: bool = False,
|
|
385
|
+
):
|
|
334
386
|
self.file_path = pathlib.Path(file_path or tag_cache_file_path())
|
|
335
387
|
if fail_if_exists and self.file_path.exists():
|
|
336
388
|
raise FileExistsError(f"tag cache file '{str(self.file_path)}' already exists")
|
|
337
389
|
self.file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
390
|
+
|
|
338
391
|
self.conn_maker = ConnectionMaker.from_url(f"sqlite:///{str(self.file_path.absolute())}",
|
|
339
392
|
engine_opts=dict(connect_args={"check_same_thread": False}))
|
|
340
393
|
BaseModel.metadata.create_all(self.conn_maker.engine)
|
|
341
394
|
|
|
342
395
|
def query(
|
|
343
396
|
self,
|
|
344
|
-
vehicle_name: str,
|
|
397
|
+
vehicle_name: str | None = None,
|
|
345
398
|
begin_time: datetime.datetime | None = None,
|
|
346
399
|
end_time: datetime.datetime | None = None,
|
|
347
400
|
tag_pattern: str | None = None,
|
|
348
|
-
|
|
401
|
+
*,
|
|
402
|
+
tagsets: Sequence[Tagset] | None = None,
|
|
403
|
+
) -> Generator[TagRecordTable]:
|
|
349
404
|
with self.conn_maker.make_session() as session:
|
|
350
|
-
query = session.query(TagRecordTable)
|
|
351
|
-
|
|
405
|
+
query = session.query(TagRecordTable)
|
|
406
|
+
if vehicle_name:
|
|
407
|
+
query = query.filter(TagRecordTable.vehicle_name == vehicle_name)
|
|
352
408
|
if begin_time:
|
|
353
409
|
query = query.filter(TagRecordTable.end_dt >= begin_time)
|
|
354
410
|
if end_time:
|
|
@@ -356,7 +412,15 @@ class TagCache(object):
|
|
|
356
412
|
if tag_pattern:
|
|
357
413
|
query = query.filter(TagRecordTable.tag.like(f"{escape_sql_like(tag_pattern)}%", escape="\\"))
|
|
358
414
|
|
|
359
|
-
|
|
415
|
+
if not tagsets:
|
|
416
|
+
yield from query.all()
|
|
417
|
+
else:
|
|
418
|
+
yield from (db_tag_record for db_tag_record in query.all()
|
|
419
|
+
if any(db_tag_record.tag in tagset for tagset in tagsets))
|
|
420
|
+
|
|
421
|
+
def undefined(self, tagsets: Sequence[Tagset]) -> Generator[TagRecordTable, None, None]:
|
|
422
|
+
yield from (db_tag_record for db_tag_record in self.query()
|
|
423
|
+
if all(db_tag_record.tag not in tagset for tagset in tagsets))
|
|
360
424
|
|
|
361
425
|
def add(
|
|
362
426
|
self,
|
|
@@ -365,7 +429,7 @@ class TagCache(object):
|
|
|
365
429
|
end_time: datetime.datetime,
|
|
366
430
|
tag: str | Tag,
|
|
367
431
|
props: JsonType | None = None,
|
|
368
|
-
):
|
|
432
|
+
) -> Self:
|
|
369
433
|
with self.conn_maker.make_session() as session:
|
|
370
434
|
tag_record = TagRecord(
|
|
371
435
|
vehicle_name=vehicle_name,
|
|
@@ -377,7 +441,9 @@ class TagCache(object):
|
|
|
377
441
|
session.add(clone_sequence_model_instance(TagRecordTable, tag_record))
|
|
378
442
|
session.commit()
|
|
379
443
|
|
|
380
|
-
|
|
444
|
+
return self
|
|
445
|
+
|
|
446
|
+
def remove(self, vehicle_name: str, begin_time: datetime.datetime, end_time: datetime.datetime) -> Self:
|
|
381
447
|
with self.conn_maker.make_session() as session:
|
|
382
448
|
session.execute(
|
|
383
449
|
sa
|
|
@@ -390,6 +456,8 @@ class TagCache(object):
|
|
|
390
456
|
)
|
|
391
457
|
session.commit()
|
|
392
458
|
|
|
459
|
+
return self
|
|
460
|
+
|
|
393
461
|
def clear(self):
|
|
394
462
|
with self.conn_maker.make_session() as session:
|
|
395
463
|
session.execute(sa.delete(TagRecordTable))
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
import ddt
|
|
5
|
+
from iker.common.utils.dtutils import dt_parse_iso
|
|
6
|
+
|
|
7
|
+
from plexus.common.utils.tagutils import MutableTagset, Tag, TagCache, Tagset
|
|
8
|
+
from plexus.common.utils.tagutils import predefined_tagsets, render_tagset_markdown_readme
|
|
9
|
+
from plexus.common.utils.tagutils import tag_cache_file_path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@ddt.ddt
|
|
13
|
+
class TagUtilsTest(unittest.TestCase):
|
|
14
|
+
|
|
15
|
+
def test_predefined_tagsets(self):
|
|
16
|
+
tagsets = predefined_tagsets()
|
|
17
|
+
for _, tagset in tagsets.items():
|
|
18
|
+
self.assertIsInstance(tagset, Tagset)
|
|
19
|
+
self.assertNotIsInstance(tagset, MutableTagset)
|
|
20
|
+
|
|
21
|
+
for tag in tagset:
|
|
22
|
+
self.assertIn(tag, tagset)
|
|
23
|
+
self.assertIn(tag.name, tagset)
|
|
24
|
+
self.assertEqual(tag, tagset.get(tag))
|
|
25
|
+
self.assertEqual(tag, tagset.get(tag.name))
|
|
26
|
+
|
|
27
|
+
markdown = render_tagset_markdown_readme(tagset)
|
|
28
|
+
self.assertIsInstance(markdown, str)
|
|
29
|
+
|
|
30
|
+
print(markdown)
|
|
31
|
+
|
|
32
|
+
def test_tag_cache(self):
|
|
33
|
+
tag_cache = TagCache()
|
|
34
|
+
|
|
35
|
+
self.assertEqual(tag_cache.file_path, tag_cache_file_path())
|
|
36
|
+
self.assertTrue(tag_cache.file_path.exists())
|
|
37
|
+
|
|
38
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle"))), 0)
|
|
39
|
+
|
|
40
|
+
tagset = MutableTagset(namespace="tagset", desc="A dummy tagset for testing")
|
|
41
|
+
|
|
42
|
+
tagset.add(Tag(name="dummy:foo", desc="A dummy tag for testing"))
|
|
43
|
+
tagset.add(Tag(name="dummy:bar", desc="A dummy tag for testing"))
|
|
44
|
+
|
|
45
|
+
tags = [
|
|
46
|
+
"dummy:foo",
|
|
47
|
+
"dummy:bar",
|
|
48
|
+
"dummy:baz",
|
|
49
|
+
"dummy:qux",
|
|
50
|
+
]
|
|
51
|
+
for i in range(1000):
|
|
52
|
+
tag_cache.add(
|
|
53
|
+
"dummy_vehicle",
|
|
54
|
+
dt_parse_iso("2020-01-01T00:00:00.000000+00:00") + datetime.timedelta(seconds=i),
|
|
55
|
+
dt_parse_iso("2021-01-01T00:00:00.000000+00:00") + datetime.timedelta(seconds=i + 1),
|
|
56
|
+
tags[i % len(tags)],
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
self.assertEqual(len(list(tag_cache.query())), 1000)
|
|
60
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle"))), 1000)
|
|
61
|
+
self.assertEqual(len(list(tag_cache.query(tagsets=[tagset]))), 500)
|
|
62
|
+
self.assertEqual(
|
|
63
|
+
len(list(tag_cache.query("dummy_vehicle",
|
|
64
|
+
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
65
|
+
dt_parse_iso("2020-01-01T00:01:00.000000+00:00")))),
|
|
66
|
+
61,
|
|
67
|
+
)
|
|
68
|
+
self.assertEqual(
|
|
69
|
+
len(list(tag_cache.query("dummy_vehicle",
|
|
70
|
+
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
71
|
+
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"),
|
|
72
|
+
tag_pattern="dummy:foo"))),
|
|
73
|
+
16,
|
|
74
|
+
)
|
|
75
|
+
self.assertEqual(
|
|
76
|
+
len(list(tag_cache.query("dummy_vehicle",
|
|
77
|
+
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
78
|
+
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"),
|
|
79
|
+
tag_pattern="dummy:bar"))),
|
|
80
|
+
15,
|
|
81
|
+
)
|
|
82
|
+
self.assertEqual(
|
|
83
|
+
len(list(tag_cache.query("dummy_vehicle",
|
|
84
|
+
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
85
|
+
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"),
|
|
86
|
+
tag_pattern="dummy"))),
|
|
87
|
+
61,
|
|
88
|
+
)
|
|
89
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle", tag_pattern="dummy:foo"))), 250)
|
|
90
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle", tag_pattern="dummy:bar"))), 250)
|
|
91
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle", tag_pattern="dummy"))), 1000)
|
|
92
|
+
self.assertEqual(len(list(tag_cache.query("another_dummy_vehicle"))), 0)
|
|
93
|
+
|
|
94
|
+
self.assertEqual(len(list(tag_cache.undefined([tagset]))), 500)
|
|
95
|
+
|
|
96
|
+
tag_cache.remove("dummy_vehicle",
|
|
97
|
+
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
98
|
+
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"))
|
|
99
|
+
|
|
100
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle"))), 939)
|
|
101
|
+
|
|
102
|
+
tag_cache.clear()
|
|
103
|
+
|
|
104
|
+
self.assertEqual(len(list(tag_cache.query("dummy_vehicle"))), 0)
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
import unittest
|
|
3
|
-
|
|
4
|
-
import ddt
|
|
5
|
-
from iker.common.utils.dtutils import dt_parse_iso
|
|
6
|
-
|
|
7
|
-
from plexus.common.utils.tagutils import TagCache, Tagset
|
|
8
|
-
from plexus.common.utils.tagutils import predefined_tagsets, render_tagset_markdown_readme
|
|
9
|
-
from plexus.common.utils.tagutils import tag_cache_file_path
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@ddt.ddt
|
|
13
|
-
class TagUtilsTest(unittest.TestCase):
|
|
14
|
-
|
|
15
|
-
def test_predefined_tagsets(self):
|
|
16
|
-
tagsets = predefined_tagsets()
|
|
17
|
-
for _, tagset in tagsets.items():
|
|
18
|
-
self.assertIsInstance(tagset, Tagset)
|
|
19
|
-
|
|
20
|
-
for tag in tagset:
|
|
21
|
-
self.assertIn(tag, tagset)
|
|
22
|
-
self.assertIn(tag.name, tagset)
|
|
23
|
-
self.assertEqual(tag, tagset.get(tag))
|
|
24
|
-
self.assertEqual(tag, tagset.get(tag.name))
|
|
25
|
-
|
|
26
|
-
markdown = render_tagset_markdown_readme(tagset)
|
|
27
|
-
self.assertIsInstance(markdown, str)
|
|
28
|
-
|
|
29
|
-
print(markdown)
|
|
30
|
-
|
|
31
|
-
def test_tag_cache(self):
|
|
32
|
-
tag_cache = TagCache()
|
|
33
|
-
|
|
34
|
-
self.assertEqual(tag_cache.file_path, tag_cache_file_path())
|
|
35
|
-
self.assertTrue(tag_cache.file_path.exists())
|
|
36
|
-
|
|
37
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle")), 0)
|
|
38
|
-
|
|
39
|
-
tags = [
|
|
40
|
-
"dummy:foo",
|
|
41
|
-
"dummy:bar",
|
|
42
|
-
"dummy:baz",
|
|
43
|
-
"dummy:qux",
|
|
44
|
-
]
|
|
45
|
-
for i in range(1000):
|
|
46
|
-
tag_cache.add(
|
|
47
|
-
"dummy_vehicle",
|
|
48
|
-
dt_parse_iso("2020-01-01T00:00:00.000000+00:00") + datetime.timedelta(seconds=i),
|
|
49
|
-
dt_parse_iso("2021-01-01T00:00:00.000000+00:00") + datetime.timedelta(seconds=i + 1),
|
|
50
|
-
tags[i % len(tags)],
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle")), 1000)
|
|
54
|
-
self.assertEqual(
|
|
55
|
-
len(tag_cache.query("dummy_vehicle",
|
|
56
|
-
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
57
|
-
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"))),
|
|
58
|
-
61,
|
|
59
|
-
)
|
|
60
|
-
self.assertEqual(
|
|
61
|
-
len(tag_cache.query("dummy_vehicle",
|
|
62
|
-
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
63
|
-
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"),
|
|
64
|
-
tag_pattern="dummy:foo")),
|
|
65
|
-
16,
|
|
66
|
-
)
|
|
67
|
-
self.assertEqual(
|
|
68
|
-
len(tag_cache.query("dummy_vehicle",
|
|
69
|
-
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
70
|
-
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"),
|
|
71
|
-
tag_pattern="dummy:bar")),
|
|
72
|
-
15,
|
|
73
|
-
)
|
|
74
|
-
self.assertEqual(
|
|
75
|
-
len(tag_cache.query("dummy_vehicle",
|
|
76
|
-
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
77
|
-
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"),
|
|
78
|
-
tag_pattern="dummy")),
|
|
79
|
-
61,
|
|
80
|
-
)
|
|
81
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle", tag_pattern="dummy:foo")), 250)
|
|
82
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle", tag_pattern="dummy:bar")), 250)
|
|
83
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle", tag_pattern="dummy")), 1000)
|
|
84
|
-
self.assertEqual(len(tag_cache.query("another_dummy_vehicle")), 0)
|
|
85
|
-
|
|
86
|
-
tag_cache.remove("dummy_vehicle",
|
|
87
|
-
dt_parse_iso("2020-01-01T00:00:00.000000+00:00"),
|
|
88
|
-
dt_parse_iso("2020-01-01T00:01:00.000000+00:00"))
|
|
89
|
-
|
|
90
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle")), 939)
|
|
91
|
-
|
|
92
|
-
tag_cache.clear()
|
|
93
|
-
|
|
94
|
-
self.assertEqual(len(tag_cache.query("dummy_vehicle")), 0)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/0-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/1-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/2-dummy
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMFile.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMNode.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMTags.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMWay.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/carto/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/resources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/__init__.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/apiutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/bagutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/config.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/datautils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/dockerutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/jsonutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/ormutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/pathutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/s3utils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/sqlutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/strutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/src/plexus/common/utils/testutils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/pose_test.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.48 → plexus_python_common-1.0.49}/test/plexus_tests/common/proj_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|