foamlib 0.8.6__py3-none-any.whl → 0.8.7__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """A Python interface for interacting with OpenFOAM."""
2
2
 
3
- __version__ = "0.8.6"
3
+ __version__ = "0.8.7"
4
4
 
5
5
  from ._cases import (
6
6
  AsyncFoamCase,
foamlib/_cases/_async.py CHANGED
@@ -99,6 +99,9 @@ class AsyncFoamCase(FoamCaseRunBase):
99
99
  cpus: int,
100
100
  **kwargs: Any,
101
101
  ) -> None:
102
+ if isinstance(cmd, str):
103
+ cmd = [*AsyncFoamCase._SHELL, cmd]
104
+
102
105
  async with AsyncFoamCase._cpus(cpus):
103
106
  await run_async(cmd, **kwargs)
104
107
 
foamlib/_cases/_run.py CHANGED
@@ -10,13 +10,16 @@ from contextlib import contextmanager
10
10
  from pathlib import Path
11
11
  from typing import IO, TYPE_CHECKING, Any
12
12
 
13
+ from rich.progress import Progress
14
+
15
+ from ._util import SingletonContextManager
16
+
13
17
  if sys.version_info >= (3, 9):
14
18
  from collections.abc import (
15
19
  Callable,
16
20
  Collection,
17
21
  Coroutine,
18
22
  Generator,
19
- Mapping,
20
23
  Sequence,
21
24
  )
22
25
  from collections.abc import Set as AbstractSet
@@ -27,7 +30,6 @@ else:
27
30
  Collection,
28
31
  Coroutine,
29
32
  Generator,
30
- Mapping,
31
33
  Sequence,
32
34
  )
33
35
 
@@ -68,6 +70,10 @@ class FoamCaseRunBase(FoamCaseBase):
68
70
 
69
71
  return ret
70
72
 
73
+ _SHELL = ("bash", "-c")
74
+
75
+ __progress = SingletonContextManager(Progress)
76
+
71
77
  def __delitem__(self, key: int | float | str) -> None:
72
78
  shutil.rmtree(self[key].path)
73
79
 
@@ -255,38 +261,60 @@ class FoamCaseRunBase(FoamCaseBase):
255
261
 
256
262
  return script
257
263
 
258
- def __env(self, *, shell: bool) -> Mapping[str, str] | None:
259
- sip_workaround = os.environ.get(
260
- "FOAM_LD_LIBRARY_PATH", ""
261
- ) and not os.environ.get("DYLD_LIBRARY_PATH", "")
262
-
263
- if not shell or sip_workaround:
264
- env = os.environ.copy()
265
-
266
- if not shell:
267
- env["PWD"] = str(self.path)
268
-
269
- if sip_workaround:
270
- env["DYLD_LIBRARY_PATH"] = env["FOAM_LD_LIBRARY_PATH"]
271
-
272
- return env
273
- return None
274
-
275
264
  @contextmanager
276
265
  def __output(
277
266
  self, cmd: Sequence[str | os.PathLike[str]] | str, *, log: bool
278
- ) -> Generator[tuple[int | IO[bytes], int | IO[bytes]], None, None]:
267
+ ) -> Generator[tuple[int | IO[str], int | IO[str]], None, None]:
279
268
  if log:
280
269
  if isinstance(cmd, str):
281
270
  name = shlex.split(cmd)[0]
282
271
  else:
283
272
  name = Path(cmd[0]).name if isinstance(cmd[0], os.PathLike) else cmd[0]
284
273
 
285
- with (self.path / f"log.{name}").open("ab") as stdout:
274
+ with (self.path / f"log.{name}").open("a") as stdout:
286
275
  yield stdout, STDOUT
287
276
  else:
288
277
  yield DEVNULL, DEVNULL
289
278
 
279
+ @contextmanager
280
+ def __process_stdout(
281
+ self, cmd: Sequence[str | os.PathLike[str]] | str
282
+ ) -> Generator[Callable[[str], None], None, None]:
283
+ if isinstance(cmd, str):
284
+ name = shlex.split(cmd)[0]
285
+ else:
286
+ name = Path(cmd[0]).name if isinstance(cmd[0], os.PathLike) else cmd[0]
287
+
288
+ try:
289
+ with self.control_dict as control_dict:
290
+ if control_dict["stopAt"] == "endTime":
291
+ control_dict_end_time = control_dict["endTime"]
292
+ if isinstance(control_dict_end_time, (int, float)):
293
+ end_time = control_dict_end_time
294
+ else:
295
+ end_time = None
296
+ else:
297
+ end_time = None
298
+ except (KeyError, FileNotFoundError):
299
+ end_time = None
300
+
301
+ with self.__progress as progress:
302
+ task = progress.add_task(f"({self.name}) Running {name}...", total=None)
303
+
304
+ def process_stdout(line: str) -> None:
305
+ if line.startswith("Time = "):
306
+ try:
307
+ time = float(line.split()[2])
308
+ except ValueError:
309
+ progress.update(task)
310
+ else:
311
+ progress.update(task, completed=time, total=end_time)
312
+ else:
313
+ progress.update(task)
314
+
315
+ yield process_stdout
316
+ progress.update(task, completed=1, total=1)
317
+
290
318
  def __mkrundir(self) -> Path:
291
319
  d = Path(os.environ["FOAM_RUN"], "foamlib")
292
320
  d.mkdir(parents=True, exist_ok=True)
@@ -379,15 +407,16 @@ class FoamCaseRunBase(FoamCaseBase):
379
407
  if cpus is None:
380
408
  cpus = 1
381
409
 
382
- with self.__output(cmd, log=log) as (stdout, stderr):
410
+ with self.__output(cmd, log=log) as (stdout, stderr), self.__process_stdout(
411
+ cmd
412
+ ) as process_stdout:
383
413
  if parallel:
384
414
  if isinstance(cmd, str):
385
415
  cmd = [
386
416
  "mpiexec",
387
417
  "-n",
388
418
  str(cpus),
389
- "/bin/sh",
390
- "-c",
419
+ *FoamCaseRunBase._SHELL,
391
420
  f"{cmd} -parallel",
392
421
  ]
393
422
  else:
@@ -396,11 +425,11 @@ class FoamCaseRunBase(FoamCaseBase):
396
425
  yield self._run(
397
426
  cmd,
398
427
  cpus=cpus,
428
+ case=self,
399
429
  check=check,
400
- cwd=self.path,
401
- env=self.__env(shell=isinstance(cmd, str)),
402
430
  stdout=stdout,
403
431
  stderr=stderr,
432
+ process_stdout=process_stdout,
404
433
  **kwargs,
405
434
  )
406
435
 
foamlib/_cases/_slurm.py CHANGED
@@ -31,10 +31,10 @@ class AsyncSlurmFoamCase(AsyncFoamCase):
31
31
  await AsyncFoamCase._run(cmd, cpus=cpus, **kwargs)
32
32
  return
33
33
 
34
- if cpus >= 1:
35
- if isinstance(cmd, str):
36
- cmd = ["/bin/sh", "-c", cmd]
34
+ if isinstance(cmd, str):
35
+ cmd = [*AsyncSlurmFoamCase._SHELL, cmd]
37
36
 
37
+ if cpus >= 1:
38
38
  if cpus == 1:
39
39
  cmd = ["srun", *cmd]
40
40
 
@@ -1,18 +1,18 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
+ import os
5
+ import selectors
4
6
  import subprocess
5
7
  import sys
6
- from io import BytesIO
7
- from typing import IO, TYPE_CHECKING
8
-
9
- if TYPE_CHECKING:
10
- import os
8
+ from io import StringIO
9
+ from pathlib import Path
10
+ from typing import IO
11
11
 
12
12
  if sys.version_info >= (3, 9):
13
- from collections.abc import Mapping, Sequence
13
+ from collections.abc import Callable, Mapping, Sequence
14
14
  else:
15
- from typing import Mapping, Sequence
15
+ from typing import Callable, Mapping, Sequence
16
16
 
17
17
  CompletedProcess = subprocess.CompletedProcess
18
18
 
@@ -32,46 +32,72 @@ PIPE = subprocess.PIPE
32
32
  STDOUT = subprocess.STDOUT
33
33
 
34
34
 
35
+ def _env(case: os.PathLike[str]) -> Mapping[str, str]:
36
+ env = os.environ.copy()
37
+
38
+ env["PWD"] = str(Path(case))
39
+
40
+ if os.environ.get("FOAM_LD_LIBRARY_PATH", "") and not os.environ.get(
41
+ "DYLD_LIBRARY_PATH", ""
42
+ ):
43
+ env["DYLD_LIBRARY_PATH"] = env["FOAM_LD_LIBRARY_PATH"]
44
+
45
+ return env
46
+
47
+
35
48
  def run_sync(
36
- cmd: Sequence[str | os.PathLike[str]] | str,
49
+ cmd: Sequence[str | os.PathLike[str]],
37
50
  *,
51
+ case: os.PathLike[str],
38
52
  check: bool = True,
39
- cwd: os.PathLike[str] | None = None,
40
- env: Mapping[str, str] | None = None,
41
- stdout: int | IO[bytes] | None = None,
42
- stderr: int | IO[bytes] | None = None,
43
- ) -> CompletedProcess[bytes]:
44
- if not isinstance(cmd, str) and sys.version_info < (3, 8):
53
+ stdout: int | IO[str] = DEVNULL,
54
+ stderr: int | IO[str] = STDOUT,
55
+ process_stdout: Callable[[str], None] = lambda _: None,
56
+ ) -> CompletedProcess[str]:
57
+ if sys.version_info < (3, 8):
45
58
  cmd = [str(arg) for arg in cmd]
46
59
 
47
- proc = subprocess.Popen(
60
+ with subprocess.Popen(
48
61
  cmd,
49
- cwd=cwd,
50
- env=env,
51
- stdout=stdout,
62
+ cwd=case,
63
+ env=_env(case),
64
+ stdout=PIPE,
52
65
  stderr=PIPE,
53
- shell=isinstance(cmd, str),
54
- )
55
-
56
- if stderr == STDOUT:
57
- stderr = stdout
58
- if stderr not in (PIPE, DEVNULL):
59
- stderr_copy = BytesIO()
60
-
61
- assert not isinstance(stderr, int)
62
- if stderr is None:
63
- stderr = sys.stderr.buffer
64
-
66
+ text=True,
67
+ ) as proc:
68
+ assert proc.stdout is not None
65
69
  assert proc.stderr is not None
66
- for line in proc.stderr:
67
- stderr.write(line)
68
- stderr_copy.write(line)
69
70
 
70
- output, _ = proc.communicate()
71
- assert not _
72
- error = stderr_copy.getvalue()
73
- else:
74
- output, error = proc.communicate()
71
+ output = StringIO() if stdout is PIPE else None
72
+ error = StringIO()
73
+
74
+ if stderr is STDOUT:
75
+ stderr = stdout
76
+
77
+ with selectors.DefaultSelector() as selector:
78
+ selector.register(proc.stdout, selectors.EVENT_READ)
79
+ selector.register(proc.stderr, selectors.EVENT_READ)
80
+ open_streams = {proc.stdout, proc.stderr}
81
+ while open_streams:
82
+ for key, _ in selector.select():
83
+ assert key.fileobj in open_streams
84
+ line = key.fileobj.readline() # type: ignore [union-attr]
85
+ if not line:
86
+ selector.unregister(key.fileobj)
87
+ open_streams.remove(key.fileobj) # type: ignore [arg-type]
88
+ elif key.fileobj is proc.stdout:
89
+ process_stdout(line)
90
+ if output is not None:
91
+ output.write(line)
92
+ if stdout not in (DEVNULL, PIPE):
93
+ assert not isinstance(stdout, int)
94
+ stdout.write(line)
95
+ else:
96
+ assert key.fileobj is proc.stderr
97
+ error.write(line)
98
+ if stderr not in (DEVNULL, PIPE):
99
+ assert not isinstance(stderr, int)
100
+ stderr.write(line)
75
101
 
76
102
  assert proc.returncode is not None
77
103
 
@@ -79,74 +105,84 @@ def run_sync(
79
105
  raise CalledProcessError(
80
106
  returncode=proc.returncode,
81
107
  cmd=cmd,
82
- output=output,
83
- stderr=error,
108
+ output=output.getvalue() if output is not None else None,
109
+ stderr=error.getvalue(),
84
110
  )
85
111
 
86
112
  return CompletedProcess(
87
- cmd, returncode=proc.returncode, stdout=output, stderr=error
113
+ cmd,
114
+ returncode=proc.returncode,
115
+ stdout=output.getvalue() if output is not None else None,
116
+ stderr=error.getvalue(),
88
117
  )
89
118
 
90
119
 
91
120
  async def run_async(
92
- cmd: Sequence[str | os.PathLike[str]] | str,
121
+ cmd: Sequence[str | os.PathLike[str]],
93
122
  *,
123
+ case: os.PathLike[str],
94
124
  check: bool = True,
95
- cwd: os.PathLike[str] | None = None,
96
- env: Mapping[str, str] | None = None,
97
- stdout: int | IO[bytes] | None = None,
98
- stderr: int | IO[bytes] | None = None,
99
- ) -> CompletedProcess[bytes]:
100
- if isinstance(cmd, str):
101
- proc = await asyncio.create_subprocess_shell(
102
- cmd,
103
- cwd=cwd,
104
- env=env,
105
- stdout=stdout,
106
- stderr=PIPE,
107
- )
125
+ stdout: int | IO[str] = DEVNULL,
126
+ stderr: int | IO[str] = STDOUT,
127
+ process_stdout: Callable[[str], None] = lambda _: None,
128
+ ) -> CompletedProcess[str]:
129
+ if sys.version_info < (3, 8):
130
+ cmd = [str(arg) for arg in cmd]
108
131
 
109
- else:
110
- if sys.version_info < (3, 8):
111
- cmd = [str(arg) for arg in cmd]
112
- proc = await asyncio.create_subprocess_exec(
113
- *cmd,
114
- cwd=cwd,
115
- env=env,
116
- stdout=stdout,
117
- stderr=PIPE,
118
- )
132
+ proc = await asyncio.create_subprocess_exec(
133
+ *cmd,
134
+ cwd=case,
135
+ env=_env(case),
136
+ stdout=PIPE,
137
+ stderr=PIPE,
138
+ )
119
139
 
120
- if stderr == STDOUT:
140
+ if stderr is STDOUT:
121
141
  stderr = stdout
122
- if stderr not in (PIPE, DEVNULL):
123
- stderr_copy = BytesIO()
124
-
125
- assert not isinstance(stderr, int)
126
- if stderr is None:
127
- stderr = sys.stderr.buffer
128
-
129
- assert proc.stderr is not None
130
- async for line in proc.stderr:
131
- stderr.write(line)
132
- stderr_copy.write(line)
133
-
134
- output, _ = await proc.communicate()
135
- assert not _
136
- error = stderr_copy.getvalue()
137
- else:
138
- output, error = await proc.communicate()
139
142
 
143
+ output = StringIO() if stdout is PIPE else None
144
+ error = StringIO()
145
+
146
+ async def tee_stdout() -> None:
147
+ while True:
148
+ assert proc.stdout is not None
149
+ line = (await proc.stdout.readline()).decode()
150
+ if not line:
151
+ break
152
+ process_stdout(line)
153
+ if output is not None:
154
+ output.write(line)
155
+ if stdout not in (DEVNULL, PIPE):
156
+ assert not isinstance(stdout, int)
157
+ stdout.write(line)
158
+
159
+ async def tee_stderr() -> None:
160
+ while True:
161
+ assert proc.stderr is not None
162
+ line = (await proc.stderr.readline()).decode()
163
+ if not line:
164
+ break
165
+ error.write(line)
166
+ if stderr not in (DEVNULL, PIPE):
167
+ assert not isinstance(stderr, int)
168
+ stderr.write(line)
169
+
170
+ await asyncio.gather(tee_stdout(), tee_stderr())
171
+
172
+ await proc.wait()
140
173
  assert proc.returncode is not None
141
174
 
142
175
  if check and proc.returncode != 0:
143
176
  raise CalledProcessError(
144
177
  returncode=proc.returncode,
145
178
  cmd=cmd,
146
- output=output,
147
- stderr=error,
179
+ output=output.getvalue() if output is not None else None,
180
+ stderr=error.getvalue(),
148
181
  )
149
182
 
150
183
  return CompletedProcess(
151
- cmd, returncode=proc.returncode, stdout=output, stderr=error
184
+ cmd,
185
+ returncode=proc.returncode,
186
+ stdout=output.getvalue() if output is not None else None,
187
+ stderr=error.getvalue(),
152
188
  )
foamlib/_cases/_sync.py CHANGED
@@ -58,6 +58,9 @@ class FoamCase(FoamCaseRunBase):
58
58
  cpus: int,
59
59
  **kwargs: Any,
60
60
  ) -> None:
61
+ if isinstance(cmd, str):
62
+ cmd = [*FoamCase._SHELL, cmd]
63
+
61
64
  run_sync(cmd, **kwargs)
62
65
 
63
66
  @staticmethod
foamlib/_cases/_util.py CHANGED
@@ -2,7 +2,17 @@ from __future__ import annotations
2
2
 
3
3
  import functools
4
4
  import sys
5
- from typing import TYPE_CHECKING, Any, AsyncContextManager, Callable, Generic, TypeVar
5
+ import threading
6
+ from typing import (
7
+ TYPE_CHECKING,
8
+ Any,
9
+ AsyncContextManager,
10
+ Callable,
11
+ ContextManager,
12
+ Generic,
13
+ TypeVar,
14
+ cast,
15
+ )
6
16
 
7
17
  if TYPE_CHECKING:
8
18
  from types import TracebackType
@@ -54,3 +64,33 @@ def awaitableasynccontextmanager(
54
64
  return _AwaitableAsyncContextManager(cm(*args, **kwargs))
55
65
 
56
66
  return f
67
+
68
+
69
+ class SingletonContextManager(Generic[R]):
70
+ def __init__(self, factory: Callable[[], ContextManager[R]]) -> None:
71
+ self._factory = factory
72
+ self._users = 0
73
+ self._cm: ContextManager[R] | None = None
74
+ self._ret: R | None = None
75
+ self._lock = threading.Lock()
76
+
77
+ def __enter__(self) -> R:
78
+ with self._lock:
79
+ if self._users == 0:
80
+ self._cm = self._factory()
81
+ self._ret = self._cm.__enter__()
82
+ self._users += 1
83
+ return cast("R", self._ret)
84
+
85
+ def __exit__(
86
+ self,
87
+ exc_type: type[BaseException] | None,
88
+ exc_val: BaseException | None,
89
+ exc_tb: TracebackType | None,
90
+ ) -> bool | None:
91
+ with self._lock:
92
+ self._users -= 1
93
+ if self._users == 0:
94
+ assert self._cm is not None
95
+ return self._cm.__exit__(exc_type, exc_val, exc_tb)
96
+ return False
@@ -167,7 +167,7 @@ def _dict_of(
167
167
 
168
168
  if directive is not None:
169
169
  assert data_entry is not None
170
- keyword_entry |= directive + data_entry + LineEnd().suppress() # type: ignore [no-untyped-call]
170
+ keyword_entry |= directive + data_entry + LineEnd().suppress()
171
171
 
172
172
  if located:
173
173
  keyword_entry = Located(keyword_entry)
@@ -198,7 +198,7 @@ def _keyword_entry_of(
198
198
 
199
199
  if directive is not None:
200
200
  assert data_entry is not None
201
- keyword_entry |= directive + data_entry + LineEnd().suppress() # type: ignore [no-untyped-call]
201
+ keyword_entry |= directive + data_entry + LineEnd().suppress()
202
202
 
203
203
  if located:
204
204
  keyword_entry = Located(keyword_entry)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: foamlib
3
- Version: 0.8.6
3
+ Version: 0.8.7
4
4
  Summary: A Python interface for interacting with OpenFOAM
5
5
  Project-URL: Homepage, https://github.com/gerlero/foamlib
6
6
  Project-URL: Repository, https://github.com/gerlero/foamlib
@@ -29,6 +29,7 @@ Requires-Dist: aioshutil<2,>=1
29
29
  Requires-Dist: numpy<3,>=1
30
30
  Requires-Dist: numpy<3,>=1.25.0; python_version >= '3.10'
31
31
  Requires-Dist: pyparsing<4,>=3.1.2
32
+ Requires-Dist: rich<14,>=13
32
33
  Requires-Dist: typing-extensions<5,>=4; python_version < '3.11'
33
34
  Provides-Extra: dev
34
35
  Requires-Dist: mypy<2,>=1; extra == 'dev'
@@ -0,0 +1,20 @@
1
+ foamlib/__init__.py,sha256=TrTrsv_QjPqa16duuXQl5FgjxRPwuHlhO-MHOtxUzdY,452
2
+ foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ foamlib/_cases/__init__.py,sha256=_A1TTHuQfS9FH2_33lSEyLtOJZGFHZBco1tWJCVOHks,358
4
+ foamlib/_cases/_async.py,sha256=vXpq5T2gDomuawARsLaUEMjUBhMsZK58q7iVwQpXsYE,7903
5
+ foamlib/_cases/_base.py,sha256=37oBbM3NM-hpG7dKewZvyJNtqSAogMurcbmX-wLIgMU,6727
6
+ foamlib/_cases/_run.py,sha256=IRsozHdXx5tjLYYIWMiKGeaf5188unhp5VwIAZLlr3E,15578
7
+ foamlib/_cases/_slurm.py,sha256=Hzpf5Ugahwq7sUsCfhZ6JgXDOdkoYGGsHGiO7NV8uFs,2331
8
+ foamlib/_cases/_subprocess.py,sha256=VHV2SuOLqa711an6kCuvN6UlIkeh4qqFfdrpNoKzQps,5630
9
+ foamlib/_cases/_sync.py,sha256=e06aGGZ9n6WTWK9eWZhrezsT4yebGhKPE0sn0nwQH8A,5977
10
+ foamlib/_cases/_util.py,sha256=QCizfbuJdOCeF9ogU2R-y-iWX5kfaOA4U2W68t6QlOM,2544
11
+ foamlib/_files/__init__.py,sha256=q1vkjXnjnSZvo45jPAICpWeF2LZv5V6xfzAR6S8fS5A,96
12
+ foamlib/_files/_files.py,sha256=YAKw3RHEw8eCja4JAxobp6BC-2Kyy7AvG1O7yOqyMic,15414
13
+ foamlib/_files/_io.py,sha256=BGbbm6HKxL2ka0YMCmHqZQZ1R4PPQlkvWWb4FHMAS8k,2217
14
+ foamlib/_files/_parsing.py,sha256=XrqG8IcTM--qZYqEHYO_jcCTb7ev9M9kz75T_DQtPuc,14047
15
+ foamlib/_files/_serialization.py,sha256=PvMzNyTja6OKT_GUfExTulx9nMLBjfu0-9yThCKbvxs,5227
16
+ foamlib/_files/_types.py,sha256=m-fFjJnS4sFSavDsijlXpAfEhnbh10RBumSHAT0GOgQ,3408
17
+ foamlib-0.8.7.dist-info/METADATA,sha256=HVzB10Bdz97hbXxBDunpGy-_seeNduk5msDAKVCXmx4,7996
18
+ foamlib-0.8.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
19
+ foamlib-0.8.7.dist-info/licenses/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
20
+ foamlib-0.8.7.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- foamlib/__init__.py,sha256=fTmSxCwa3jslIzrR21plDa2dAdw0v7tFSX1pBqOi4_A,452
2
- foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- foamlib/_cases/__init__.py,sha256=_A1TTHuQfS9FH2_33lSEyLtOJZGFHZBco1tWJCVOHks,358
4
- foamlib/_cases/_async.py,sha256=onECxRLQCF7Kd-GeuLqH_Xv3gbMMhKOSbFaUG5Ttgmk,7822
5
- foamlib/_cases/_base.py,sha256=37oBbM3NM-hpG7dKewZvyJNtqSAogMurcbmX-wLIgMU,6727
6
- foamlib/_cases/_run.py,sha256=lveqKZium_qK_eTxYE8jOjwx0eiIoolCBbi56-zLw1o,14420
7
- foamlib/_cases/_slurm.py,sha256=kj4wqgr3foMyAoUkoHOZODRBmVqH1B9KqAIEEjM8ZBg,2328
8
- foamlib/_cases/_subprocess.py,sha256=6BlBRxknj2-BFcGkx7oVcuL63_utSaY1Axmsc1qV9j8,3887
9
- foamlib/_cases/_sync.py,sha256=2BJXB7Nzldb4OgPukqupgYqdceUGkI2mYhhtGPWEBrc,5901
10
- foamlib/_cases/_util.py,sha256=tK4SM5WT3eEgGsFLnidIySbom1qowBAua9z13gipKJk,1518
11
- foamlib/_files/__init__.py,sha256=q1vkjXnjnSZvo45jPAICpWeF2LZv5V6xfzAR6S8fS5A,96
12
- foamlib/_files/_files.py,sha256=YAKw3RHEw8eCja4JAxobp6BC-2Kyy7AvG1O7yOqyMic,15414
13
- foamlib/_files/_io.py,sha256=BGbbm6HKxL2ka0YMCmHqZQZ1R4PPQlkvWWb4FHMAS8k,2217
14
- foamlib/_files/_parsing.py,sha256=9MOFG6Akk-xYIHs84aY8rHL2cGeWQLx7wQE4x7mfJek,14115
15
- foamlib/_files/_serialization.py,sha256=PvMzNyTja6OKT_GUfExTulx9nMLBjfu0-9yThCKbvxs,5227
16
- foamlib/_files/_types.py,sha256=m-fFjJnS4sFSavDsijlXpAfEhnbh10RBumSHAT0GOgQ,3408
17
- foamlib-0.8.6.dist-info/METADATA,sha256=t4nSfDbDQtd2gelYCgSdFv2x6YWg8SFEQLb7Ol7ePAU,7968
18
- foamlib-0.8.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
19
- foamlib-0.8.6.dist-info/licenses/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
20
- foamlib-0.8.6.dist-info/RECORD,,