foamlib 0.3.0__tar.gz → 0.3.2__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.
- {foamlib-0.3.0 → foamlib-0.3.2}/PKG-INFO +1 -1
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/__init__.py +3 -2
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_files/_base.py +14 -3
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_files/_fields.py +12 -5
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_files/_files.py +3 -3
- foamlib-0.3.2/foamlib/_files/_serialization.py +99 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_util.py +35 -33
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib.egg-info/PKG-INFO +1 -1
- foamlib-0.3.0/foamlib/_files/_serialization.py +0 -156
- {foamlib-0.3.0 → foamlib-0.3.2}/LICENSE.txt +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/README.md +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_cases.py +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_files/__init__.py +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_files/_io.py +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/_files/_parsing.py +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib/py.typed +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib.egg-info/SOURCES.txt +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib.egg-info/dependency_links.txt +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib.egg-info/requires.txt +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/foamlib.egg-info/top_level.txt +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/pyproject.toml +0 -0
- {foamlib-0.3.0 → foamlib-0.3.2}/setup.cfg +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
"""A Python interface for interacting with OpenFOAM."""
|
2
2
|
|
3
|
-
__version__ = "0.3.
|
3
|
+
__version__ = "0.3.2"
|
4
4
|
|
5
5
|
from ._cases import AsyncFoamCase, FoamCase, FoamCaseBase
|
6
6
|
from ._files import FoamDict, FoamFieldFile, FoamFile
|
7
|
-
from ._util import CalledProcessError
|
7
|
+
from ._util import CalledProcessError, CalledProcessWarning
|
8
8
|
|
9
9
|
__all__ = [
|
10
10
|
"FoamCase",
|
@@ -14,4 +14,5 @@ __all__ = [
|
|
14
14
|
"FoamFieldFile",
|
15
15
|
"FoamDict",
|
16
16
|
"CalledProcessError",
|
17
|
+
"CalledProcessWarning",
|
17
18
|
]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import sys
|
2
2
|
from abc import abstractmethod
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Dict, NamedTuple, Optional, Union
|
4
|
+
from typing import Dict, NamedTuple, Optional, Tuple, Union
|
5
5
|
|
6
6
|
if sys.version_info >= (3, 9):
|
7
7
|
from collections.abc import Mapping, Sequence
|
@@ -10,7 +10,6 @@ else:
|
|
10
10
|
|
11
11
|
try:
|
12
12
|
import numpy as np
|
13
|
-
from numpy.typing import NDArray
|
14
13
|
except ModuleNotFoundError:
|
15
14
|
pass
|
16
15
|
|
@@ -59,4 +58,16 @@ class FoamDict:
|
|
59
58
|
"""Return a nested dict representation of the dictionary."""
|
60
59
|
raise NotImplementedError
|
61
60
|
|
62
|
-
_SetData = Union[
|
61
|
+
_SetData = Union[
|
62
|
+
str,
|
63
|
+
int,
|
64
|
+
float,
|
65
|
+
bool,
|
66
|
+
Dimensioned,
|
67
|
+
DimensionSet,
|
68
|
+
Sequence["_SetData"],
|
69
|
+
Mapping[str, "_SetData"],
|
70
|
+
"np.ndarray[Tuple[()], np.dtype[np.generic]]",
|
71
|
+
"np.ndarray[Tuple[int], np.dtype[np.generic]]",
|
72
|
+
"np.ndarray[Tuple[int, int], np.dtype[np.generic]]",
|
73
|
+
]
|
@@ -10,7 +10,6 @@ from ._files import FoamFile
|
|
10
10
|
|
11
11
|
try:
|
12
12
|
import numpy as np
|
13
|
-
from numpy.typing import NDArray
|
14
13
|
except ModuleNotFoundError:
|
15
14
|
pass
|
16
15
|
|
@@ -58,7 +57,9 @@ class FoamFieldFile(FoamFile):
|
|
58
57
|
int,
|
59
58
|
float,
|
60
59
|
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
61
|
-
"
|
60
|
+
"np.ndarray[Tuple[()], np.dtype[np.generic]]",
|
61
|
+
"np.ndarray[Tuple[int], np.dtype[np.generic]]",
|
62
|
+
"np.ndarray[Tuple[int, int], np.dtype[np.generic]]",
|
62
63
|
]:
|
63
64
|
"""Alias of `self["value"]`."""
|
64
65
|
ret = self["value"]
|
@@ -73,7 +74,9 @@ class FoamFieldFile(FoamFile):
|
|
73
74
|
int,
|
74
75
|
float,
|
75
76
|
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
76
|
-
"
|
77
|
+
"np.ndarray[Tuple[()], np.dtype[np.generic]]",
|
78
|
+
"np.ndarray[Tuple[int], np.dtype[np.generic]]",
|
79
|
+
"np.ndarray[Tuple[int, int], np.dtype[np.generic]]",
|
77
80
|
],
|
78
81
|
) -> None:
|
79
82
|
self["value"] = value
|
@@ -128,7 +131,9 @@ class FoamFieldFile(FoamFile):
|
|
128
131
|
int,
|
129
132
|
float,
|
130
133
|
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
131
|
-
"
|
134
|
+
"np.ndarray[Tuple[()], np.dtype[np.generic]]",
|
135
|
+
"np.ndarray[Tuple[int], np.dtype[np.generic]]",
|
136
|
+
"np.ndarray[Tuple[int, int], np.dtype[np.generic]]",
|
132
137
|
]:
|
133
138
|
"""Alias of `self["internalField"]`."""
|
134
139
|
ret = self["internalField"]
|
@@ -143,7 +148,9 @@ class FoamFieldFile(FoamFile):
|
|
143
148
|
int,
|
144
149
|
float,
|
145
150
|
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
146
|
-
"
|
151
|
+
"np.ndarray[Tuple[()], np.dtype[np.generic]]",
|
152
|
+
"np.ndarray[Tuple[int], np.dtype[np.generic]]",
|
153
|
+
"np.ndarray[Tuple[int, int], np.dtype[np.generic]]",
|
147
154
|
],
|
148
155
|
) -> None:
|
149
156
|
self["internalField"] = value
|
@@ -12,7 +12,7 @@ else:
|
|
12
12
|
|
13
13
|
from ._base import FoamDict
|
14
14
|
from ._io import FoamFileIO
|
15
|
-
from ._serialization import
|
15
|
+
from ._serialization import dumps
|
16
16
|
|
17
17
|
|
18
18
|
class FoamFile(
|
@@ -134,7 +134,7 @@ class FoamFile(
|
|
134
134
|
start, end = parsed.entry_location(keywords, missing_ok=True)
|
135
135
|
|
136
136
|
self._write(
|
137
|
-
f"{contents[:start]}\n{
|
137
|
+
f"{contents[:start]}\n{dumps({keywords[-1]: {}})}\n{contents[end:]}"
|
138
138
|
)
|
139
139
|
|
140
140
|
for k, v in data.items():
|
@@ -143,7 +143,7 @@ class FoamFile(
|
|
143
143
|
start, end = parsed.entry_location(keywords, missing_ok=True)
|
144
144
|
|
145
145
|
self._write(
|
146
|
-
f"{contents[:start]}\n{
|
146
|
+
f"{contents[:start]}\n{dumps({keywords[-1]: data}, assume_field=assume_field, assume_dimensions=assume_dimensions)}\n{contents[end:]}"
|
147
147
|
)
|
148
148
|
|
149
149
|
def __setitem__(
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
if sys.version_info >= (3, 9):
|
4
|
+
from collections.abc import Mapping
|
5
|
+
else:
|
6
|
+
from typing import Mapping
|
7
|
+
|
8
|
+
from .._util import is_sequence
|
9
|
+
from ._base import FoamDict
|
10
|
+
|
11
|
+
try:
|
12
|
+
import numpy as np
|
13
|
+
|
14
|
+
numpy = True
|
15
|
+
except ModuleNotFoundError:
|
16
|
+
numpy = False
|
17
|
+
|
18
|
+
|
19
|
+
def dumps(
|
20
|
+
data: FoamDict._SetData,
|
21
|
+
*,
|
22
|
+
assume_field: bool = False,
|
23
|
+
assume_dimensions: bool = False,
|
24
|
+
assume_data_entries: bool = False,
|
25
|
+
) -> str:
|
26
|
+
if numpy and isinstance(data, np.ndarray):
|
27
|
+
return dumps(
|
28
|
+
data.tolist(),
|
29
|
+
assume_field=assume_field,
|
30
|
+
assume_dimensions=assume_dimensions,
|
31
|
+
)
|
32
|
+
|
33
|
+
elif isinstance(data, Mapping):
|
34
|
+
entries = []
|
35
|
+
for k, v in data.items():
|
36
|
+
s = dumps(
|
37
|
+
v,
|
38
|
+
assume_field=assume_field,
|
39
|
+
assume_dimensions=assume_dimensions,
|
40
|
+
assume_data_entries=True,
|
41
|
+
)
|
42
|
+
if isinstance(v, Mapping):
|
43
|
+
entries.append(f"{k}\n{{\n{s}\n}}")
|
44
|
+
elif s:
|
45
|
+
entries.append(f"{k} {s};")
|
46
|
+
else:
|
47
|
+
entries.append(f"{k};")
|
48
|
+
return "\n".join(entries)
|
49
|
+
|
50
|
+
elif isinstance(data, FoamDict.DimensionSet) or (
|
51
|
+
assume_dimensions and is_sequence(data) and len(data) == 7
|
52
|
+
):
|
53
|
+
return f"[{' '.join(str(v) for v in data)}]"
|
54
|
+
|
55
|
+
elif assume_field and isinstance(data, (int, float)):
|
56
|
+
return f"uniform {data}"
|
57
|
+
|
58
|
+
elif assume_field and is_sequence(data):
|
59
|
+
if isinstance(data[0], (int, float)) and len(data) in (3, 6, 9):
|
60
|
+
return f"uniform {dumps(data)}"
|
61
|
+
elif isinstance(data[0], (int, float)):
|
62
|
+
return f"nonuniform List<scalar> {len(data)}{dumps(data)}"
|
63
|
+
elif len(data[0]) == 3:
|
64
|
+
return f"nonuniform List<vector> {len(data)}{dumps(data)}"
|
65
|
+
elif len(data[0]) == 6:
|
66
|
+
return f"nonuniform List<symmTensor> {len(data)}{dumps(data)}"
|
67
|
+
elif len(data[0]) == 9:
|
68
|
+
return f"nonuniform List<tensor> {len(data)}{dumps(data)}"
|
69
|
+
else:
|
70
|
+
return dumps(
|
71
|
+
data,
|
72
|
+
assume_dimensions=assume_dimensions,
|
73
|
+
assume_data_entries=assume_data_entries,
|
74
|
+
)
|
75
|
+
|
76
|
+
elif assume_data_entries and isinstance(data, tuple):
|
77
|
+
return " ".join(
|
78
|
+
dumps(v, assume_field=assume_field, assume_dimensions=assume_dimensions)
|
79
|
+
for v in data
|
80
|
+
)
|
81
|
+
|
82
|
+
elif isinstance(data, FoamDict.Dimensioned):
|
83
|
+
if data.name is not None:
|
84
|
+
return f"{data.name} {dumps(data.dimensions, assume_dimensions=True)} {dumps(data.value)}"
|
85
|
+
else:
|
86
|
+
return (
|
87
|
+
f"{dumps(data.dimensions, assume_dimensions=True)} {dumps(data.value)}"
|
88
|
+
)
|
89
|
+
|
90
|
+
elif is_sequence(data):
|
91
|
+
return f"({' '.join(dumps(v) for v in data)})"
|
92
|
+
|
93
|
+
elif data is True:
|
94
|
+
return "yes"
|
95
|
+
elif data is False:
|
96
|
+
return "no"
|
97
|
+
|
98
|
+
else:
|
99
|
+
return str(data)
|
@@ -2,7 +2,8 @@ import asyncio
|
|
2
2
|
import subprocess
|
3
3
|
import sys
|
4
4
|
from pathlib import Path
|
5
|
-
from typing import Any, Union
|
5
|
+
from typing import Any, Optional, Union
|
6
|
+
from warnings import warn
|
6
7
|
|
7
8
|
if sys.version_info >= (3, 9):
|
8
9
|
from collections.abc import Mapping, Sequence
|
@@ -14,31 +15,36 @@ if sys.version_info >= (3, 10):
|
|
14
15
|
else:
|
15
16
|
from typing_extensions import TypeGuard
|
16
17
|
|
17
|
-
try:
|
18
|
-
import numpy as np
|
19
|
-
except ModuleNotFoundError:
|
20
|
-
numpy = False
|
21
|
-
else:
|
22
|
-
numpy = True
|
23
|
-
|
24
18
|
|
25
19
|
def is_sequence(
|
26
20
|
value: Any,
|
27
|
-
) -> TypeGuard[
|
28
|
-
return (
|
29
|
-
isinstance(value, Sequence)
|
30
|
-
and not isinstance(value, str)
|
31
|
-
or numpy
|
32
|
-
and isinstance(value, np.ndarray)
|
33
|
-
)
|
21
|
+
) -> TypeGuard[Sequence[Any]]:
|
22
|
+
return isinstance(value, Sequence) and not isinstance(value, str)
|
34
23
|
|
35
24
|
|
36
|
-
CalledProcessError
|
25
|
+
class CalledProcessError(subprocess.CalledProcessError):
|
26
|
+
"""Exception raised when a process fails and `check=True`."""
|
37
27
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
def __str__(self) -> str:
|
29
|
+
msg = super().__str__()
|
30
|
+
if self.stderr:
|
31
|
+
msg += f"\n{self.stderr}"
|
32
|
+
return msg
|
33
|
+
|
34
|
+
|
35
|
+
class CalledProcessWarning(Warning):
|
36
|
+
"""Warning raised when a process prints to stderr and `check=True`."""
|
37
|
+
|
38
|
+
|
39
|
+
def _check(
|
40
|
+
retcode: int,
|
41
|
+
cmd: Union[Sequence[Union[str, Path]], str, Path],
|
42
|
+
stderr: Optional[str],
|
43
|
+
) -> None:
|
44
|
+
if retcode != 0:
|
45
|
+
raise CalledProcessError(retcode, cmd, None, stderr)
|
46
|
+
elif stderr:
|
47
|
+
warn(f"Command {cmd} printed to stderr.\n{stderr}", CalledProcessWarning)
|
42
48
|
|
43
49
|
|
44
50
|
def run_process(
|
@@ -47,7 +53,7 @@ def run_process(
|
|
47
53
|
check: bool = True,
|
48
54
|
cwd: Union[None, str, Path] = None,
|
49
55
|
env: Union[None, Mapping[str, str]] = None,
|
50
|
-
) ->
|
56
|
+
) -> None:
|
51
57
|
shell = not is_sequence(cmd)
|
52
58
|
|
53
59
|
if sys.version_info < (3, 8):
|
@@ -60,14 +66,14 @@ def run_process(
|
|
60
66
|
cmd,
|
61
67
|
cwd=cwd,
|
62
68
|
env=env,
|
63
|
-
stdout=
|
64
|
-
stderr=
|
69
|
+
stdout=subprocess.DEVNULL,
|
70
|
+
stderr=subprocess.PIPE if check else subprocess.DEVNULL,
|
65
71
|
text=True,
|
66
72
|
shell=shell,
|
67
|
-
check=check,
|
68
73
|
)
|
69
74
|
|
70
|
-
|
75
|
+
if check:
|
76
|
+
_check(proc.returncode, cmd, proc.stderr)
|
71
77
|
|
72
78
|
|
73
79
|
async def run_process_async(
|
@@ -76,14 +82,14 @@ async def run_process_async(
|
|
76
82
|
check: bool = True,
|
77
83
|
cwd: Union[None, str, Path] = None,
|
78
84
|
env: Union[None, Mapping[str, str]] = None,
|
79
|
-
) ->
|
85
|
+
) -> None:
|
80
86
|
if not is_sequence(cmd):
|
81
87
|
proc = await asyncio.create_subprocess_shell(
|
82
88
|
str(cmd),
|
83
89
|
cwd=cwd,
|
84
90
|
env=env,
|
85
91
|
stdout=asyncio.subprocess.DEVNULL,
|
86
|
-
stderr=asyncio.subprocess.PIPE,
|
92
|
+
stderr=asyncio.subprocess.PIPE if check else asyncio.subprocess.DEVNULL,
|
87
93
|
)
|
88
94
|
|
89
95
|
else:
|
@@ -94,7 +100,7 @@ async def run_process_async(
|
|
94
100
|
cwd=cwd,
|
95
101
|
env=env,
|
96
102
|
stdout=asyncio.subprocess.DEVNULL,
|
97
|
-
stderr=asyncio.subprocess.PIPE,
|
103
|
+
stderr=asyncio.subprocess.PIPE if check else asyncio.subprocess.DEVNULL,
|
98
104
|
)
|
99
105
|
|
100
106
|
stdout, stderr = await proc.communicate()
|
@@ -102,9 +108,5 @@ async def run_process_async(
|
|
102
108
|
assert stdout is None
|
103
109
|
assert proc.returncode is not None
|
104
110
|
|
105
|
-
ret = CompletedProcess(cmd, proc.returncode, None, stderr.decode())
|
106
|
-
|
107
111
|
if check:
|
108
|
-
|
109
|
-
|
110
|
-
return ret
|
112
|
+
_check(proc.returncode, cmd, stderr.decode())
|
@@ -1,156 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
from contextlib import suppress
|
3
|
-
|
4
|
-
if sys.version_info >= (3, 9):
|
5
|
-
from collections.abc import Mapping
|
6
|
-
else:
|
7
|
-
from typing import Mapping
|
8
|
-
|
9
|
-
from .._util import is_sequence
|
10
|
-
from ._base import FoamDict
|
11
|
-
|
12
|
-
|
13
|
-
def _serialize_switch(data: FoamDict._SetData) -> str:
|
14
|
-
if data is True:
|
15
|
-
return "yes"
|
16
|
-
elif data is False:
|
17
|
-
return "no"
|
18
|
-
else:
|
19
|
-
raise TypeError(f"Not a bool: {type(data)}")
|
20
|
-
|
21
|
-
|
22
|
-
def _serialize_list(
|
23
|
-
data: FoamDict._SetData,
|
24
|
-
) -> str:
|
25
|
-
if is_sequence(data):
|
26
|
-
return f"({' '.join(_serialize_data_entry(v) for v in data)})"
|
27
|
-
else:
|
28
|
-
raise TypeError(f"Not a valid sequence: {type(data)}")
|
29
|
-
|
30
|
-
|
31
|
-
def _serialize_field(
|
32
|
-
data: FoamDict._SetData,
|
33
|
-
) -> str:
|
34
|
-
if is_sequence(data):
|
35
|
-
try:
|
36
|
-
s = _serialize_list(data)
|
37
|
-
except TypeError:
|
38
|
-
raise TypeError(f"Not a valid field: {type(data)}") from None
|
39
|
-
else:
|
40
|
-
if not is_sequence(data[0]) and len(data) < 10:
|
41
|
-
return f"uniform {s}"
|
42
|
-
else:
|
43
|
-
if not is_sequence(data[0]):
|
44
|
-
kind = "scalar"
|
45
|
-
elif len(data[0]) == 3:
|
46
|
-
kind = "vector"
|
47
|
-
elif len(data[0]) == 6:
|
48
|
-
kind = "symmTensor"
|
49
|
-
elif len(data[0]) == 9:
|
50
|
-
kind = "tensor"
|
51
|
-
else:
|
52
|
-
raise TypeError(
|
53
|
-
f"Unsupported sequence length for field: {len(data[0])}"
|
54
|
-
)
|
55
|
-
return f"nonuniform List<{kind}> {len(data)}{s}"
|
56
|
-
else:
|
57
|
-
return f"uniform {data}"
|
58
|
-
|
59
|
-
|
60
|
-
def _serialize_dimensions(
|
61
|
-
data: FoamDict._SetData,
|
62
|
-
) -> str:
|
63
|
-
if is_sequence(data) and len(data) == 7:
|
64
|
-
return f"[{' '.join(str(v) for v in data)}]"
|
65
|
-
else:
|
66
|
-
raise TypeError(f"Not a valid dimension set: {type(data)}")
|
67
|
-
|
68
|
-
|
69
|
-
def _serialize_dimensioned(
|
70
|
-
data: FoamDict._SetData,
|
71
|
-
) -> str:
|
72
|
-
if isinstance(data, FoamDict.Dimensioned):
|
73
|
-
if data.name is not None:
|
74
|
-
return f"{data.name} {_serialize_dimensions(data.dimensions)} {_serialize_data_entry(data.value)}"
|
75
|
-
else:
|
76
|
-
return f"{_serialize_dimensions(data.dimensions)} {_serialize_data_entry(data.value)}"
|
77
|
-
else:
|
78
|
-
raise TypeError(f"Not a valid dimensioned value: {type(data)}")
|
79
|
-
|
80
|
-
|
81
|
-
def _serialize_data_entry(
|
82
|
-
data: FoamDict._SetData,
|
83
|
-
*,
|
84
|
-
assume_field: bool = False,
|
85
|
-
assume_dimensions: bool = False,
|
86
|
-
) -> str:
|
87
|
-
if isinstance(data, FoamDict.DimensionSet) or assume_dimensions:
|
88
|
-
with suppress(TypeError):
|
89
|
-
return _serialize_dimensions(data)
|
90
|
-
|
91
|
-
if assume_field:
|
92
|
-
with suppress(TypeError):
|
93
|
-
return _serialize_field(data)
|
94
|
-
|
95
|
-
with suppress(TypeError):
|
96
|
-
return _serialize_dimensioned(data)
|
97
|
-
|
98
|
-
with suppress(TypeError):
|
99
|
-
return _serialize_list(data)
|
100
|
-
|
101
|
-
with suppress(TypeError):
|
102
|
-
return _serialize_switch(data)
|
103
|
-
|
104
|
-
with suppress(TypeError):
|
105
|
-
return _serialize_dictionary(data)
|
106
|
-
|
107
|
-
return str(data)
|
108
|
-
|
109
|
-
|
110
|
-
def _serialize_data_entries(
|
111
|
-
data: FoamDict._SetData,
|
112
|
-
*,
|
113
|
-
assume_field: bool = False,
|
114
|
-
assume_dimensions: bool = False,
|
115
|
-
) -> str:
|
116
|
-
if isinstance(data, FoamDict.DimensionSet) or assume_dimensions:
|
117
|
-
with suppress(TypeError):
|
118
|
-
return _serialize_dimensions(data)
|
119
|
-
|
120
|
-
if assume_field:
|
121
|
-
with suppress(TypeError):
|
122
|
-
return _serialize_field(data)
|
123
|
-
|
124
|
-
if isinstance(data, tuple):
|
125
|
-
return " ".join(_serialize_data_entry(v) for v in data)
|
126
|
-
|
127
|
-
return _serialize_data_entry(data)
|
128
|
-
|
129
|
-
|
130
|
-
def _serialize_dictionary(
|
131
|
-
data: FoamDict._SetData,
|
132
|
-
) -> str:
|
133
|
-
if isinstance(data, Mapping):
|
134
|
-
return "\n".join(serialize_keyword_entry(k, v) for k, v in data.items())
|
135
|
-
else:
|
136
|
-
raise TypeError(f"Not a valid dictionary: {type(data)}")
|
137
|
-
|
138
|
-
|
139
|
-
def serialize_keyword_entry(
|
140
|
-
keyword: str,
|
141
|
-
data: FoamDict._SetData,
|
142
|
-
*,
|
143
|
-
assume_field: bool = False,
|
144
|
-
assume_dimensions: bool = False,
|
145
|
-
) -> str:
|
146
|
-
with suppress(TypeError):
|
147
|
-
return f"{keyword}\n{{\n{_serialize_dictionary(data)}\n}}"
|
148
|
-
|
149
|
-
data = _serialize_data_entries(
|
150
|
-
data, assume_field=assume_field, assume_dimensions=assume_dimensions
|
151
|
-
)
|
152
|
-
|
153
|
-
if not data:
|
154
|
-
return f"{keyword};"
|
155
|
-
else:
|
156
|
-
return f"{keyword} {data};"
|
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
|