foamlib 0.7.1__py3-none-any.whl → 0.7.3__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.7.1"
3
+ __version__ = "0.7.3"
4
4
 
5
5
  from ._cases import (
6
6
  AsyncFoamCase,
foamlib/_files/_files.py CHANGED
@@ -19,10 +19,10 @@ from ._io import FoamFileIO
19
19
  from ._serialization import Kind, dumps, normalize
20
20
  from ._types import (
21
21
  Data,
22
- DataEntry,
23
22
  Dict_,
24
23
  Dimensioned,
25
24
  DimensionSet,
25
+ Entry,
26
26
  Field,
27
27
  File,
28
28
  MutableData,
@@ -57,13 +57,13 @@ class FoamFile(
57
57
  self._file = _file
58
58
  self._keywords = _keywords
59
59
 
60
- def __getitem__(self, keyword: str) -> DataEntry | FoamFile.SubDict:
60
+ def __getitem__(self, keyword: str) -> Data | FoamFile.SubDict:
61
61
  return self._file[(*self._keywords, keyword)]
62
62
 
63
63
  def __setitem__(
64
64
  self,
65
65
  keyword: str,
66
- data: Data,
66
+ data: Entry,
67
67
  ) -> None:
68
68
  self._file[(*self._keywords, keyword)] = data
69
69
 
@@ -174,7 +174,7 @@ class FoamFile(
174
174
 
175
175
  def __getitem__(
176
176
  self, keywords: str | tuple[str, ...] | None
177
- ) -> DataEntry | FoamFile.SubDict:
177
+ ) -> Data | FoamFile.SubDict:
178
178
  if not keywords:
179
179
  keywords = ()
180
180
  elif not isinstance(keywords, tuple):
@@ -190,7 +190,7 @@ class FoamFile(
190
190
  return FoamFile.SubDict(self, keywords)
191
191
  return deepcopy(value)
192
192
 
193
- def __setitem__(self, keywords: str | tuple[str, ...] | None, data: Data) -> None:
193
+ def __setitem__(self, keywords: str | tuple[str, ...] | None, data: Entry) -> None:
194
194
  if not keywords:
195
195
  keywords = ()
196
196
  elif not isinstance(keywords, tuple):
@@ -438,7 +438,7 @@ class FoamFieldFile(FoamFile):
438
438
 
439
439
  def __getitem__(
440
440
  self, keywords: str | tuple[str, ...] | None
441
- ) -> DataEntry | FoamFile.SubDict:
441
+ ) -> Data | FoamFile.SubDict:
442
442
  if not keywords:
443
443
  keywords = ()
444
444
  elif not isinstance(keywords, tuple):
@@ -16,7 +16,6 @@ else:
16
16
  from typing import Any as EllipsisType
17
17
 
18
18
  from pyparsing import (
19
- CharsNotIn,
20
19
  Combine,
21
20
  Dict,
22
21
  Forward,
@@ -28,20 +27,22 @@ from pyparsing import (
28
27
  Opt,
29
28
  ParserElement,
30
29
  ParseResults,
31
- QuotedString,
32
30
  Regex,
33
31
  Word,
34
32
  common,
35
33
  counted_array,
34
+ dbl_quoted_string,
36
35
  identchars,
37
36
  printables,
38
37
  )
39
38
 
40
- from ._types import DataEntry, Dimensioned, DimensionSet, File
39
+ from ._types import Data, Dimensioned, DimensionSet, File
41
40
 
42
41
 
43
42
  def _list_of(entry: ParserElement) -> ParserElement:
44
- return (
43
+ return Opt(
44
+ Literal("List") + Literal("<") + _IDENTIFIER + Literal(">")
45
+ ).suppress() + (
45
46
  (
46
47
  counted_array(entry, common.integer + Literal("(").suppress())
47
48
  + Literal(")").suppress()
@@ -57,18 +58,52 @@ def _list_of(entry: ParserElement) -> ParserElement:
57
58
  )
58
59
 
59
60
 
60
- def _counted_tensor_list(*, size: int, ignore: Regex) -> ParserElement:
61
- float_pattern = r"[+-]?((\d+\.?\d*(e[+-]?\d+)?)|nan|inf(inity)?)"
62
- ignore_pattern = rf"(?:{ignore.re.pattern}|\s)+"
61
+ def _parse_ascii_field(
62
+ s: str, *, elsize: int, ignore: Regex | None
63
+ ) -> list[float] | list[list[float]]:
64
+ values = [
65
+ float(v)
66
+ for v in (re.sub(ignore.re, " ", s) if ignore is not None else s)
67
+ .replace("(", " ")
68
+ .replace(")", " ")
69
+ .split()
70
+ ]
63
71
 
64
- if size == 1:
72
+ if elsize == 1:
73
+ return values
74
+
75
+ return [values[i : i + elsize] for i in range(0, len(values), elsize)]
76
+
77
+
78
+ def _unpack_binary_field(
79
+ b: bytes, *, elsize: int, length: int
80
+ ) -> list[float] | list[list[float]]:
81
+ float_size = len(b) / elsize / length
82
+ assert float_size in (4, 8)
83
+
84
+ arr = array.array("f" if float_size == 4 else "d", b)
85
+ values = arr.tolist()
86
+
87
+ if elsize == 1:
88
+ return values
89
+
90
+ return [values[i : i + elsize] for i in range(0, len(values), elsize)]
91
+
92
+
93
+ def _counted_tensor_list(
94
+ *, elsize: int = 1, ignore: Regex | None = None
95
+ ) -> ParserElement:
96
+ float_pattern = r"(?i:[+-]?(?:(?:\d+\.?\d*(?:e[+-]?\d+)?)|nan|inf(?:inity)?))"
97
+ ignore_pattern = rf"(?:\s|{ignore.re.pattern})+" if ignore is not None else r"\s+"
98
+
99
+ if elsize == 1:
65
100
  tensor_pattern = float_pattern
66
101
  tensor = common.ieee_float
67
102
  else:
68
- tensor_pattern = rf"\((?:{ignore_pattern})?(?:{float_pattern}{ignore_pattern}){{{size - 1}}}{float_pattern}(?:{ignore_pattern})?\)"
103
+ tensor_pattern = rf"\((?:{ignore_pattern})?(?:{float_pattern}{ignore_pattern}){{{elsize - 1}}}{float_pattern}(?:{ignore_pattern})?\)"
69
104
  tensor = (
70
105
  Literal("(").suppress()
71
- + Group(common.ieee_float[size], aslist=True)
106
+ + Group(common.ieee_float[elsize], aslist=True)
72
107
  + Literal(")").suppress()
73
108
  )
74
109
 
@@ -79,35 +114,29 @@ def _counted_tensor_list(*, size: int, ignore: Regex) -> ParserElement:
79
114
  length = tks[0]
80
115
  assert isinstance(length, int)
81
116
 
82
- list_ <<= Regex(
83
- rf"\((?:{ignore_pattern})?(?:{tensor_pattern}{ignore_pattern}){{{length - 1}}}{tensor_pattern}(?:{ignore_pattern})?\)",
84
- re.IGNORECASE,
85
- )
86
-
87
- count = common.integer.add_parse_action(count_parse_action)
88
-
89
- def list_parse_action(
90
- tks: ParseResults,
91
- ) -> list[list[float]] | list[list[list[float]]]:
92
- values = (
93
- re.sub(ignore.re, " ", tks[0]).replace("(", " ").replace(")", " ").split()
117
+ list_ <<= (
118
+ Regex(
119
+ rf"\((?:{ignore_pattern})?(?:{tensor_pattern}{ignore_pattern}){{{length - 1}}}{tensor_pattern}(?:{ignore_pattern})?\)"
120
+ ).add_parse_action(
121
+ lambda tks: [_parse_ascii_field(tks[0], elsize=elsize, ignore=ignore)]
122
+ )
123
+ | Regex(
124
+ rf"\((?s:.{{{length * elsize * 8}}}|.{{{length * elsize * 4}}})\)"
125
+ ).set_parse_action(
126
+ lambda tks: [
127
+ _unpack_binary_field(
128
+ tks[0][1:-1].encode("latin-1"), elsize=elsize, length=length
129
+ )
130
+ ]
131
+ )
132
+ | (
133
+ Literal("{").suppress() + tensor + Literal("}").suppress()
134
+ ).set_parse_action(lambda tks: [[tks[0]] * length])
94
135
  )
95
136
 
96
- if size == 1:
97
- return [[float(v) for v in values]]
98
-
99
- return [
100
- [
101
- [float(v) for v in values[i : i + size]]
102
- for i in range(0, len(values), size)
103
- ]
104
- ]
137
+ count = common.integer.copy().add_parse_action(count_parse_action)
105
138
 
106
- list_.add_parse_action(list_parse_action)
107
-
108
- return (count.suppress() + list_) | (
109
- common.integer + Literal("{").suppress() + tensor + Literal("}").suppress()
110
- ).set_parse_action(lambda tks: [[tks[1]] * tks[0]])
139
+ return count.suppress() + list_
111
140
 
112
141
 
113
142
  def _keyword_entry_of(
@@ -131,25 +160,6 @@ def _keyword_entry_of(
131
160
  return keyword_entry
132
161
 
133
162
 
134
- def _unpack_binary_field(
135
- tks: ParseResults,
136
- *,
137
- elsize: int = 1,
138
- ) -> Sequence[Sequence[float] | Sequence[Sequence[float]]]:
139
- float_size = len(tks[0]) // elsize
140
-
141
- arr = array.array("f" if float_size == 4 else "d", "".join(tks).encode("latin-1"))
142
-
143
- values: Sequence[float] | Sequence[Sequence[float]]
144
-
145
- if elsize != 1:
146
- values = [arr[i : i + elsize].tolist() for i in range(0, len(arr), elsize)]
147
- else:
148
- values = arr.tolist()
149
-
150
- return [values]
151
-
152
-
153
163
  # https://github.com/pyparsing/pyparsing/pull/584
154
164
  _COMMENT = Regex(r"(?:/\*(?:[^*]|\*(?!/))*\*/)|(?://(?:\\\n|[^\n])*)")
155
165
 
@@ -201,103 +211,27 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
201
211
  (
202
212
  Literal("scalar").suppress()
203
213
  + Literal(">").suppress()
204
- + (
205
- _counted_tensor_list(size=1, ignore=_COMMENT)
206
- | (
207
- (
208
- (
209
- counted_array(
210
- CharsNotIn(exact=8),
211
- common.integer + Literal("(").suppress(),
212
- )
213
- )
214
- | (
215
- counted_array(
216
- CharsNotIn(exact=4),
217
- common.integer + Literal("(").suppress(),
218
- )
219
- )
220
- )
221
- + Literal(")").suppress()
222
- ).set_parse_action(_unpack_binary_field)
223
- )
214
+ + _counted_tensor_list(elsize=1, ignore=_COMMENT)
224
215
  )
225
216
  | (
226
217
  Literal("vector").suppress()
227
218
  + Literal(">").suppress()
228
- + (
229
- _counted_tensor_list(size=3, ignore=_COMMENT)
230
- | (
231
- (
232
- (
233
- counted_array(
234
- CharsNotIn(exact=8 * 3),
235
- common.integer + Literal("(").suppress(),
236
- )
237
- )
238
- | (
239
- counted_array(
240
- CharsNotIn(exact=4 * 3),
241
- common.integer + Literal("(").suppress(),
242
- )
243
- )
244
- )
245
- + Literal(")").suppress()
246
- ).set_parse_action(lambda tks: _unpack_binary_field(tks, elsize=3))
247
- )
219
+ + _counted_tensor_list(elsize=3, ignore=_COMMENT)
248
220
  )
249
221
  | (
250
222
  Literal("symmTensor").suppress()
251
223
  + Literal(">").suppress()
252
- + (
253
- _counted_tensor_list(size=6, ignore=_COMMENT)
254
- | (
255
- (
256
- (
257
- counted_array(
258
- CharsNotIn(exact=8 * 6),
259
- common.integer + Literal("(").suppress(),
260
- )
261
- )
262
- | (
263
- counted_array(
264
- CharsNotIn(exact=4 * 6),
265
- common.integer + Literal("(").suppress(),
266
- )
267
- )
268
- )
269
- + Literal(")").suppress()
270
- ).set_parse_action(lambda tks: _unpack_binary_field(tks, elsize=6))
271
- )
224
+ + _counted_tensor_list(elsize=6, ignore=_COMMENT)
272
225
  )
273
226
  | (
274
227
  Literal("tensor").suppress()
275
228
  + Literal(">").suppress()
276
- + (
277
- _counted_tensor_list(size=9, ignore=_COMMENT)
278
- | (
279
- (
280
- (
281
- counted_array(
282
- CharsNotIn(exact=8 * 9),
283
- common.integer + Literal("(").suppress(),
284
- )
285
- )
286
- | (
287
- counted_array(
288
- CharsNotIn(exact=4 * 9),
289
- common.integer + Literal("(").suppress(),
290
- )
291
- )
292
- )
293
- + Literal(")").suppress()
294
- ).set_parse_action(lambda tks: _unpack_binary_field(tks, elsize=9))
295
- )
229
+ + _counted_tensor_list(elsize=9, ignore=_COMMENT)
296
230
  )
297
231
  )
298
232
  )
299
233
  )
300
- _TOKEN = QuotedString('"', unquote_results=False) | _IDENTIFIER
234
+ _TOKEN = dbl_quoted_string | _IDENTIFIER
301
235
  DATA = Forward()
302
236
  KEYWORD = (
303
237
  _TOKEN
@@ -332,11 +266,11 @@ _FILE = (
332
266
  )
333
267
 
334
268
 
335
- class Parsed(Mapping[Tuple[str, ...], Union[DataEntry, EllipsisType]]):
269
+ class Parsed(Mapping[Tuple[str, ...], Union[Data, EllipsisType]]):
336
270
  def __init__(self, contents: bytes) -> None:
337
271
  self._parsed: MutableMapping[
338
272
  tuple[str, ...],
339
- tuple[int, DataEntry | EllipsisType, int],
273
+ tuple[int, Data | EllipsisType, int],
340
274
  ] = {}
341
275
  for parse_result in _FILE.parse_string(
342
276
  contents.decode("latin-1"), parse_all=True
@@ -349,10 +283,10 @@ class Parsed(Mapping[Tuple[str, ...], Union[DataEntry, EllipsisType]]):
349
283
  @staticmethod
350
284
  def _flatten_result(
351
285
  parse_result: ParseResults, *, _keywords: tuple[str, ...] = ()
352
- ) -> Mapping[tuple[str, ...], tuple[int, DataEntry | EllipsisType, int]]:
286
+ ) -> Mapping[tuple[str, ...], tuple[int, Data | EllipsisType, int]]:
353
287
  ret: MutableMapping[
354
288
  tuple[str, ...],
355
- tuple[int, DataEntry | EllipsisType, int],
289
+ tuple[int, Data | EllipsisType, int],
356
290
  ] = {}
357
291
  start = parse_result.locn_start
358
292
  assert isinstance(start, int)
@@ -379,14 +313,14 @@ class Parsed(Mapping[Tuple[str, ...], Union[DataEntry, EllipsisType]]):
379
313
  ret[(*_keywords, keyword)] = (start, d, end)
380
314
  return ret
381
315
 
382
- def __getitem__(self, keywords: tuple[str, ...]) -> DataEntry | EllipsisType:
316
+ def __getitem__(self, keywords: tuple[str, ...]) -> Data | EllipsisType:
383
317
  _, data, _ = self._parsed[keywords]
384
318
  return data
385
319
 
386
320
  def put(
387
321
  self,
388
322
  keywords: tuple[str, ...],
389
- data: DataEntry | EllipsisType,
323
+ data: Data | EllipsisType,
390
324
  content: bytes,
391
325
  ) -> None:
392
326
  start, end = self.entry_location(keywords, missing_ok=True)
@@ -12,7 +12,7 @@ else:
12
12
  from typing import Mapping, Sequence
13
13
 
14
14
  from ._parsing import DATA, KEYWORD
15
- from ._types import Data, DataEntry, Dimensioned, DimensionSet
15
+ from ._types import Data, Dimensioned, DimensionSet, Entry
16
16
  from ._util import is_sequence
17
17
 
18
18
  try:
@@ -34,14 +34,14 @@ class Kind(Enum):
34
34
 
35
35
 
36
36
  @overload
37
- def normalize(data: DataEntry, *, kind: Kind = Kind.DEFAULT) -> DataEntry: ...
37
+ def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data: ...
38
38
 
39
39
 
40
40
  @overload
41
- def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data: ...
41
+ def normalize(data: Entry, *, kind: Kind = Kind.DEFAULT) -> Entry: ...
42
42
 
43
43
 
44
- def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data:
44
+ def normalize(data: Entry, *, kind: Kind = Kind.DEFAULT) -> Entry:
45
45
  if numpy and isinstance(data, np.ndarray):
46
46
  ret = data.tolist()
47
47
  assert isinstance(ret, list)
@@ -76,7 +76,7 @@ def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data:
76
76
  assert isinstance(data, str)
77
77
  return data
78
78
 
79
- return cast(DataEntry, DATA.parse_string(data, parse_all=True)[0])
79
+ return cast(Data, DATA.parse_string(data, parse_all=True)[0])
80
80
 
81
81
  if isinstance(
82
82
  data,
@@ -89,7 +89,7 @@ def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data:
89
89
 
90
90
 
91
91
  def dumps(
92
- data: Data,
92
+ data: Entry,
93
93
  *,
94
94
  kind: Kind = Kind.DEFAULT,
95
95
  ) -> bytes:
foamlib/_files/_types.py CHANGED
@@ -46,33 +46,36 @@ class Dimensioned:
46
46
 
47
47
 
48
48
  Field = Union[
49
- Tensor, Sequence[Tensor], "np.ndarray[Tuple[int, int], np.dtype[np.generic]]"
49
+ Tensor,
50
+ Sequence[Tensor],
51
+ "np.ndarray[Tuple[int], np.dtype[np.generic]]",
52
+ "np.ndarray[Tuple[int, int], np.dtype[np.generic]]",
50
53
  ]
51
54
 
52
- DataEntry = Union[
55
+ Data = Union[
53
56
  str,
54
57
  int,
55
58
  float,
56
59
  bool,
57
60
  Dimensioned,
58
61
  DimensionSet,
59
- Sequence["Data"],
62
+ Sequence["Entry"],
60
63
  Tensor,
61
64
  Field,
62
65
  ]
63
66
 
64
- Data = Union[
65
- DataEntry,
66
- Mapping[str, "Data"],
67
+ Entry = Union[
68
+ Data,
69
+ Mapping[str, "Entry"],
67
70
  ]
68
71
  """
69
72
  A value that can be stored in an OpenFOAM file.
70
73
  """
71
74
 
72
75
  MutableData = Union[
73
- DataEntry,
76
+ Data,
74
77
  MutableMapping[str, "MutableData"],
75
78
  ]
76
79
 
77
- Dict_ = Dict[str, Union["Data", "Dict_"]]
78
- File = Dict[Optional[str], Union["Data", "Dict_"]]
80
+ Dict_ = Dict[str, Union["Entry", "Dict_"]]
81
+ File = Dict[Optional[str], Union["Entry", "Dict_"]]
foamlib/_files/_util.py CHANGED
@@ -14,10 +14,10 @@ else:
14
14
  from typing_extensions import TypeGuard
15
15
 
16
16
  if TYPE_CHECKING:
17
- from ._types import Data
17
+ from ._types import Entry
18
18
 
19
19
 
20
20
  def is_sequence(
21
- value: Data,
22
- ) -> TypeGuard[Sequence[Data]]:
21
+ value: Entry,
22
+ ) -> TypeGuard[Sequence[Entry]]:
23
23
  return isinstance(value, Sequence) and not isinstance(value, str)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foamlib
3
- Version: 0.7.1
3
+ Version: 0.7.3
4
4
  Summary: A Python interface for interacting with OpenFOAM
5
5
  Author-email: "Gabriel S. Gerlero" <ggerlero@cimec.unl.edu.ar>
6
6
  Project-URL: Homepage, https://github.com/gerlero/foamlib
@@ -1,4 +1,4 @@
1
- foamlib/__init__.py,sha256=FH3qcxKWITL8HKS4m81vo9oCCM3ckcC2f3rOtzOia_w,452
1
+ foamlib/__init__.py,sha256=GdEjgMru_5M1AG0ltkVKqNek6vw5aI4j_6QNApGRqsg,452
2
2
  foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  foamlib/_cases/__init__.py,sha256=wTUHcUgU1CBgpu0cUMtksQ5VKG6B8CFu9xc3dWwsQuo,358
4
4
  foamlib/_cases/_async.py,sha256=i6g4EBHqvI-1PkdrxsRto2ynW7sxsOga2bSYk1XVG1U,7795
@@ -9,14 +9,14 @@ foamlib/_cases/_subprocess.py,sha256=6BlBRxknj2-BFcGkx7oVcuL63_utSaY1Axmsc1qV9j8
9
9
  foamlib/_cases/_sync.py,sha256=2BJXB7Nzldb4OgPukqupgYqdceUGkI2mYhhtGPWEBrc,5901
10
10
  foamlib/_cases/_util.py,sha256=lhVca3ERY0zwYjDam6W2QMROt0yX5vAF-9_DS5RuMbM,1547
11
11
  foamlib/_files/__init__.py,sha256=GDkYkF3F-ADhkCRT3j9dQQHPP5LyJJYb8TaBbZTQ6fo,96
12
- foamlib/_files/_files.py,sha256=LVLMeP9Zt9esuVGhntnjBA4_u_NhiX5xkm09Qemcle8,15846
12
+ foamlib/_files/_files.py,sha256=_qzXSsKRVXNrfySewonJJqL9I4OA8RTZuYyuWTGR4Ys,15829
13
13
  foamlib/_files/_io.py,sha256=IQLqoqnA1TpHf21NbUho2wsYWevyqC6MKo-wfpaObUU,2226
14
- foamlib/_files/_parsing.py,sha256=pJzlzFeiT6MDNeCoxfIUvTdrgG7MMqQdL0T-64ZANqk,15371
15
- foamlib/_files/_serialization.py,sha256=0vqJxltjscqp16mIvd0iKXbeRMbq3a7uLG2INWxzCBg,5861
16
- foamlib/_files/_types.py,sha256=eY06nox8cZe6FixUQigvZRV9Fc7gwehJxuQz_wCCnqo,1678
17
- foamlib/_files/_util.py,sha256=O9t2W26XDs63cVLroW8rZ35Puas20NhnKr_gLMlZixI,493
18
- foamlib-0.7.1.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
- foamlib-0.7.1.dist-info/METADATA,sha256=N6QL29i-hDl1ZrKrC7Lm99A3p1Fx7dgCtz21lXPXrOA,7957
20
- foamlib-0.7.1.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
21
- foamlib-0.7.1.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
- foamlib-0.7.1.dist-info/RECORD,,
14
+ foamlib/_files/_parsing.py,sha256=sY_Cyep9R7HfeTOKnKoAh9ZVXTnrJw3HGIgFFwUPGms,12541
15
+ foamlib/_files/_serialization.py,sha256=GOhWIMHNf5MaLJUjbiRffNGQn1xVGPbyh_Mm50iz5e8,5847
16
+ foamlib/_files/_types.py,sha256=mOOTXVrrD6MZGH64TmK1KX7WfUVBS8JLOuHTeeDerDQ,1729
17
+ foamlib/_files/_util.py,sha256=lkoSJHXjd6MvDxx39ZF75mhPq-_QX9AjrruVcQ7I9WI,496
18
+ foamlib-0.7.3.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
+ foamlib-0.7.3.dist-info/METADATA,sha256=4yvR9-0fYVRRfbROkoO3HcmmtZVYI4QAqIC_NPqKE0A,7957
20
+ foamlib-0.7.3.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
21
+ foamlib-0.7.3.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
+ foamlib-0.7.3.dist-info/RECORD,,