plexus-python-common 1.0.40__tar.gz → 1.0.41__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.40 → plexus_python_common-1.0.41}/PKG-INFO +1 -1
- plexus_python_common-1.0.41/src/plexus/common/resources/tags/__init__.py +20 -0
- plexus_python_common-1.0.41/src/plexus/common/resources/tags/universal.tagset.yaml +176 -0
- plexus_python_common-1.0.41/src/plexus/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/datautils.py +189 -2
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/jsonutils.py +1 -1
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/s3utils.py +1 -1
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus_python_common.egg-info/PKG-INFO +1 -1
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus_python_common.egg-info/SOURCES.txt +3 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/datautils_test.py +13 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/.editorconfig +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/.github/workflows/pr.yml +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/.github/workflows/push.yml +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/.gitignore +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/MANIFEST.in +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/README.md +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/VERSION +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/pyproject.toml +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/file.bar +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/file.baz +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils/dir.foo/file.foo +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils_archive/archive.compressed.zip +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/s3utils_archive/archive.uncompressed.zip +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/0-dummy +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/1-dummy +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/2-dummy +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.0.0.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.0.0.vol-0.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.1.1.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.1.1.vol-1.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.2.2.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.2.2.vol-2.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.csv.part0 +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.csv.part1 +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.csv.part2 +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.txt +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/setup.cfg +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/setup.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/__init__.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMFile.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMNode.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMTags.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMWay.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/pose.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/proj.py +0 -0
- {plexus_python_common-1.0.40/src/plexus/common/utils → plexus_python_common-1.0.41/src/plexus/common/resources}/__init__.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/apiutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/bagutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/config.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/dockerutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/ormutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/shutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/sqlutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/strutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/testutils.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus_python_common.egg-info/requires.txt +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus_python_common.egg-info/top_level.txt +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/__init__.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/pose_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/proj_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/dockerutils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/ormutils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/s3utils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/shutils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/strutils_test.py +0 -0
- {plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/utils/testutils_test.py +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import yaml
|
|
4
|
+
from iker.common.utils.funcutils import singleton
|
|
5
|
+
from iker.common.utils.jsonutils import JsonObject
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"predefined_tagset_specs",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@singleton
|
|
13
|
+
def predefined_tagset_specs() -> list[tuple[Path, JsonObject]]:
|
|
14
|
+
def load():
|
|
15
|
+
root = Path(__file__).parent
|
|
16
|
+
for path in root.glob("**/*.tagset.yaml"):
|
|
17
|
+
text = path.read_text(encoding="utf-8")
|
|
18
|
+
yield path, yaml.safe_load(text)
|
|
19
|
+
|
|
20
|
+
return list(load())
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
$namespace: "universal"
|
|
2
|
+
$desc: "Universal tags applicable across various scenarios."
|
|
3
|
+
$def:
|
|
4
|
+
camera_views:
|
|
5
|
+
&camera_views
|
|
6
|
+
unified: { $desc: "unified" }
|
|
7
|
+
front_center: { $desc: "front center" }
|
|
8
|
+
front_left: { $desc: "front left" }
|
|
9
|
+
front_right: { $desc: "front right" }
|
|
10
|
+
side_left: { $desc: "side left" }
|
|
11
|
+
side_right: { $desc: "side right" }
|
|
12
|
+
rear_left: { $desc: "rear left" }
|
|
13
|
+
rear_right: { $desc: "rear right" }
|
|
14
|
+
radar_views:
|
|
15
|
+
&radar_views
|
|
16
|
+
unified: { $desc: "unified" }
|
|
17
|
+
bumper_center: { $desc: "bumper center" }
|
|
18
|
+
bumper_left: { $desc: "bumper left" }
|
|
19
|
+
bumper_right: { $desc: "bumper right" }
|
|
20
|
+
lidar_views:
|
|
21
|
+
&lidar_views
|
|
22
|
+
unified: { $desc: "unified" }
|
|
23
|
+
front_center: { $desc: "front center" }
|
|
24
|
+
front_left: { $desc: "front left" }
|
|
25
|
+
front_right: { $desc: "front right" }
|
|
26
|
+
side_left: { $desc: "side left" }
|
|
27
|
+
side_right: { $desc: "side right" }
|
|
28
|
+
rear_left: { $desc: "rear left" }
|
|
29
|
+
rear_right: { $desc: "rear right" }
|
|
30
|
+
$tags:
|
|
31
|
+
environment:
|
|
32
|
+
tod:
|
|
33
|
+
dawn: { $desc: "dawn" }
|
|
34
|
+
daytime: { $desc: "daytime" }
|
|
35
|
+
dusk: { $desc: "dusk" }
|
|
36
|
+
nighttime: { $desc: "nighttime" }
|
|
37
|
+
unknown: { $desc: "unknown" }
|
|
38
|
+
weather:
|
|
39
|
+
cloudy: { $desc: "cloudy" }
|
|
40
|
+
foggy: { $desc: "foggy" }
|
|
41
|
+
rainy: { $desc: "rainy" }
|
|
42
|
+
snowy: { $desc: "snowy" }
|
|
43
|
+
unknown: { $desc: "unknown" }
|
|
44
|
+
visibility:
|
|
45
|
+
high: { $desc: "high" }
|
|
46
|
+
moderate: { $desc: "moderate" }
|
|
47
|
+
low: { $desc: "low" }
|
|
48
|
+
unknown: { $desc: "unknown" }
|
|
49
|
+
obstructions:
|
|
50
|
+
fog: { $desc: "fog" }
|
|
51
|
+
smoke: { $desc: "smoke" }
|
|
52
|
+
dust: { $desc: "dust" }
|
|
53
|
+
snowfall: { $desc: "snowfall" }
|
|
54
|
+
rainfall: { $desc: "rainfall" }
|
|
55
|
+
unknown: { $desc: "unknown" }
|
|
56
|
+
lighting:
|
|
57
|
+
normal: { $desc: "normal ambient lighting" }
|
|
58
|
+
low_light: { $desc: "low ambient lighting" }
|
|
59
|
+
glare: { $desc: "glare from sun or artificial source" }
|
|
60
|
+
shadows: { $desc: "shadows casting on the roadway" }
|
|
61
|
+
unknown: { $desc: "unknown" }
|
|
62
|
+
road_surface:
|
|
63
|
+
dry: { $desc: "dry" }
|
|
64
|
+
wet: { $desc: "wet" }
|
|
65
|
+
standing_water: { $desc: "standing water" }
|
|
66
|
+
icy: { $desc: "icy" }
|
|
67
|
+
snow_covered: { $desc: "snow covered" }
|
|
68
|
+
slush: { $desc: "covered in slush" }
|
|
69
|
+
gravel: { $desc: "covered in gravel" }
|
|
70
|
+
contaminated: { $desc: "contaminated with oil, mud, etc." }
|
|
71
|
+
unknown: { $desc: "unknown" }
|
|
72
|
+
roadway:
|
|
73
|
+
classification:
|
|
74
|
+
expressway: { $desc: "expressway/freeway" }
|
|
75
|
+
highway: { $desc: "highway/major road" }
|
|
76
|
+
arterial: { $desc: "arterial road" }
|
|
77
|
+
collector: { $desc: "collector road" }
|
|
78
|
+
residential: { $desc: "residential/street" }
|
|
79
|
+
rural: { $desc: "rural road" }
|
|
80
|
+
unpaved: { $desc: "unpaved road" }
|
|
81
|
+
service_road: { $desc: "service road/alley" }
|
|
82
|
+
parking_lot: { $desc: "parking lot/garage" }
|
|
83
|
+
unknown: { $desc: "unknown" }
|
|
84
|
+
layout:
|
|
85
|
+
single_way: { $desc: "single way" }
|
|
86
|
+
undivided_two_way: { $desc: "undivided two way" }
|
|
87
|
+
divided_two_way: { $desc: "divided two way" }
|
|
88
|
+
unknown: { $desc: "unknown" }
|
|
89
|
+
lane_config:
|
|
90
|
+
single_lane: { $desc: "single lane" }
|
|
91
|
+
two_lane: { $desc: "two lane" }
|
|
92
|
+
multi_lane: { $desc: "multi lane" }
|
|
93
|
+
unknown: { $desc: "unknown" }
|
|
94
|
+
shoulder:
|
|
95
|
+
none: { $desc: "no shoulder" }
|
|
96
|
+
median: { $desc: "median shoulder" }
|
|
97
|
+
verge: { $desc: "verge shoulder" }
|
|
98
|
+
sidewalk: { $desc: "sidewalk shoulder" }
|
|
99
|
+
emergency_lane: { $desc: "emergency lane" }
|
|
100
|
+
unknown: { $desc: "unknown" }
|
|
101
|
+
junction:
|
|
102
|
+
cross: { $desc: "cross intersection" }
|
|
103
|
+
tee_left_right: { $desc: "tee intersection left and right" }
|
|
104
|
+
tee_left_only: { $desc: "tee intersection left only and straight" }
|
|
105
|
+
tee_right_only: { $desc: "tee intersection right only and straight" }
|
|
106
|
+
y_intersection: { $desc: "y intersection" }
|
|
107
|
+
roundabout: { $desc: "roundabout" }
|
|
108
|
+
merge: { $desc: "merge" }
|
|
109
|
+
split: { $desc: "split" }
|
|
110
|
+
other: { $desc: "other junction type" }
|
|
111
|
+
unknown: { $desc: "unknown" }
|
|
112
|
+
infrastructure:
|
|
113
|
+
tunnel: { $desc: "tunnel" }
|
|
114
|
+
bridge: { $desc: "bridge/overpass" }
|
|
115
|
+
underpass: { $desc: "underpass" }
|
|
116
|
+
unknown: { $desc: "unknown" }
|
|
117
|
+
geometry:
|
|
118
|
+
curved: { $desc: "curved segment" }
|
|
119
|
+
incline: { $desc: "incline segment" }
|
|
120
|
+
decline: { $desc: "decline segment" }
|
|
121
|
+
hill_crest: { $desc: "hill crest" }
|
|
122
|
+
sag: { $desc: "sag segment" }
|
|
123
|
+
traffic:
|
|
124
|
+
density:
|
|
125
|
+
absent: { $desc: "no traffic" }
|
|
126
|
+
sparse: { $desc: "sparse traffic" }
|
|
127
|
+
light: { $desc: "light traffic" }
|
|
128
|
+
moderate: { $desc: "moderate traffic" }
|
|
129
|
+
dense: { $desc: "dense traffic" }
|
|
130
|
+
jammed: { $desc: "traffic jam" }
|
|
131
|
+
unknown: { $desc: "unknown" }
|
|
132
|
+
pedestrian_presence:
|
|
133
|
+
absent: { $desc: "no pedestrians" }
|
|
134
|
+
sparse: { $desc: "sparse pedestrians" }
|
|
135
|
+
moderate: { $desc: "moderate pedestrians" }
|
|
136
|
+
dense: { $desc: "dense pedestrians" }
|
|
137
|
+
unknown: { $desc: "unknown" }
|
|
138
|
+
cyclist_presence:
|
|
139
|
+
absent: { $desc: "no cyclists" }
|
|
140
|
+
sparse: { $desc: "sparse cyclists" }
|
|
141
|
+
moderate: { $desc: "moderate cyclists" }
|
|
142
|
+
dense: { $desc: "dense cyclists" }
|
|
143
|
+
unknown: { $desc: "unknown" }
|
|
144
|
+
construction_zone:
|
|
145
|
+
absent: { $desc: "no construction" }
|
|
146
|
+
minor: { $desc: "minor construction" }
|
|
147
|
+
major: { $desc: "major construction" }
|
|
148
|
+
unknown: { $desc: "unknown" }
|
|
149
|
+
accident:
|
|
150
|
+
road_block: { $desc: "road block" }
|
|
151
|
+
debris_on_road: { $desc: "debris on road" }
|
|
152
|
+
animal_on_road: { $desc: "animal on road" }
|
|
153
|
+
pedestrian_on_road: { $desc: "pedestrian on road" }
|
|
154
|
+
vehicle_breakdown: { $desc: "vehicle breakdown" }
|
|
155
|
+
emergency_vehicle_present: { $desc: "emergency vehicle present" }
|
|
156
|
+
police_stop: { $desc: "police stop" }
|
|
157
|
+
other: { $desc: "other accident type" }
|
|
158
|
+
data_fidelity:
|
|
159
|
+
camera_issue:
|
|
160
|
+
glare: { $desc: "glare from sun or artificial source", <<: *camera_views }
|
|
161
|
+
motion_blur: { $desc: "motion blur", <<: *camera_views }
|
|
162
|
+
lens_smear: { $desc: "lens smear or dirt", <<: *camera_views }
|
|
163
|
+
occlusion: { $desc: "occlusion by objects", <<: *camera_views }
|
|
164
|
+
underexposure: { $desc: "underexposure", <<: *camera_views }
|
|
165
|
+
overexposure: { $desc: "overexposure", <<: *camera_views }
|
|
166
|
+
radar_issue:
|
|
167
|
+
weather_effects: { $desc: "weather effects", <<: *radar_views }
|
|
168
|
+
interference: { $desc: "interference", <<: *radar_views }
|
|
169
|
+
multipath: { $desc: "multipath reflections", <<: *radar_views }
|
|
170
|
+
clutter: { $desc: "clutter", <<: *radar_views }
|
|
171
|
+
lidar_issue:
|
|
172
|
+
weather_effects: { $desc: "weather effects", <<: *lidar_views }
|
|
173
|
+
occlusion: { $desc: "occlusion by objects", <<: *lidar_views }
|
|
174
|
+
motion_distortion: { $desc: "motion distortion", <<: *lidar_views }
|
|
175
|
+
range_dropout: { $desc: "range dropout", <<: *lidar_views }
|
|
176
|
+
reflectivity: { $desc: "reflectivity issues", <<: *lidar_views }
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/datautils.py
RENAMED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
import datetime
|
|
2
|
-
from collections.abc import Callable, Generator
|
|
3
|
+
from collections.abc import Callable, Generator, Mapping, Sequence
|
|
3
4
|
from typing import Any
|
|
4
5
|
|
|
5
6
|
import pyparsing as pp
|
|
6
7
|
import ujson as json
|
|
7
8
|
from iker.common.utils.funcutils import singleton
|
|
8
|
-
from iker.common.utils.
|
|
9
|
+
from iker.common.utils.iterutils import dicttree
|
|
10
|
+
from iker.common.utils.iterutils import dicttree_add, dicttree_remove
|
|
11
|
+
from iker.common.utils.iterutils import dicttree_children, dicttree_lineage, dicttree_subtree
|
|
12
|
+
from iker.common.utils.iterutils import head_or_none
|
|
13
|
+
from iker.common.utils.jsonutils import JsonObject, JsonType
|
|
9
14
|
from iker.common.utils.randutils import randomizer
|
|
10
15
|
|
|
16
|
+
from plexus.common.resources.tags import predefined_tagset_specs
|
|
11
17
|
from plexus.common.utils.strutils import BagName, UserName, VehicleName
|
|
12
18
|
from plexus.common.utils.strutils import colon_tag_parser, slash_tag_parser
|
|
13
19
|
from plexus.common.utils.strutils import dot_case_parser, kebab_case_parser, snake_case_parser
|
|
@@ -18,6 +24,38 @@ from plexus.common.utils.strutils import strict_abspath_parser, strict_relpath_p
|
|
|
18
24
|
from plexus.common.utils.strutils import strict_fragmented_abspath_parser, strict_fragmented_relpath_parser
|
|
19
25
|
from plexus.common.utils.strutils import topic_parser, vin_code_chars, vin_code_parser
|
|
20
26
|
|
|
27
|
+
__all__ = [
|
|
28
|
+
"compute_vin_code_check_digit",
|
|
29
|
+
"validate_hex_string",
|
|
30
|
+
"validate_snake_case",
|
|
31
|
+
"validate_kebab_case",
|
|
32
|
+
"validate_dot_case",
|
|
33
|
+
"validate_uuid",
|
|
34
|
+
"validate_strict_relpath",
|
|
35
|
+
"validate_strict_abspath",
|
|
36
|
+
"validate_strict_fragmented_relpath",
|
|
37
|
+
"validate_strict_fragmented_abspath",
|
|
38
|
+
"validate_semver",
|
|
39
|
+
"validate_colon_tag",
|
|
40
|
+
"validate_slash_tag",
|
|
41
|
+
"validate_topic",
|
|
42
|
+
"validate_vin_code",
|
|
43
|
+
"validate_user_name",
|
|
44
|
+
"validate_vehicle_name",
|
|
45
|
+
"validate_bag_name",
|
|
46
|
+
"validate_dt_timezone",
|
|
47
|
+
"validate_json_type_dump_size",
|
|
48
|
+
"random_vin_code",
|
|
49
|
+
"known_topics",
|
|
50
|
+
"known_user_names",
|
|
51
|
+
"known_vehicle_names",
|
|
52
|
+
"random_bag_names_sequence",
|
|
53
|
+
"Tag",
|
|
54
|
+
"Tagset",
|
|
55
|
+
"populate_tagset",
|
|
56
|
+
"predefined_tagsets",
|
|
57
|
+
]
|
|
58
|
+
|
|
21
59
|
|
|
22
60
|
def make_compute_vin_code_check_digit() -> Callable[[str], str]:
|
|
23
61
|
trans_nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
@@ -201,3 +239,152 @@ def random_bag_names_sequence(
|
|
|
201
239
|
|
|
202
240
|
for record_sn in range(bags_count):
|
|
203
241
|
yield BagName(vehicle_name=vehicle_name, record_dt=record_dt, record_sn=record_sn)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@dataclasses.dataclass(frozen=True, eq=True, order=True)
|
|
245
|
+
class Tag(object):
|
|
246
|
+
name: str
|
|
247
|
+
desc: str | None
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def tag_parts(self) -> list[str]:
|
|
251
|
+
return self.name.rsplit(":")
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def parent_tag_name(self) -> str | None:
|
|
255
|
+
return head_or_none(self.name.rsplit(":", 1))
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class Tagset(Sequence[Tag], Mapping[str, Tag]):
|
|
259
|
+
def __init__(self, namespace: str, desc: str) -> None:
|
|
260
|
+
super().__init__()
|
|
261
|
+
self.namespace = namespace
|
|
262
|
+
self.desc = desc
|
|
263
|
+
self.tags: list[Tag] = []
|
|
264
|
+
self.tags_dict: dict[str, Tag] = {}
|
|
265
|
+
self.tags_tree: dicttree[str, Tag] = {}
|
|
266
|
+
|
|
267
|
+
def __contains__(self, item: str | Tag) -> bool:
|
|
268
|
+
tag_name = item.name if isinstance(item, Tag) else item
|
|
269
|
+
return tag_name in self.tags_dict
|
|
270
|
+
|
|
271
|
+
def __len__(self) -> int:
|
|
272
|
+
return len(self.tags)
|
|
273
|
+
|
|
274
|
+
def __getitem__(self, index: int) -> Tag:
|
|
275
|
+
return self.tags[index]
|
|
276
|
+
|
|
277
|
+
def keys(self):
|
|
278
|
+
return self.tags_dict.keys()
|
|
279
|
+
|
|
280
|
+
def values(self):
|
|
281
|
+
return self.tags_dict.values()
|
|
282
|
+
|
|
283
|
+
def items(self):
|
|
284
|
+
return self.tags_dict.items()
|
|
285
|
+
|
|
286
|
+
def get(self, item: str | Tag) -> Tag | None:
|
|
287
|
+
tag_name = item.name if isinstance(item, Tag) else item
|
|
288
|
+
return self.tags_dict.get(tag_name)
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def tag_names(self) -> list[str]:
|
|
292
|
+
return list(self.tags_dict.keys())
|
|
293
|
+
|
|
294
|
+
def add(self, tag: Tag) -> None:
|
|
295
|
+
if tag.name in self.tags_dict:
|
|
296
|
+
raise ValueError(f"duplicate tag name '{tag.name}'")
|
|
297
|
+
|
|
298
|
+
self.tags.append(tag)
|
|
299
|
+
self.tags_dict[tag.name] = tag
|
|
300
|
+
|
|
301
|
+
dicttree_add(self.tags_tree, tag.tag_parts, tag, create_prefix=True)
|
|
302
|
+
|
|
303
|
+
def remove(self, tag_name: str) -> None:
|
|
304
|
+
tag = self.get(tag_name)
|
|
305
|
+
if tag is None:
|
|
306
|
+
raise ValueError(f"tag '{tag_name}' not found")
|
|
307
|
+
|
|
308
|
+
self.tags.remove(tag)
|
|
309
|
+
del self.tags_dict[tag_name]
|
|
310
|
+
|
|
311
|
+
dicttree_remove(self.tags_tree, tag.tag_parts, recursive=True)
|
|
312
|
+
|
|
313
|
+
def child_tags(self, parent: str | Tag) -> list[Tag]:
|
|
314
|
+
if parent is None:
|
|
315
|
+
return []
|
|
316
|
+
if isinstance(parent, str):
|
|
317
|
+
return self.child_tags(self.get(parent))
|
|
318
|
+
|
|
319
|
+
subtree = dicttree_subtree(self.tags_tree, parent.tag_parts)
|
|
320
|
+
return list(dicttree_children(subtree)) if subtree else []
|
|
321
|
+
|
|
322
|
+
def parent_tags(self, child: str | Tag) -> list[Tag]:
|
|
323
|
+
if child is None:
|
|
324
|
+
return []
|
|
325
|
+
if isinstance(child, str):
|
|
326
|
+
return self.parent_tags(self.get(child))
|
|
327
|
+
|
|
328
|
+
return list(dicttree_lineage(self.tags_tree, child.tag_parts[:-1]))
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def populate_tagset(tagset_spec: JsonObject) -> Tagset:
|
|
332
|
+
"""
|
|
333
|
+
Collect tags from tagset spec JSON object, validate the format along the way.
|
|
334
|
+
|
|
335
|
+
:param tagset_spec: JSON object of tagset spec
|
|
336
|
+
:return: Populated Tagset instance
|
|
337
|
+
"""
|
|
338
|
+
|
|
339
|
+
def validate_and_collect(tag_name: str, tag_def: JsonObject) -> Generator[Tag, None, None]:
|
|
340
|
+
if not isinstance(tag_def, dict):
|
|
341
|
+
raise ValueError(f"tag '{tag_name}' definition is not a dict")
|
|
342
|
+
|
|
343
|
+
for child_tag_name, child_tag_def in tag_def.items():
|
|
344
|
+
if child_tag_name == "$desc":
|
|
345
|
+
continue
|
|
346
|
+
|
|
347
|
+
if not isinstance(child_tag_name, str):
|
|
348
|
+
raise ValueError(f"child '{child_tag_name}' of tag '{tag_name}' is not a string")
|
|
349
|
+
try:
|
|
350
|
+
validate_snake_case(child_tag_name)
|
|
351
|
+
except ValueError as e:
|
|
352
|
+
raise ValueError(f"child '{child_tag_name}' of tag '{tag_name}' is not in snake case") from e
|
|
353
|
+
|
|
354
|
+
child_tag_name = tag_name + ":" + child_tag_name if tag_name else child_tag_name
|
|
355
|
+
|
|
356
|
+
yield from validate_and_collect(child_tag_name, child_tag_def)
|
|
357
|
+
|
|
358
|
+
yield Tag(name=tag_name, desc=tag_def.get("$desc"))
|
|
359
|
+
|
|
360
|
+
namespace = tagset_spec.get("$namespace")
|
|
361
|
+
if namespace is None:
|
|
362
|
+
raise ValueError("missing '$namespace' in tagset spec")
|
|
363
|
+
try:
|
|
364
|
+
validate_snake_case(namespace)
|
|
365
|
+
except ValueError as e:
|
|
366
|
+
raise ValueError(f"tagset namespace '{namespace}' is not in snake case") from e
|
|
367
|
+
|
|
368
|
+
desc = tagset_spec.get("$desc")
|
|
369
|
+
if desc is None:
|
|
370
|
+
raise ValueError("missing '$desc' in tagset spec")
|
|
371
|
+
|
|
372
|
+
tags = tagset_spec.get("$tags")
|
|
373
|
+
if tags is None:
|
|
374
|
+
raise ValueError("missing '$tags' in tagset spec")
|
|
375
|
+
|
|
376
|
+
tagset = Tagset(namespace=namespace, desc=desc)
|
|
377
|
+
|
|
378
|
+
for tag in validate_and_collect("", tags):
|
|
379
|
+
tagset.add(tag)
|
|
380
|
+
|
|
381
|
+
return tagset
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
@singleton
|
|
385
|
+
def predefined_tagsets() -> dict[str, Tagset]:
|
|
386
|
+
tagsets: dict[str, Tagset] = {}
|
|
387
|
+
for _, tagset_spec in predefined_tagset_specs():
|
|
388
|
+
tagset = populate_tagset(tagset_spec)
|
|
389
|
+
tagsets[tagset.namespace] = tagset
|
|
390
|
+
return tagsets
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/jsonutils.py
RENAMED
|
@@ -5,9 +5,9 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
import ujson as json
|
|
7
7
|
from iker.common.utils.dtutils import dt_format, dt_parse, extended_format
|
|
8
|
+
from iker.common.utils.iterutils import batched
|
|
8
9
|
from iker.common.utils.jsonutils import JsonType, JsonValueCompatible
|
|
9
10
|
from iker.common.utils.jsonutils import json_reformat
|
|
10
|
-
from iker.common.utils.sequtils import batched
|
|
11
11
|
|
|
12
12
|
from plexus.common.utils.shutils import collect_volumed_filenames, populate_volumed_filenames
|
|
13
13
|
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/s3utils.py
RENAMED
|
@@ -18,8 +18,8 @@ from typing import Literal
|
|
|
18
18
|
import boto3
|
|
19
19
|
import fsspec
|
|
20
20
|
import fsspec.utils
|
|
21
|
+
from iker.common.utils.iterutils import chunk_between, head, last
|
|
21
22
|
from iker.common.utils.jsonutils import JsonObject
|
|
22
|
-
from iker.common.utils.sequtils import chunk_between, head, last
|
|
23
23
|
from iker.common.utils.shutils import glob_match, listfile, path_depth
|
|
24
24
|
from iker.common.utils.strutils import is_empty, trim_to_none
|
|
25
25
|
from mypy_boto3_s3 import S3Client
|
|
@@ -46,6 +46,9 @@ src/plexus/common/carto/OSMNode.py
|
|
|
46
46
|
src/plexus/common/carto/OSMTags.py
|
|
47
47
|
src/plexus/common/carto/OSMWay.py
|
|
48
48
|
src/plexus/common/carto/__init__.py
|
|
49
|
+
src/plexus/common/resources/__init__.py
|
|
50
|
+
src/plexus/common/resources/tags/__init__.py
|
|
51
|
+
src/plexus/common/resources/tags/universal.tagset.yaml
|
|
49
52
|
src/plexus/common/utils/__init__.py
|
|
50
53
|
src/plexus/common/utils/apiutils.py
|
|
51
54
|
src/plexus/common/utils/bagutils.py
|
|
@@ -2,6 +2,8 @@ import unittest
|
|
|
2
2
|
|
|
3
3
|
import ddt
|
|
4
4
|
|
|
5
|
+
from plexus.common.utils.datautils import Tagset
|
|
6
|
+
from plexus.common.utils.datautils import predefined_tagsets
|
|
5
7
|
from plexus.common.utils.datautils import random_vin_code, validate_vin_code
|
|
6
8
|
|
|
7
9
|
|
|
@@ -36,3 +38,14 @@ class DataUtilsTest(unittest.TestCase):
|
|
|
36
38
|
def test_validate_vin_code__bad_case(self, data):
|
|
37
39
|
with self.assertRaises(ValueError):
|
|
38
40
|
validate_vin_code(data)
|
|
41
|
+
|
|
42
|
+
def test_predefined_tagsets(self):
|
|
43
|
+
tagsets = predefined_tagsets()
|
|
44
|
+
for _, tagset in tagsets.items():
|
|
45
|
+
self.assertIsInstance(tagset, Tagset)
|
|
46
|
+
|
|
47
|
+
for tag in tagset:
|
|
48
|
+
self.assertIn(tag, tagset)
|
|
49
|
+
self.assertIn(tag.name, tagset)
|
|
50
|
+
self.assertEqual(tag, tagset.get(tag))
|
|
51
|
+
self.assertEqual(tag, tagset.get(tag.name))
|
|
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
|
|
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.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/0-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/1-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/2-dummy
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.0.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.1.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.2.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/resources/unittest/shutils/dummy.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMFile.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMNode.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMTags.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/OSMWay.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/carto/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/apiutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/bagutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/config.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/dockerutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/ormutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/shutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/sqlutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/src/plexus/common/utils/strutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/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
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/test/plexus_tests/common/pose_test.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.40 → plexus_python_common-1.0.41}/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
|