Skip to content

Commit 4563927

Browse files
authored
root namespace in inspector args (#252)
* Add command line arg to provide the root namespace in case archive has multiple top level namespaces. * Fix rust build errors related to `"error: hiding a lifetime that's elided elsewhere is confusing"` Signed-off-by: mohapatr3 <[email protected]>
1 parent d75bc69 commit 4563927

File tree

4 files changed

+50
-8
lines changed

4 files changed

+50
-8
lines changed

flatdata-generator/flatdata/generator/engine.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
Copyright (c) 2017 HERE Europe B.V.
2+
Copyright (c) 2025 HERE Europe B.V.
33
See the LICENSE file in the root of this project for license details.
44
'''
55

@@ -61,14 +61,15 @@ def render(self, generator_name):
6161
output_content = generator.render(self.tree)
6262
return output_content
6363

64-
def render_python_module(self, module_name=None, archive_name=None):
64+
def render_python_module(self, module_name=None, archive_name=None, root_namespace=None):
6565
"""
6666
Render python module.
6767
:param module_name: Module name to use. If none, root namespace name is used.
6868
:param archive_name: Archive name to lookup,
6969
if specified, archive type is returned along with the model
70+
:param root_namespace: Root namespace to pick in case of multiple top level namespaces.
7071
"""
71-
root_namespace = self._find_root_namespace(self.tree)
72+
root_namespace = self._find_root_namespace(self.tree, root_namespace)
7273
module_code = self.render("py")
7374
module = types.ModuleType(module_name if module_name is not None else root_namespace.name)
7475
#pylint: disable=exec-used
@@ -89,14 +90,20 @@ def _create_generator(cls, name):
8990
return generator_type()
9091

9192
@staticmethod
92-
def _find_root_namespace(tree):
93+
def _find_root_namespace(tree, root_namespace=None):
9394
root_children = tree.root.children
9495
root_namespaces = [
9596
child for child in root_children
9697
if isinstance(child, Namespace) and "builtin" not in child.name
9798
]
9899
if not root_namespaces:
99100
raise RuntimeError("No root namespace found.")
101+
elif root_namespace:
102+
for namespace in root_namespaces:
103+
if namespace.name == root_namespace:
104+
return namespace
105+
raise RuntimeError("Invalid root namespace provided. Could not find root namespace in archive.")
100106
elif len(root_namespaces) > 1:
101107
raise RuntimeError("Ambiguous root namespace. Could not find root archive.")
108+
102109
return root_namespaces[0]

flatdata-py/flatdata/lib/inspector.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
Copyright (c) 2017 HERE Europe B.V.
2+
Copyright (c) 2025 HERE Europe B.V.
33
See the LICENSE file in the root of this project for license details.
44
'''
55

@@ -29,7 +29,7 @@
2929
"""
3030

3131

32-
def open_archive(path, archive=None, module_name=None):
32+
def open_archive(path, archive=None, module_name=None, root_namespace=None):
3333
"""
3434
Opens archive at a given path.
3535
Archive schema is read and python bindings are generated on the fly.
@@ -38,6 +38,7 @@ def open_archive(path, archive=None, module_name=None):
3838
:param archive: Archive name to open (in case multiple archives reside in one directory)
3939
if None, will be implied. If cannot be implied, RuntimeError is raised.
4040
:param module_name: Module name to create. If None, will match the highest-level namespace.
41+
:param root_namespace: Root namespace to pick in case of multiple top level namespaces.
4142
:return: tuple archive, module
4243
"""
4344
if not os.path.exists(path):
@@ -73,7 +74,8 @@ def open_archive(path, archive=None, module_name=None):
7374
try:
7475
module, archive_type = \
7576
Engine(schema.read().decode()).render_python_module(module_name=module_name,
76-
archive_name=archive_name)
77+
archive_name=archive_name,
78+
root_namespace=root_namespace)
7779
except FlatdataSyntaxError as err:
7880
raise RuntimeError("Error reading schema: %s " % err)
7981

@@ -87,12 +89,14 @@ def main():
8789
help="Path to archive")
8890
parser.add_argument("-a", "--archive", type=str, dest="archive", required=False, default=None,
8991
help="Name of the archive")
92+
parser.add_argument("-n", "--namespace", type=str, dest="namespace", required=False, default=None,
93+
help="Root namespace to pick in case of multiple top level namespaces")
9094
parser.add_argument("--non-interactive", type=str, dest="non_interactive", required=False,
9195
default=None,
9296
help="Python code to execute in non-interactive mode")
9397
args = parser.parse_args()
9498

95-
archive, _ = open_archive(args.path, args.archive)
99+
archive, _ = open_archive(args.path, args.archive, None, args.namespace)
96100

97101
pd.set_option('display.max_rows', 30)
98102
pd.set_option('expand_frame_repr', False)

flatdata-py/tests/common.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@
2929
)
3030

3131

32+
MULTI_NAMESPACE_TEST_SCHEMA = """
33+
namespace backward_compatibility {
34+
struct SignedStruct {
35+
a : i16 : 5;
36+
b : u32 : 32;
37+
c : i32 : 7;
38+
d : u32 : 32;
39+
}
40+
archive Archive {
41+
resource: SignedStruct;
42+
}
43+
}
44+
namespace second {
45+
}
46+
"""
47+
48+
3249

3350
VECTOR_TEST_SCHEMA = """
3451
namespace backward_compatibility {

flatdata-py/tests/test_backward_compatibility.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ def test_instance_reading():
2929
check_signed_struct(archive.resource[0])
3030

3131

32+
def test_multi_namespace_instance_reading():
33+
root_namespace = "backward_compatibility"
34+
module = Engine(MULTI_NAMESPACE_TEST_SCHEMA).render_python_module(None, None, root_namespace)
35+
valid_data = {
36+
"Archive.archive": ARCHIVE_SIGNATURE_PAYLOAD,
37+
"Archive.archive.schema": module.backward_compatibility_Archive.schema().encode(),
38+
"resource": RESOURCE_PAYLOAD,
39+
"resource.schema": module.backward_compatibility_Archive.resource_schema('resource').encode()
40+
}
41+
archive = module.backward_compatibility_Archive(DictResourceStorage(valid_data))
42+
check_signed_struct(archive.resource)
43+
check_signed_struct(archive.resource[0])
44+
45+
3246
def test_vector_reading():
3347
module = Engine(VECTOR_TEST_SCHEMA).render_python_module()
3448
valid_data = {

0 commit comments

Comments
 (0)