plexus-python-common 1.0.47__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.47 → plexus_python_common-1.0.49}/PKG-INFO +1 -1
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/ormutils.py +9 -9
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/s3utils.py +1 -1
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/tagutils.py +95 -27
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/PKG-INFO +1 -1
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/ormutils_test.py +83 -0
- plexus_python_common-1.0.49/test/plexus_tests/common/utils/tagutils_test.py +104 -0
- plexus_python_common-1.0.47/test/plexus_tests/common/utils/tagutils_test.py +0 -94
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/.editorconfig +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/.github/workflows/pr.yml +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/.github/workflows/push.yml +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/.gitignore +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/MANIFEST.in +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/README.md +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/VERSION +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/pyproject.toml +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/0-dummy +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/1-dummy +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/2-dummy +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.0.0.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.0.0.vol-0.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.1.1.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.1.1.vol-1.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.2.2.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.2.2.vol-2.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.csv.part0 +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.csv.part1 +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.csv.part2 +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/dummy.txt +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
- {plexus_python_common-1.0.47 → 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.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/file.bar +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/file.baz +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils/dir.foo/file.foo +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils_archive/archive.compressed.zip +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/s3utils_archive/archive.uncompressed.zip +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/setup.cfg +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/setup.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMFile.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMNode.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMTags.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMWay.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/pose.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/proj.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/resources/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/resources/tags/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/resources/tags/universal.tagset.yaml +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/apiutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/bagutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/config.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/datautils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/dockerutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/jsonutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/pathutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/sqlutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/strutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/testutils.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/SOURCES.txt +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/requires.txt +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus_python_common.egg-info/top_level.txt +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/pose_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/proj_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/datautils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/dockerutils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/pathutils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/s3utils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/strutils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/utils/testutils_test.py +0 -0
- {plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/test/testenv.py +0 -0
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/ormutils.py
RENAMED
|
@@ -1146,7 +1146,7 @@ def db_read_active_snapshot_model_of_record[SnapshotModelT: SnapshotModelMixin](
|
|
|
1146
1146
|
) -> SnapshotModelT:
|
|
1147
1147
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1148
1148
|
if db_instance is None:
|
|
1149
|
-
raise sa_exc.NoResultFound(f"
|
|
1149
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1150
1150
|
|
|
1151
1151
|
return db_instance
|
|
1152
1152
|
|
|
@@ -1218,7 +1218,7 @@ def db_update_snapshot_model[SnapshotModelT: SnapshotModelMixin](
|
|
|
1218
1218
|
) -> SnapshotModelT:
|
|
1219
1219
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1220
1220
|
if db_instance is None:
|
|
1221
|
-
raise sa_exc.NoResultFound(f"
|
|
1221
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1222
1222
|
|
|
1223
1223
|
db_instance.expired_at = updated_at
|
|
1224
1224
|
db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1247,7 +1247,7 @@ def db_expire_snapshot_model[SnapshotModelT: SnapshotModelMixin](
|
|
|
1247
1247
|
.one_or_none()
|
|
1248
1248
|
)
|
|
1249
1249
|
if db_instance is None:
|
|
1250
|
-
raise sa_exc.NoResultFound(f"
|
|
1250
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1251
1251
|
|
|
1252
1252
|
db_instance.expired_at = updated_at
|
|
1253
1253
|
db_instance = clone_snapshot_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1275,7 +1275,7 @@ def db_activate_snapshot_model[SnapshotModelT: SnapshotModelMixin](
|
|
|
1275
1275
|
.first()
|
|
1276
1276
|
)
|
|
1277
1277
|
if db_instance is None:
|
|
1278
|
-
raise sa_exc.NoResultFound(f"
|
|
1278
|
+
raise sa_exc.NoResultFound(f"expired '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1279
1279
|
|
|
1280
1280
|
db_new_instance = clone_snapshot_model_instance(model, db_instance)
|
|
1281
1281
|
db_new_instance.record_sqn = record_sqn
|
|
@@ -1371,7 +1371,7 @@ def db_read_active_revision_model_of_record[RevisionModelT: RevisionModelMixin](
|
|
|
1371
1371
|
) -> RevisionModelT:
|
|
1372
1372
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1373
1373
|
if db_instance is None:
|
|
1374
|
-
raise sa_exc.NoResultFound(f"
|
|
1374
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1375
1375
|
|
|
1376
1376
|
return db_instance
|
|
1377
1377
|
|
|
@@ -1443,7 +1443,7 @@ def db_update_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1443
1443
|
) -> RevisionModelT:
|
|
1444
1444
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1445
1445
|
if db_instance is None:
|
|
1446
|
-
raise sa_exc.NoResultFound(f"
|
|
1446
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1447
1447
|
|
|
1448
1448
|
db_instance.expired_at = updated_at
|
|
1449
1449
|
db_instance = clone_revision_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1474,7 +1474,7 @@ def db_expire_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1474
1474
|
.one_or_none()
|
|
1475
1475
|
)
|
|
1476
1476
|
if db_instance is None:
|
|
1477
|
-
raise sa_exc.NoResultFound(f"
|
|
1477
|
+
raise sa_exc.NoResultFound(f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1478
1478
|
|
|
1479
1479
|
db_instance.expired_at = updated_at
|
|
1480
1480
|
db_instance = clone_revision_model_instance(model, db_instance, clear_meta_fields=False, inplace=True)
|
|
@@ -1492,7 +1492,7 @@ def db_activate_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1492
1492
|
db_instance = db.query(model).where(model.record_sqn == record_sqn, model.expired_at.is_(None)).one_or_none()
|
|
1493
1493
|
if db_instance is not None:
|
|
1494
1494
|
raise sa_exc.MultipleResultsFound(
|
|
1495
|
-
f"
|
|
1495
|
+
f"active '{model_name_of(model)}' of specified record_sqn '{record_sqn}' already exists")
|
|
1496
1496
|
|
|
1497
1497
|
db_instance = (
|
|
1498
1498
|
db
|
|
@@ -1502,7 +1502,7 @@ def db_activate_revision_model[RevisionModelT: RevisionModelMixin](
|
|
|
1502
1502
|
.first()
|
|
1503
1503
|
)
|
|
1504
1504
|
if db_instance is None:
|
|
1505
|
-
raise sa_exc.NoResultFound(f"
|
|
1505
|
+
raise sa_exc.NoResultFound(f"expired '{model_name_of(model)}' of specified record_sqn '{record_sqn}' not found")
|
|
1506
1506
|
|
|
1507
1507
|
db_new_instance = clone_revision_model_instance(model, db_instance)
|
|
1508
1508
|
db_new_instance.record_sqn = record_sqn
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/s3utils.py
RENAMED
|
@@ -843,7 +843,7 @@ def s3_archive_open_members(
|
|
|
843
843
|
|
|
844
844
|
archive_size, member_zip_infos, missed_members = s3_archive_list_files(client, bucket, key, members)
|
|
845
845
|
if missed_members:
|
|
846
|
-
raise FileNotFoundError(f"
|
|
846
|
+
raise FileNotFoundError(f"archive members not found: {', '.join(missed_members)}")
|
|
847
847
|
|
|
848
848
|
if callable(use_ranged_requests):
|
|
849
849
|
use_ranged_requests = use_ranged_requests(archive_size, member_zip_infos)
|
{plexus_python_common-1.0.47 → 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))
|
|
@@ -30,9 +30,13 @@ from plexus.common.utils.ormutils import (
|
|
|
30
30
|
db_activate_revision_model,
|
|
31
31
|
db_activate_snapshot_model,
|
|
32
32
|
db_create_changing_model,
|
|
33
|
+
db_create_changing_models,
|
|
33
34
|
db_create_revision_model,
|
|
35
|
+
db_create_revision_models,
|
|
34
36
|
db_create_sequence_model,
|
|
37
|
+
db_create_sequence_models,
|
|
35
38
|
db_create_snapshot_model,
|
|
39
|
+
db_create_snapshot_models,
|
|
36
40
|
db_delete_sequence_model,
|
|
37
41
|
db_expire_revision_model,
|
|
38
42
|
db_expire_snapshot_model,
|
|
@@ -223,6 +227,21 @@ def test_db_sequence_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
223
227
|
results = db_read_sequence_models(session, DummySequenceModel, 0, 200)
|
|
224
228
|
assert len(results) == 0
|
|
225
229
|
|
|
230
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
231
|
+
|
|
232
|
+
results = db_create_sequence_models(session, DummySequenceModel, create_records)
|
|
233
|
+
assert len(results) == len(create_records)
|
|
234
|
+
|
|
235
|
+
for i, result in zip(range(0, 100), results):
|
|
236
|
+
assert result.sqn == i + 101
|
|
237
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
238
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
239
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
240
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
241
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
242
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
243
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
244
|
+
|
|
226
245
|
|
|
227
246
|
def test_db_changing_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
228
247
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -359,6 +378,26 @@ def test_db_changing_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
359
378
|
results = db_read_sequence_models(session, DummyChangingModel, 0, 200)
|
|
360
379
|
assert len(results) == 0
|
|
361
380
|
|
|
381
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
382
|
+
|
|
383
|
+
results = db_create_changing_models(session,
|
|
384
|
+
DummyChangingModel,
|
|
385
|
+
create_records,
|
|
386
|
+
dt_parse_iso("2024-01-01T00:00:00+00:00"))
|
|
387
|
+
assert len(results) == len(create_records)
|
|
388
|
+
|
|
389
|
+
for i, result in zip(range(0, 100), results):
|
|
390
|
+
assert result.sqn == i + 101
|
|
391
|
+
assert result.created_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
392
|
+
assert result.updated_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
393
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
394
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
395
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
396
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
397
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
398
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
399
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
400
|
+
|
|
362
401
|
|
|
363
402
|
def test_db_snapshot_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
364
403
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -644,6 +683,27 @@ def test_db_snapshot_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
644
683
|
assert result.dummy_array == update_records[i].dummy_array
|
|
645
684
|
assert result.dummy_json == update_records[i].dummy_json
|
|
646
685
|
|
|
686
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
687
|
+
|
|
688
|
+
results = db_create_snapshot_models(session,
|
|
689
|
+
DummySnapshotModel,
|
|
690
|
+
create_records,
|
|
691
|
+
dt_parse_iso("2024-01-01T00:00:00+00:00"))
|
|
692
|
+
assert len(results) == len(create_records)
|
|
693
|
+
|
|
694
|
+
for i, result in zip(range(0, 100), results):
|
|
695
|
+
assert result.sqn == i + 301
|
|
696
|
+
assert result.record_sqn == i + 301
|
|
697
|
+
assert result.created_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
698
|
+
assert result.expired_at is None
|
|
699
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
700
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
701
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
702
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
703
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
704
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
705
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
706
|
+
|
|
647
707
|
|
|
648
708
|
def test_db_revision_model_crud(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
649
709
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -957,6 +1017,29 @@ def test_db_revision_model_crud(fixture_postgresql_test_proc, fixture_postgresql
|
|
|
957
1017
|
assert result.dummy_array == update_records[i].dummy_array
|
|
958
1018
|
assert result.dummy_json == update_records[i].dummy_json
|
|
959
1019
|
|
|
1020
|
+
create_records = [random_record() for _ in range(0, 100)]
|
|
1021
|
+
|
|
1022
|
+
results = db_create_revision_models(session,
|
|
1023
|
+
DummyRevisionModel,
|
|
1024
|
+
create_records,
|
|
1025
|
+
dt_parse_iso("2024-01-01T00:00:00+00:00"))
|
|
1026
|
+
assert len(results) == len(create_records)
|
|
1027
|
+
|
|
1028
|
+
for i, result in zip(range(0, 100), results):
|
|
1029
|
+
assert result.sqn == i + 301
|
|
1030
|
+
assert result.record_sqn == i + 301
|
|
1031
|
+
assert result.revision == 1
|
|
1032
|
+
assert result.created_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
1033
|
+
assert result.updated_at == dt_parse_iso("2024-01-01T00:00:00+00:00")
|
|
1034
|
+
assert result.expired_at is None
|
|
1035
|
+
assert result.dummy_uuid == create_records[i].dummy_uuid
|
|
1036
|
+
assert result.dummy_int == create_records[i].dummy_int
|
|
1037
|
+
assert result.dummy_str == create_records[i].dummy_str
|
|
1038
|
+
assert result.dummy_float == create_records[i].dummy_float
|
|
1039
|
+
assert result.dummy_bool == create_records[i].dummy_bool
|
|
1040
|
+
assert result.dummy_array == create_records[i].dummy_array
|
|
1041
|
+
assert result.dummy_json == create_records[i].dummy_json
|
|
1042
|
+
|
|
960
1043
|
|
|
961
1044
|
def test_make_snapshot_model_trigger(fixture_postgresql_test_proc, fixture_postgresql_test):
|
|
962
1045
|
scheme = make_scheme(Dialects.postgresql, Drivers.psycopg)
|
|
@@ -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.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/0-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/resources/unittest/pathutils/1-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → 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.47 → 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.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMFile.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMNode.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMTags.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/carto/OSMWay.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → 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.47 → 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.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/__init__.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/apiutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/bagutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/config.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/datautils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/dockerutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/jsonutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/pathutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/sqlutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → plexus_python_common-1.0.49}/src/plexus/common/utils/strutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → 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.47 → 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.47 → plexus_python_common-1.0.49}/test/plexus_tests/common/pose_test.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.47 → 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
|