Skip to content

Commit 0de0782

Browse files
authored
Defer loading the default DD definitions (#95)
1 parent 28a35f7 commit 0de0782

3 files changed

Lines changed: 22 additions & 5 deletions

File tree

imas/backends/db_entry_impl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def get(
7878
destination: IDSToplevel,
7979
lazy: bool,
8080
nbc_map: Optional[NBCPathMap],
81-
) -> None:
81+
) -> IDSToplevel:
8282
"""Implement DBEntry.get/get_slice/get_sample. Load data from the data source.
8383
8484
Args:

imas/db_entry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def __init__(
160160
legacy = True
161161
except TypeError as exc2:
162162
raise TypeError(
163-
f"Incorrect arguments to {__class__.__name__}.__init__(): "
163+
"Incorrect arguments to DBEntry.__init__(): "
164164
f"{exc1.args[0]}, {exc2.args[0]}"
165165
) from None
166166

@@ -561,7 +561,7 @@ def _get(
561561
raise RuntimeError("Database entry is not open.")
562562
if lazy and destination:
563563
raise ValueError("Cannot supply a destination IDS when lazy loading.")
564-
if not self._ids_factory.exists(ids_name):
564+
if autoconvert and not self._ids_factory.exists(ids_name):
565565
raise IDSNameError(ids_name, self._ids_factory)
566566

567567
# Note: this will raise an exception when the ids/occurrence is not filled:
@@ -577,7 +577,7 @@ def _get(
577577
ids_name,
578578
occurrence,
579579
)
580-
elif dd_version != self.dd_version and dd_version not in dd_xml_versions():
580+
elif dd_version not in dd_xml_versions() and dd_version != self.dd_version:
581581
# We don't know the DD version that this IDS was written with
582582
if ignore_unknown_dd_version:
583583
# User chooses to ignore this problem, load as if it was stored with

imas/ids_factory.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ def __init__(
4141
version: DD version string, e.g. "3.38.1".
4242
xml_path: XML file containing data dictionary definition.
4343
"""
44+
if version is None and xml_path is None:
45+
# Defer loading the DD definitions until we really need them
46+
self.__deferred_init = True
47+
else:
48+
# If a specific version or xml_path is requested, we still load immediately
49+
# so any exceptions are raise when creating the IDSfactory
50+
self.__do_init(version, xml_path)
51+
self.__deferred_init = False
52+
53+
def __do_init(self, version: str | None, xml_path: str | pathlib.Path | None):
54+
"""Actual initialization logic"""
4455
self._xml_path = xml_path
4556
self._etree = dd_zip.dd_etree(version, xml_path)
4657
self._ids_elements = {
@@ -71,10 +82,16 @@ def __dir__(self) -> Iterable[str]:
7182
return sorted(set(object.__dir__(self)).union(self._ids_elements))
7283

7384
def __getattr__(self, name: str) -> Any:
85+
# Actually initialize when we deferred it before
86+
if self.__deferred_init:
87+
self.__do_init(None, None)
88+
self.__deferred_init = False
89+
return getattr(self, name)
90+
# Check if the name matches any IDS and return a 'constructor' for it
7491
if name in self._ids_elements:
7592
# Note: returning a partial to mimic AL HLI, e.g. factory.core_profiles()
7693
return partial(IDSToplevel, self, self._ids_elements[name])
77-
raise AttributeError(f"{type(self)!r} object has no attribute {name!r}")
94+
raise AttributeError(f"'IDSFactory' has no attribute {name!r}")
7895

7996
def __iter__(self) -> Iterator[str]:
8097
"""Iterate over the IDS names defined by the loaded Data Dictionary"""

0 commit comments

Comments
 (0)