foamlib 0.1.5__tar.gz → 0.1.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foamlib
3
- Version: 0.1.5
3
+ Version: 0.1.7
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
@@ -26,12 +26,15 @@ Requires-Python: >=3.7
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE.txt
28
28
  Requires-Dist: aioshutil<2,>=1
29
+ Requires-Dist: pyparsing<4,>=3
29
30
  Provides-Extra: lint
30
31
  Requires-Dist: mypy<2,>=1; extra == "lint"
31
32
  Requires-Dist: pytest<9,>=7; extra == "lint"
32
33
  Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "lint"
33
34
  Requires-Dist: numpy<2,>=1; extra == "lint"
34
35
  Requires-Dist: black; extra == "lint"
36
+ Requires-Dist: flake8; extra == "lint"
37
+ Requires-Dist: Flake8-pyproject; extra == "lint"
35
38
  Provides-Extra: test
36
39
  Requires-Dist: pytest<9,>=7; extra == "test"
37
40
  Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "test"
@@ -1,4 +1,4 @@
1
- __version__ = "0.1.5"
1
+ __version__ = "0.1.7"
2
2
 
3
3
  from ._cases import FoamCase, AsyncFoamCase, FoamTimeDirectory, FoamCaseBase
4
4
  from ._dictionaries import (
@@ -14,7 +14,6 @@ from typing import (
14
14
  Sequence,
15
15
  AsyncGenerator,
16
16
  Callable,
17
- Mapping,
18
17
  Iterator,
19
18
  overload,
20
19
  )
@@ -23,6 +23,7 @@ except ModuleNotFoundError:
23
23
  else:
24
24
  numpy = True
25
25
 
26
+ from pyparsing import Group, Keyword, Opt, ZeroOrMore, Literal, Forward, common
26
27
 
27
28
  FoamDimensionSet = namedtuple(
28
29
  "FoamDimensionSet",
@@ -63,108 +64,45 @@ FoamValue = Union[
63
64
  A value that can be stored in an OpenFOAM dictionary.
64
65
  """
65
66
 
67
+ _yes = Keyword("yes").set_parse_action(lambda s, loc, tks: True)
68
+ _no = Keyword("no").set_parse_action(lambda s, loc, tks: False)
69
+ _value = Forward()
70
+ _list = (
71
+ Opt(common.integer).suppress()
72
+ + Literal("(").suppress()
73
+ + Group(ZeroOrMore(_value))
74
+ + Literal(")").suppress()
75
+ )
76
+ _uniform_field = Keyword("uniform").suppress() + _value
77
+ _nonuniform_field = (
78
+ Keyword("nonuniform").suppress()
79
+ + Literal("List<").suppress()
80
+ + common.identifier.suppress()
81
+ + Literal(">").suppress()
82
+ + _list
83
+ )
84
+ _dimensions = (
85
+ Literal("[").suppress() + common.number * 7 + Literal("]").suppress()
86
+ ).set_parse_action(lambda s, loc, tks: FoamDimensionSet(*tks))
87
+ _dimensioned = (common.identifier + _dimensions + _value).set_parse_action(
88
+ lambda s, loc, tks: FoamDimensioned(tks[0], tks[1], tks[2].as_list())
89
+ )
66
90
 
67
- def _parse_bool(value: str) -> bool:
68
- if value == "yes":
69
- return True
70
- elif value == "no":
71
- return False
72
- else:
73
- raise ValueError(f"Cannot parse '{value}' as a boolean")
74
-
75
-
76
- def _parse_number(value: str) -> Union[int, float]:
77
- with suppress(ValueError):
78
- return int(value)
79
- with suppress(ValueError):
80
- return float(value)
81
- raise ValueError(f"Cannot parse '{value}' as a number")
82
-
83
-
84
- def _parse_sequence(value: str) -> Sequence[FoamValue]:
85
- start = value.find("(")
86
- if start != -1:
87
- assert value.endswith(")")
88
- seq = []
89
- nested = 0
90
- start += 1
91
- for i, c in enumerate(value[start:], start=start):
92
- if c == "(":
93
- nested += 1
94
- elif c == ")":
95
- nested -= 1
96
- if c.isspace() and not nested:
97
- v = value[start:i].strip()
98
- if v:
99
- seq.append(_parse(v))
100
- start = i + 1
101
-
102
- v = value[start:-1].strip()
103
- if v:
104
- seq.append(_parse(v))
105
-
106
- return seq
107
-
108
- else:
109
- raise ValueError(f"Cannot parse '{value}' as a sequence")
110
-
111
-
112
- def _parse_field(value: str) -> FoamValue:
113
- if value.startswith("uniform "):
114
- value = value[len("uniform ") :]
115
- return _parse(value)
116
- elif value.startswith("nonuniform "):
117
- value = value[len("nonuniform ") :]
118
- return _parse_sequence(value)
119
- else:
120
- raise ValueError(f"Cannot parse '{value}' as a field")
121
-
122
-
123
- def _parse_dimensions(value: str) -> FoamDimensionSet:
124
- if value.startswith("["):
125
- assert value.endswith("]")
126
- return FoamDimensionSet(*(_parse_number(v) for v in value[1:-1].split()))
127
- else:
128
- raise ValueError(f"Cannot parse '{value}' as a dimension set")
129
-
130
-
131
- def _parse_dimensioned(value: str) -> FoamDimensioned:
132
- start = value.find("[", 1)
133
- if start != -1:
134
- name = value[:start].strip()
135
- end = value.find("]", start)
136
- if end != -1:
137
- dimensions = _parse_dimensions(value[start : end + 1])
138
- value = value[end + 1 :].strip()
139
- return FoamDimensioned(
140
- name,
141
- dimensions,
142
- cast(Union[int, float, Sequence[Union[int, float]]], _parse(value)),
143
- )
144
-
145
- raise ValueError(f"Cannot parse '{value}' as a dimensioned value")
91
+ _value << (
92
+ _uniform_field
93
+ | _nonuniform_field
94
+ | _list
95
+ | _dimensioned
96
+ | _dimensions
97
+ | common.number
98
+ | _yes
99
+ | _no
100
+ | common.identifier
101
+ )
146
102
 
147
103
 
148
104
  def _parse(value: str) -> FoamValue:
149
- with suppress(ValueError):
150
- return _parse_bool(value)
151
-
152
- with suppress(ValueError):
153
- return _parse_field(value)
154
-
155
- with suppress(ValueError):
156
- return _parse_number(value)
157
-
158
- with suppress(ValueError):
159
- return _parse_dimensions(value)
160
-
161
- with suppress(ValueError):
162
- return _parse_dimensioned(value)
163
-
164
- with suppress(ValueError):
165
- return _parse_sequence(value)
166
-
167
- return value
105
+ return cast(FoamValue, _value.parse_string(value, parse_all=True).as_list()[0])
168
106
 
169
107
 
170
108
  def _serialize_bool(value: Any) -> str:
@@ -176,7 +114,7 @@ def _serialize_bool(value: Any) -> str:
176
114
  raise TypeError(f"Not a bool: {type(value)}")
177
115
 
178
116
 
179
- def _serialize_sequence(sequence: Any) -> str:
117
+ def _serialize_list(sequence: Any) -> str:
180
118
  if (
181
119
  isinstance(sequence, Sequence)
182
120
  and not isinstance(sequence, str)
@@ -193,7 +131,7 @@ def _serialize_field(value: Any) -> str:
193
131
  return f"uniform {value}"
194
132
  else:
195
133
  try:
196
- s = _serialize_sequence(value)
134
+ s = _serialize_list(value)
197
135
  except TypeError:
198
136
  raise TypeError(f"Not a valid field: {type(value)}") from None
199
137
  else:
@@ -249,7 +187,7 @@ def _serialize(
249
187
  return _serialize_dimensioned(value)
250
188
 
251
189
  with suppress(TypeError):
252
- return _serialize_sequence(value)
190
+ return _serialize_list(value)
253
191
 
254
192
  with suppress(TypeError):
255
193
  return _serialize_bool(value)
@@ -393,7 +331,10 @@ class FoamBoundaryDictionary(FoamDictionary):
393
331
  def value(
394
332
  self,
395
333
  value: Union[
396
- int, float, Sequence[Union[int, float, Sequence[Union[int, float]]]]
334
+ int,
335
+ float,
336
+ Sequence[Union[int, float, Sequence[Union[int, float]]]],
337
+ NDArray[np.generic],
397
338
  ],
398
339
  ) -> None:
399
340
  self["value"] = value
@@ -483,17 +424,21 @@ class FoamFieldFile(FoamFile):
483
424
  def internal_field(
484
425
  self,
485
426
  value: Union[
486
- int, float, Sequence[Union[int, float, Sequence[Union[int, float]]]]
427
+ int,
428
+ float,
429
+ Sequence[Union[int, float, Sequence[Union[int, float]]]],
430
+ NDArray[np.generic],
487
431
  ],
488
432
  ) -> None:
489
433
  self["internalField"] = value
490
434
 
491
435
  @property
492
- def boundary_field(self) -> FoamDictionary:
436
+ def boundary_field(self) -> FoamBoundariesDictionary:
493
437
  """
494
438
  Alias of `self["boundaryField"]`.
495
439
  """
496
440
  ret = self["boundaryField"]
497
- if not isinstance(ret, FoamDictionary):
441
+ if not isinstance(ret, FoamBoundariesDictionary):
442
+ assert not isinstance(ret, FoamDictionary)
498
443
  raise TypeError("boundaryField is not a dictionary")
499
444
  return ret
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foamlib
3
- Version: 0.1.5
3
+ Version: 0.1.7
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
@@ -26,12 +26,15 @@ Requires-Python: >=3.7
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE.txt
28
28
  Requires-Dist: aioshutil<2,>=1
29
+ Requires-Dist: pyparsing<4,>=3
29
30
  Provides-Extra: lint
30
31
  Requires-Dist: mypy<2,>=1; extra == "lint"
31
32
  Requires-Dist: pytest<9,>=7; extra == "lint"
32
33
  Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "lint"
33
34
  Requires-Dist: numpy<2,>=1; extra == "lint"
34
35
  Requires-Dist: black; extra == "lint"
36
+ Requires-Dist: flake8; extra == "lint"
37
+ Requires-Dist: Flake8-pyproject; extra == "lint"
35
38
  Provides-Extra: test
36
39
  Requires-Dist: pytest<9,>=7; extra == "test"
37
40
  Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "test"
@@ -1,4 +1,5 @@
1
1
  aioshutil<2,>=1
2
+ pyparsing<4,>=3
2
3
 
3
4
  [docs]
4
5
  sphinx<8,>=7
@@ -11,6 +12,8 @@ pytest<9,>=7
11
12
  pytest-asyncio<0.24,>=0.21
12
13
  numpy<2,>=1
13
14
  black
15
+ flake8
16
+ Flake8-pyproject
14
17
 
15
18
  [test]
16
19
  pytest<9,>=7
@@ -27,7 +27,10 @@ classifiers = [
27
27
  "Typing :: Typed",
28
28
  ]
29
29
 
30
- dependencies = ["aioshutil>=1,<2"]
30
+ dependencies = [
31
+ "aioshutil>=1,<2",
32
+ "pyparsing>=3,<4",
33
+ ]
31
34
 
32
35
  dynamic = ["version"]
33
36
 
@@ -38,6 +41,8 @@ lint = [
38
41
  "pytest-asyncio>=0.21,<0.24",
39
42
  "numpy>=1,<2",
40
43
  "black",
44
+ "flake8",
45
+ "Flake8-pyproject",
41
46
  ]
42
47
  test = [
43
48
  "pytest>=7,<9",
@@ -71,3 +76,22 @@ packages = [
71
76
  "tests",
72
77
  ]
73
78
  strict = true
79
+
80
+ [tool.flake8]
81
+ count = true
82
+ ignore = [
83
+ "E203", # whitespace before ':'
84
+ "E501", # line too long
85
+ "E704", # multiple statements on one line (def)
86
+ "F403", # 'from foamlib import *' used; unable to detect undefined names
87
+ "F405", # 'FoamDimensionSet' may be undefined, or defined from star imports: foamlib
88
+ "W503", # line break before binary operator
89
+ ]
90
+ exclude = [
91
+ ".git",
92
+ "__pycache__",
93
+ "docs/source/conf.py",
94
+ "build",
95
+ "dist",
96
+ "venv",
97
+ ]
@@ -14,8 +14,8 @@ def test_parse() -> None:
14
14
  assert _parse("1") == 1
15
15
  assert _parse("1.0") == 1.0
16
16
  assert _parse("1.0e-3") == 1.0e-3
17
- assert _parse("yes") == True
18
- assert _parse("no") == False
17
+ assert _parse("yes") is True
18
+ assert _parse("no") is False
19
19
  assert _parse("uniform 1") == 1
20
20
  assert _parse("uniform 1.0") == 1.0
21
21
  assert _parse("uniform 1.0e-3") == 1.0e-3
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes