Skip to content

Commit 28a35f7

Browse files
Cleanup unit tests: remove checks for imas-core (#92)
1 parent 9c56a3e commit 28a35f7

19 files changed

+73
-179
lines changed

conftest.py

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import functools
1010
import logging
1111
import os
12-
import sys
1312
from copy import deepcopy
1413
from pathlib import Path
1514

@@ -22,7 +21,6 @@
2221
import pytest
2322
from packaging.version import Version
2423

25-
from imas.backends.imas_core.imas_interface import has_imas as _has_imas
2624
from imas.backends.imas_core.imas_interface import ll_interface, lowlevel
2725
from imas.dd_zip import dd_etree, dd_xml_versions, latest_dd_version
2826
from imas.ids_defs import (
@@ -39,17 +37,7 @@
3937

4038
os.environ["IMAS_AL_DISABLE_VALIDATE"] = "1"
4139

42-
43-
try:
44-
import imas # noqa
45-
except ImportError:
46-
47-
class SkipOnIMASAccess:
48-
def __getattr__(self, attr):
49-
pytest.skip("This test requires the `imas` HLI, which is not available.")
50-
51-
# Any test that tries to access an attribute from the `imas` package will be skipped
52-
sys.modules["imas"] = SkipOnIMASAccess()
40+
import imas # noqa
5341

5442

5543
def pytest_addoption(parser):
@@ -78,7 +66,6 @@ def pytest_addoption(parser):
7866
if "not available" in str(iex.message):
7967
_BACKENDS.pop("mdsplus")
8068

81-
8269
try:
8370
import pytest_xdist
8471
except ImportError:
@@ -91,28 +78,11 @@ def worker_id():
9178
@pytest.fixture(params=_BACKENDS)
9279
def backend(pytestconfig: pytest.Config, request: pytest.FixtureRequest):
9380
backends_provided = any(map(pytestconfig.getoption, _BACKENDS))
94-
if not _has_imas:
95-
if backends_provided:
96-
raise RuntimeError(
97-
"Explicit backends are provided, but IMAS is not available."
98-
)
99-
pytest.skip("No IMAS available, skip tests using a backend")
10081
if backends_provided and not pytestconfig.getoption(request.param):
10182
pytest.skip(f"Tests for {request.param} backend are skipped.")
10283
return _BACKENDS[request.param]
10384

10485

105-
@pytest.fixture()
106-
def has_imas():
107-
return _has_imas
108-
109-
110-
@pytest.fixture()
111-
def requires_imas():
112-
if not _has_imas:
113-
pytest.skip("No IMAS available")
114-
115-
11686
def pytest_generate_tests(metafunc):
11787
if "ids_name" in metafunc.fixturenames:
11888
if metafunc.config.getoption("ids"):
@@ -214,7 +184,7 @@ def wrapper(*args, **kwargs):
214184

215185

216186
@pytest.fixture
217-
def log_lowlevel_calls(monkeypatch, requires_imas):
187+
def log_lowlevel_calls(monkeypatch):
218188
"""Debugging fixture to log calls to the imas lowlevel module."""
219189
for al_function in dir(lowlevel):
220190
if al_function.startswith("ual_") or al_function.startswith("al"):

imas/backends/imas_core/db_entry_al.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
from .al_context import ALContext, LazyALContext
4040
from .db_entry_helpers import delete_children, get_children, put_children
41-
from .imas_interface import LLInterfaceError, has_imas, ll_interface
41+
from .imas_interface import LLInterfaceError, ll_interface
4242
from .mdsplus_model import mdsplus_model_dir
4343
from .uda_support import extract_idsdef, get_dd_version_from_idsdef_xml
4444

@@ -52,14 +52,6 @@
5252
logger = logging.getLogger(__name__)
5353

5454

55-
def require_imas_available():
56-
if not has_imas:
57-
raise RuntimeError(
58-
"The IMAS Core library is not available. Please install 'imas_core', "
59-
"or load a supported IMAS module if you use an HPC environment."
60-
)
61-
62-
6355
class ALDBEntryImpl(DBEntryImpl):
6456
"""DBEntry implementation using imas_core as a backend."""
6557

@@ -86,7 +78,6 @@ def __init__(self, uri: str, mode: int, factory: IDSFactory):
8678

8779
@classmethod
8880
def from_uri(cls, uri: str, mode: str, factory: IDSFactory) -> "ALDBEntryImpl":
89-
require_imas_available()
9081
if mode not in _OPEN_MODES:
9182
modes = list(_OPEN_MODES)
9283
raise ValueError(f"Unknown mode {mode!r}, was expecting any of {modes}")
@@ -105,8 +96,6 @@ def from_pulse_run(
10596
options: Any,
10697
factory: IDSFactory,
10798
) -> "ALDBEntryImpl":
108-
# Raise an error if imas is not available
109-
require_imas_available()
11099

111100
# Set defaults
112101
user_name = user_name or getpass.getuser()

imas/backends/imas_core/imas_interface.py

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,17 @@
1212

1313
from packaging.version import Version
1414

15-
logger = logging.getLogger(__name__)
15+
# Import the Access Layer module
16+
# First try to import imas_core, which is available since AL 5.2
17+
from imas_core import _al_lowlevel as lowlevel
18+
from imas_core import imasdef # noqa: F401
1619

20+
logger = logging.getLogger(__name__)
1721

18-
# Import the Access Layer module
19-
has_imas = True
20-
try:
21-
# First try to import imas_core, which is available since AL 5.2
22-
from imas_core import _al_lowlevel as lowlevel
23-
from imas_core import imasdef
24-
25-
# Enable throwing exceptions from the _al_lowlevel interface
26-
enable_exceptions = getattr(lowlevel, "imas_core_config_enable_exceptions", None)
27-
if enable_exceptions:
28-
enable_exceptions()
29-
30-
except ImportError as exc:
31-
imas = None
32-
has_imas = False
33-
imasdef = None
34-
lowlevel = None
35-
logger.warning(
36-
"Could not import 'imas_core': %s. Some functionality is not available.",
37-
exc,
38-
)
22+
# Enable throwing exceptions from the _al_lowlevel interface
23+
enable_exceptions = getattr(lowlevel, "imas_core_config_enable_exceptions", None)
24+
if enable_exceptions:
25+
enable_exceptions()
3926

4027

4128
class LLInterfaceError(RuntimeError):

imas/exception.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020

2121

2222
# Expose ALException, which may be thrown by the lowlevel
23-
if _imas_interface.has_imas:
24-
ALException = _imas_interface.lowlevel.ALException
25-
else:
26-
ALException = None
23+
24+
ALException = _imas_interface.lowlevel.ALException
2725

2826

2927
class IDSNameError(ValueError):

imas/ids_defs.py

Lines changed: 37 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -86,86 +86,46 @@
8686
Identifier for the default serialization protocol.
8787
"""
8888

89-
import functools
9089
import logging
9190

92-
from imas.backends.imas_core.imas_interface import has_imas, imasdef
91+
from imas.backends.imas_core.imas_interface import imasdef
9392

9493
logger = logging.getLogger(__name__)
9594

9695

97-
if has_imas:
98-
ASCII_BACKEND = imasdef.ASCII_BACKEND
99-
CHAR_DATA = imasdef.CHAR_DATA
100-
CLOSE_PULSE = imasdef.CLOSE_PULSE
101-
CLOSEST_INTERP = imasdef.CLOSEST_INTERP
102-
CREATE_PULSE = imasdef.CREATE_PULSE
103-
DOUBLE_DATA = imasdef.DOUBLE_DATA
104-
COMPLEX_DATA = imasdef.COMPLEX_DATA
105-
EMPTY_COMPLEX = imasdef.EMPTY_COMPLEX
106-
EMPTY_FLOAT = imasdef.EMPTY_FLOAT
107-
EMPTY_INT = imasdef.EMPTY_INT
108-
ERASE_PULSE = imasdef.ERASE_PULSE
109-
FORCE_CREATE_PULSE = imasdef.FORCE_CREATE_PULSE
110-
FORCE_OPEN_PULSE = imasdef.FORCE_OPEN_PULSE
111-
HDF5_BACKEND = imasdef.HDF5_BACKEND
112-
IDS_TIME_MODE_HETEROGENEOUS = imasdef.IDS_TIME_MODE_HETEROGENEOUS
113-
IDS_TIME_MODE_HOMOGENEOUS = imasdef.IDS_TIME_MODE_HOMOGENEOUS
114-
IDS_TIME_MODE_INDEPENDENT = imasdef.IDS_TIME_MODE_INDEPENDENT
115-
IDS_TIME_MODE_UNKNOWN = imasdef.IDS_TIME_MODE_UNKNOWN
116-
IDS_TIME_MODES = imasdef.IDS_TIME_MODES
117-
INTEGER_DATA = imasdef.INTEGER_DATA
118-
LINEAR_INTERP = imasdef.LINEAR_INTERP
119-
MDSPLUS_BACKEND = imasdef.MDSPLUS_BACKEND
120-
MEMORY_BACKEND = imasdef.MEMORY_BACKEND
121-
NODE_TYPE_STRUCTURE = imasdef.NODE_TYPE_STRUCTURE
122-
OPEN_PULSE = imasdef.OPEN_PULSE
123-
PREVIOUS_INTERP = imasdef.PREVIOUS_INTERP
124-
READ_OP = imasdef.READ_OP
125-
UDA_BACKEND = imasdef.UDA_BACKEND
126-
UNDEFINED_INTERP = imasdef.UNDEFINED_INTERP
127-
UNDEFINED_TIME = imasdef.UNDEFINED_TIME
128-
WRITE_OP = imasdef.WRITE_OP
129-
ASCII_SERIALIZER_PROTOCOL = getattr(imasdef, "ASCII_SERIALIZER_PROTOCOL", 60)
130-
FLEXBUFFERS_SERIALIZER_PROTOCOL = getattr(
131-
imasdef, "FLEXBUFFERS_SERIALIZER_PROTOCOL", None
132-
)
133-
DEFAULT_SERIALIZER_PROTOCOL = getattr(imasdef, "DEFAULT_SERIALIZER_PROTOCOL", 60)
134-
135-
else:
136-
# Preset some constants which are used elsewhere
137-
# this is a bit ugly, perhaps reuse the list of imports from above?
138-
# it seems no problem to use None, since the use of the values should not
139-
# be allowed, they are only used in operations which use the backend,
140-
# which we (should) gate
141-
ASCII_BACKEND = CHAR_DATA = CLOSE_PULSE = CLOSEST_INTERP = DOUBLE_DATA = None
142-
FORCE_OPEN_PULSE = CREATE_PULSE = ERASE_PULSE = None
143-
COMPLEX_DATA = FORCE_CREATE_PULSE = HDF5_BACKEND = None
144-
INTEGER_DATA = LINEAR_INTERP = MDSPLUS_BACKEND = MEMORY_BACKEND = None
145-
NODE_TYPE_STRUCTURE = OPEN_PULSE = PREVIOUS_INTERP = READ_OP = None
146-
UDA_BACKEND = UNDEFINED_INTERP = UNDEFINED_TIME = WRITE_OP = None
147-
# These constants are also useful when not working with the AL
148-
EMPTY_FLOAT = -9e40
149-
EMPTY_INT = -999_999_999
150-
EMPTY_COMPLEX = complex(EMPTY_FLOAT, EMPTY_FLOAT)
151-
IDS_TIME_MODE_UNKNOWN = EMPTY_INT
152-
IDS_TIME_MODE_HETEROGENEOUS = 0
153-
IDS_TIME_MODE_HOMOGENEOUS = 1
154-
IDS_TIME_MODE_INDEPENDENT = 2
155-
IDS_TIME_MODES = [0, 1, 2]
156-
ASCII_SERIALIZER_PROTOCOL = 60
157-
FLEXBUFFERS_SERIALIZER_PROTOCOL = None
158-
DEFAULT_SERIALIZER_PROTOCOL = 60
159-
160-
161-
def needs_imas(func):
162-
if has_imas:
163-
return func
164-
165-
@functools.wraps(func)
166-
def wrapper(*args, **kwargs):
167-
raise RuntimeError(
168-
f"Function {func.__name__} requires IMAS, but IMAS is not available."
169-
)
170-
171-
return wrapper
96+
ASCII_BACKEND = imasdef.ASCII_BACKEND
97+
CHAR_DATA = imasdef.CHAR_DATA
98+
CLOSE_PULSE = imasdef.CLOSE_PULSE
99+
CLOSEST_INTERP = imasdef.CLOSEST_INTERP
100+
CREATE_PULSE = imasdef.CREATE_PULSE
101+
DOUBLE_DATA = imasdef.DOUBLE_DATA
102+
COMPLEX_DATA = imasdef.COMPLEX_DATA
103+
EMPTY_COMPLEX = imasdef.EMPTY_COMPLEX
104+
EMPTY_FLOAT = imasdef.EMPTY_FLOAT
105+
EMPTY_INT = imasdef.EMPTY_INT
106+
ERASE_PULSE = imasdef.ERASE_PULSE
107+
FORCE_CREATE_PULSE = imasdef.FORCE_CREATE_PULSE
108+
FORCE_OPEN_PULSE = imasdef.FORCE_OPEN_PULSE
109+
HDF5_BACKEND = imasdef.HDF5_BACKEND
110+
IDS_TIME_MODE_HETEROGENEOUS = imasdef.IDS_TIME_MODE_HETEROGENEOUS
111+
IDS_TIME_MODE_HOMOGENEOUS = imasdef.IDS_TIME_MODE_HOMOGENEOUS
112+
IDS_TIME_MODE_INDEPENDENT = imasdef.IDS_TIME_MODE_INDEPENDENT
113+
IDS_TIME_MODE_UNKNOWN = imasdef.IDS_TIME_MODE_UNKNOWN
114+
IDS_TIME_MODES = imasdef.IDS_TIME_MODES
115+
INTEGER_DATA = imasdef.INTEGER_DATA
116+
LINEAR_INTERP = imasdef.LINEAR_INTERP
117+
MDSPLUS_BACKEND = imasdef.MDSPLUS_BACKEND
118+
MEMORY_BACKEND = imasdef.MEMORY_BACKEND
119+
NODE_TYPE_STRUCTURE = imasdef.NODE_TYPE_STRUCTURE
120+
OPEN_PULSE = imasdef.OPEN_PULSE
121+
PREVIOUS_INTERP = imasdef.PREVIOUS_INTERP
122+
READ_OP = imasdef.READ_OP
123+
UDA_BACKEND = imasdef.UDA_BACKEND
124+
UNDEFINED_INTERP = imasdef.UNDEFINED_INTERP
125+
UNDEFINED_TIME = imasdef.UNDEFINED_TIME
126+
WRITE_OP = imasdef.WRITE_OP
127+
ASCII_SERIALIZER_PROTOCOL = getattr(imasdef, "ASCII_SERIALIZER_PROTOCOL", 60)
128+
FLEXBUFFERS_SERIALIZER_PROTOCOL = getattr(
129+
imasdef, "FLEXBUFFERS_SERIALIZER_PROTOCOL", None
130+
)
131+
DEFAULT_SERIALIZER_PROTOCOL = getattr(imasdef, "DEFAULT_SERIALIZER_PROTOCOL", 60)

imas/ids_toplevel.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
IDS_TIME_MODE_INDEPENDENT,
2323
IDS_TIME_MODE_UNKNOWN,
2424
IDS_TIME_MODES,
25-
needs_imas,
2625
)
2726
from imas.ids_metadata import IDSMetadata, IDSType, get_toplevel_metadata
2827
from imas.ids_structure import IDSStructure
@@ -99,7 +98,6 @@ def default_serializer_protocol():
9998
"""Return the default serializer protocol."""
10099
return DEFAULT_SERIALIZER_PROTOCOL
101100

102-
@needs_imas
103101
def serialize(self, protocol=None) -> bytes:
104102
"""Serialize this IDS to a data buffer.
105103
@@ -169,7 +167,6 @@ def serialize(self, protocol=None) -> bytes:
169167
return bytes(buffer)
170168
raise ValueError(f"Unrecognized serialization protocol: {protocol}")
171169

172-
@needs_imas
173170
def deserialize(self, data: bytes) -> None:
174171
"""Deserialize the data buffer into this IDS.
175172
@@ -289,7 +286,6 @@ def _validate(self):
289286
for child in self.iter_nonempty_(accept_lazy=True):
290287
child._validate()
291288

292-
@needs_imas
293289
def get(self, occurrence: int = 0, db_entry: Optional["DBEntry"] = None) -> None:
294290
"""Get data from AL backend storage format.
295291
@@ -300,7 +296,6 @@ def get(self, occurrence: int = 0, db_entry: Optional["DBEntry"] = None) -> None
300296
raise NotImplementedError()
301297
db_entry.get(self.metadata.name, occurrence, destination=self)
302298

303-
@needs_imas
304299
def getSlice(
305300
self,
306301
time_requested: float,
@@ -323,7 +318,6 @@ def getSlice(
323318
destination=self,
324319
)
325320

326-
@needs_imas
327321
def putSlice(
328322
self, occurrence: int = 0, db_entry: Optional["DBEntry"] = None
329323
) -> None:
@@ -336,7 +330,6 @@ def putSlice(
336330
raise NotImplementedError()
337331
db_entry.put_slice(self, occurrence)
338332

339-
@needs_imas
340333
def deleteData(
341334
self, occurrence: int = 0, db_entry: Optional["DBEntry"] = None
342335
) -> None:
@@ -349,7 +342,6 @@ def deleteData(
349342
raise NotImplementedError()
350343
db_entry.delete_data(self, occurrence)
351344

352-
@needs_imas
353345
def put(self, occurrence: int = 0, db_entry: Optional["DBEntry"] = None) -> None:
354346
"""Put this IDS to the backend.
355347

imas/test/test_cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def test_imas_version():
1717

1818

1919
@pytest.mark.cli
20-
def test_db_analysis(tmp_path, requires_imas):
20+
def test_db_analysis(tmp_path):
2121
# This only tests the happy flow, error handling is not tested
2222
db_path = tmp_path / "test_db_analysis"
2323
with DBEntry(f"imas:hdf5?path={db_path}", "w") as entry:
@@ -42,7 +42,7 @@ def test_db_analysis(tmp_path, requires_imas):
4242

4343

4444
@pytest.mark.cli
45-
def test_db_analysis_csv(tmp_path, requires_imas):
45+
def test_db_analysis_csv(tmp_path):
4646
with DBEntry(f"imas:hdf5?path={tmp_path}/entry1", "w") as entry:
4747
eq = entry.factory.equilibrium()
4848
eq.ids_properties.homogeneous_time = 2

0 commit comments

Comments
 (0)