Skip to content

Commit 2166615

Browse files
committed
Merge branch 'develop' into origin/master
2 parents b67fac1 + 0566d28 commit 2166615

18 files changed

+169115
-75
lines changed

.github/workflows/python-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313

1414
strategy:
1515
matrix:
16-
python-version: ["3.6", "3.7", "3.8", "3.9"]
16+
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
1717

1818
steps:
1919
- uses: actions/checkout@v2

.github/workflows/python-unittest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313

1414
strategy:
1515
matrix:
16-
python-version: ["3.6", "3.7", "3.8", "3.9"]
16+
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
1717

1818
steps:
1919
- uses: actions/checkout@v2

py2dm/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
Element6T, Element8Q, Element9Q, Entity, LinearElement,
1515
Node, NodeString, QuadrilateralElement,
1616
TriangularElement)
17+
from ._parser import implementation
1718
from ._read import Reader, ReaderBase
1819
from ._write import Writer
1920

@@ -28,6 +29,7 @@
2829
'Element9Q',
2930
'Entity',
3031
'errors',
32+
'implementation',
3133
'LinearElement',
3234
'Node',
3335
'NodeString',
@@ -36,7 +38,7 @@
3638
'ReaderBase',
3739
'TriangularElement',
3840
'utils',
39-
'Writer'
41+
'Writer',
4042
]
4143

42-
__version__ = '0.2.1'
44+
__version__ = '0.2.2'

py2dm/_entities.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
'Node',
2424
'NodeString',
2525
'QuadrilateralElement',
26-
'TriangularElement'
26+
'TriangularElement',
2727
]
2828

2929
_Material = Union[int, float]

py2dm/_parser/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
"""Py2DM parser submodule."""
22

3-
import platform
4-
import warnings
5-
63
from ._pyparser import scan_metadata
74

5+
implementation: str = 'unknown'
6+
87
try:
98
from ._cparser import parse_element, parse_node, parse_node_string
109
except ImportError: # pragma: no cover
1110
from ._pyparser import parse_element, parse_node, parse_node_string
12-
if platform.python_implementation() == 'CPython':
13-
warnings.warn('C parser not found, using Python implementation')
11+
implementation = 'python'
12+
else:
13+
implementation = 'c'
14+
1415

1516
__all__ = [
17+
'implementation',
1618
'parse_element',
1719
'parse_node',
1820
'parse_node_string',
19-
'scan_metadata'
21+
'scan_metadata',
2022
]

py2dm/_parser/_pyparser.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
from ..errors import CardError, FormatError, ReadError
77

88
_MetadataArgs = Tuple[
9-
int, # num_nodes
10-
int, # num_elements
11-
int, # num_node_strings
9+
int, # num_nodes
10+
int, # num_elements
11+
int, # num_node_strings
1212
Optional[str], # name
1313
Optional[int], # num_materials_per_elem
14-
int, # nodes start
15-
int, # elements start
16-
int] # node strings start
14+
int, # nodes start
15+
int, # elements start
16+
int, # node strings start
17+
]
1718

1819
_ELEMENT_CARDS = [
1920
'E2L',
@@ -22,7 +23,7 @@
2223
'E4Q',
2324
'E6T',
2425
'E8Q',
25-
'E9Q'
26+
'E9Q',
2627
]
2728

2829

@@ -105,7 +106,7 @@ def parse_node(line: str, allow_zero_index: bool = False
105106
return id_, pos_x, pos_y, pos_z
106107

107108

108-
def parse_node_string(line: str, allow_zero_index: bool = False,
109+
def parse_node_string(line: str, allow_zero_index: bool = False,
109110
nodes: Optional[List[int]] = None
110111
) -> Tuple[List[int], bool, str]:
111112
"""Parse a string into a node string.
@@ -162,9 +163,9 @@ def scan_metadata(file_: IO[str], filename: Union[str, pathlib.Path],
162163
last_node = -1
163164
last_element = -1
164165
# File seek offsets
165-
nodes_start = 0
166-
elements_start = 0
167-
node_strings_start = 0
166+
nodes_start = -1
167+
elements_start = -1
168+
node_strings_start = -1
168169

169170
file_.seek(0)
170171
for index, line_raw in enumerate(iter(file_.readline, '')):
@@ -191,7 +192,7 @@ def scan_metadata(file_: IO[str], filename: Union[str, pathlib.Path],
191192
raise FormatError('Node IDs have holes',
192193
filename, index+1)
193194
last_node = id_
194-
if nodes_start == 0:
195+
if nodes_start < 0:
195196
nodes_start = file_.tell() - len(line_raw) - 1
196197
continue
197198
if line.split(maxsplit=1)[0] in _ELEMENT_CARDS:
@@ -205,14 +206,14 @@ def scan_metadata(file_: IO[str], filename: Union[str, pathlib.Path],
205206
raise FormatError('Element IDs have holes',
206207
filename, index+1)
207208
last_element = id_
208-
if elements_start == 0:
209+
if elements_start < 0:
209210
elements_start = file_.tell() - len(line_raw) - 1
210211
continue
211-
if (line.startswith('NS')
212-
and '-' in line.split('#', maxsplit=1)[0]):
213-
num_node_strings += 1
214-
if node_strings_start == 0:
212+
if line.startswith('NS'):
213+
if node_strings_start < 0:
215214
node_strings_start = file_.tell() - len(line_raw) - 1
215+
if '-' in line.split('#', maxsplit=1)[0]:
216+
num_node_strings += 1
216217
elif line.startswith('MESHNAME') or line.startswith('GM'):
217218
# NOTE: This fails for meshes with double quotes in their
218219
# mesh name, but that is an unreasonable thing to want to
@@ -227,6 +228,13 @@ def scan_metadata(file_: IO[str], filename: Union[str, pathlib.Path],
227228
if isinstance(filename, pathlib.Path):
228229
filename = str(filename)
229230
raise ReadError('MESH2D tag not found', filename)
231+
# Set *_start offsets to end of file if no instances were found
232+
if nodes_start < 0:
233+
nodes_start = file_.tell()
234+
if elements_start < 0:
235+
elements_start = file_.tell()
236+
if node_strings_start < 0:
237+
node_strings_start = file_.tell()
230238
return (num_nodes, num_elements, num_node_strings, name,
231239
num_materials_per_elem, nodes_start, elements_start,
232240
node_strings_start)

py2dm/_read.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
__all__ = [
2020
'Reader',
21-
'ReaderBase'
21+
'ReaderBase',
2222
]
2323

2424
_ReaderT = TypeVar('_ReaderT', bound='ReaderBase')
@@ -465,15 +465,15 @@ def open(self) -> None:
465465
element.materials = tuple(
466466
element.materials[:self._num_materials])
467467
self._cache_elements.append(element)
468-
if element.id >= self.num_elements:
468+
if element.id >= self.num_elements - self._zero_index:
469469
break
470470
# Node strings
471471
file_.seek(self._metadata.pos_node_strings)
472472
node_string: Optional[NodeString] = None
473473
for line in file_:
474474
if line.startswith('NS'):
475475
node_string, is_done = NodeString.from_line(
476-
line, node_string)
476+
line, node_string, allow_zero_index=self._zero_index)
477477
if is_done:
478478
self._cache_node_strings.append(node_string)
479479
node_string = None

py2dm/_typing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ def __get__(self, *args: Any, **kwargs: Any) -> Any:
5555

5656
__all__ = [
5757
'Literal',
58-
'cached_property'
58+
'cached_property',
5959
]

py2dm/_write.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ._typing import Literal
1818

1919
__all__ = [
20-
'Writer'
20+
'Writer',
2121
]
2222

2323
_MeshObject = Union[Entity, NodeString]
@@ -527,9 +527,11 @@ def flush_node_strings(self, **kwargs: Any) -> None:
527527
if 'header' not in self._write_history:
528528
self.write_header()
529529
self._check_flush_state('node string')
530-
self._file.writelines(
531-
(f'{" ".join(n.to_line(**kwargs))}\n'
532-
for n in cast(List[NodeString], self._cache[NodeString])))
530+
# Remove whitespace around newline characters
531+
for node_string in cast(List[NodeString], self._cache[NodeString]):
532+
lines = ' '.join(node_string.to_line(**kwargs))
533+
lines = '\n'.join(l.strip() for l in lines.split('\n'))
534+
self._file.writelines((lines, '\n'))
533535
self._update_flush_state('node string')
534536
self._cache[NodeString].clear()
535537

0 commit comments

Comments
 (0)