diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06bb34211..65a65794d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,11 +13,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 - name: Run pre-commit - uses: pre-commit/action@v2.0.3 + uses: pre-commit/action@v3.0.0 build: needs: [lint] @@ -25,9 +25,9 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.12"] steps: - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Checkout code @@ -36,5 +36,5 @@ jobs: run: | pip install tox tox -- --cov meshio --cov-report xml --cov-report term - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v3 if: ${{ matrix.python-version == '3.10' && matrix.os == 'ubuntu-latest' }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cea1f193a..841f29a39 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,16 +1,16 @@ repos: - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/psf/black - rev: 22.1.0 + rev: 24.1.1 hooks: - id: black language_version: python3 - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 7.0.0 hooks: - id: flake8 diff --git a/justfile b/justfile index c5740d162..ddb9707d1 100644 --- a/justfile +++ b/justfile @@ -1,4 +1,4 @@ -version := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['version'])"` +version := `python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])"` default: @echo "\"just publish\"?" diff --git a/pyproject.toml b/pyproject.toml index cb99ded5b..c207c5350 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,33 +1,46 @@ +[build-system] +requires = ["setuptools>=42", "wheel"] +build-backend = "setuptools.build_meta" + [project] name = "meshio" -version = "5.0.0" +version = "5.3.5" description = "I/O for many mesh formats" readme = "README.md" -requires-python = ">=3.7" +requires-python = ">=3.8" license = {file = "LICENSE.txt"} -keywords = ["mesh", "file formats", "scientific", "engineering", "fem", "finite elements"] +keywords = [ + "mesh", + "file formats", + "scientific", + "engineering", + "fem", + "finite elements" +] authors = [ {email = "nico.schloemer@gmail.com"}, {name = "Nico Schlömer"} ] classifiers = [ - "Development Status :: 4 - Beta", - "Programming Language :: Python", "Development Status :: 5 - Production/Stable", + "Programming Language :: Python", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering", - "Topic :: Utilities" + "Topic :: Utilities", ] dependencies = [ "importlib_metadata; python_version<'3.8'", - "numpy>=1.20.0" + "numpy>=1.20.0", + "rich", ] [project.optional-dependencies] @@ -40,14 +53,13 @@ all = [ homepage = "https://github.com/nschloe/meshio" code = "https://github.com/nschloe/meshio" issues = "https://github.com/nschloe/meshio/issues" -funding = "https://github.com/sponsors/nschloe" [project.entry-points.console_scripts] meshio = "meshio._cli:main" -[build-system] -requires = ["setuptools>=42", "wheel"] -build-backend = "setuptools.build_meta" - [tool.isort] profile = "black" + +# [options.data_files] +# share/paraview-5.9/plugins = +# tools/paraview-meshio-plugin.py diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 4f69fbe07..000000000 --- a/setup.cfg +++ /dev/null @@ -1,60 +0,0 @@ -[metadata] -name = meshio -version = 5.3.4 -author = Nico Schlömer et al. -author_email = nico.schloemer@gmail.com -description = I/O for many mesh formats -url = https://github.com/nschloe/meshio -project_urls = - Code=https://github.com/nschloe/meshio - Issues=https://github.com/nschloe/meshio/issues - Funding=https://github.com/sponsors/nschloe -long_description = file: README.md -long_description_content_type = text/markdown -license = MIT -classifiers = - Development Status :: 5 - Production/Stable - Intended Audience :: Science/Research - License :: OSI Approved :: MIT License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Topic :: Scientific/Engineering - Topic :: Utilities -keywords = - mesh - file formats - scientific - engineering - fem - finite elements - -[options] -package_dir = - =src -packages = find: -install_requires = - importlib_metadata;python_version<"3.8" - numpy - rich -python_requires = >=3.7 - -[options.packages.find] -where=src - -[options.extras_require] -all = - netCDF4 - h5py # CGNS, H5M, MED, XDMF formats - -[options.entry_points] -console_scripts = - meshio = meshio._cli:main - -[options.data_files] -share/paraview-5.9/plugins = - tools/paraview-meshio-plugin.py diff --git a/src/meshio/abaqus/_abaqus.py b/src/meshio/abaqus/_abaqus.py index b0594297b..0dd88774e 100644 --- a/src/meshio/abaqus/_abaqus.py +++ b/src/meshio/abaqus/_abaqus.py @@ -1,6 +1,7 @@ """ I/O for Abaqus inp files. """ + import pathlib from itertools import count diff --git a/src/meshio/ansys/_ansys.py b/src/meshio/ansys/_ansys.py index 3f8abe016..364616a75 100644 --- a/src/meshio/ansys/_ansys.py +++ b/src/meshio/ansys/_ansys.py @@ -3,6 +3,7 @@ """ + import re import numpy as np diff --git a/src/meshio/avsucd/_avsucd.py b/src/meshio/avsucd/_avsucd.py index 7ae1305aa..5fdbfe643 100644 --- a/src/meshio/avsucd/_avsucd.py +++ b/src/meshio/avsucd/_avsucd.py @@ -2,6 +2,7 @@ I/O for AVS-UCD format, cf. . """ + import numpy as np from ..__about__ import __version__ as version diff --git a/src/meshio/cgns/_cgns.py b/src/meshio/cgns/_cgns.py index ddb91534f..fde2ae735 100644 --- a/src/meshio/cgns/_cgns.py +++ b/src/meshio/cgns/_cgns.py @@ -3,6 +3,7 @@ TODO link to specification? """ + import numpy as np from .._exceptions import ReadError diff --git a/src/meshio/dolfin/_dolfin.py b/src/meshio/dolfin/_dolfin.py index b9af20476..e43dbd546 100644 --- a/src/meshio/dolfin/_dolfin.py +++ b/src/meshio/dolfin/_dolfin.py @@ -2,6 +2,7 @@ I/O for DOLFIN's XML format, cf. . """ + import os import pathlib import re diff --git a/src/meshio/exodus/_exodus.py b/src/meshio/exodus/_exodus.py index 80a90a097..60fce5806 100644 --- a/src/meshio/exodus/_exodus.py +++ b/src/meshio/exodus/_exodus.py @@ -5,6 +5,7 @@ , in particular Appendix A (page 171, Implementation of EXODUS II with netCDF). """ + import datetime import re diff --git a/src/meshio/flac3d/_flac3d.py b/src/meshio/flac3d/_flac3d.py index 4e660dbc2..45ea0d9cd 100644 --- a/src/meshio/flac3d/_flac3d.py +++ b/src/meshio/flac3d/_flac3d.py @@ -1,6 +1,7 @@ """ I/O for FLAC3D format. """ + from __future__ import annotations import re @@ -534,6 +535,7 @@ def _translate_zcells(points, cells): normal vectors). Reorder corner points according to sign of scalar triple products. """ + # See def slicing_summing(a, b, c): c0 = b[:, 1] * c[:, 2] - b[:, 2] * c[:, 1] diff --git a/src/meshio/gmsh/_gmsh22.py b/src/meshio/gmsh/_gmsh22.py index da4d4b3f7..56fbdb6df 100644 --- a/src/meshio/gmsh/_gmsh22.py +++ b/src/meshio/gmsh/_gmsh22.py @@ -2,6 +2,7 @@ I/O for Gmsh's msh format, cf. . """ + from __future__ import annotations import numpy as np diff --git a/src/meshio/gmsh/_gmsh40.py b/src/meshio/gmsh/_gmsh40.py index 46e62e96a..3d4270e28 100644 --- a/src/meshio/gmsh/_gmsh40.py +++ b/src/meshio/gmsh/_gmsh40.py @@ -2,6 +2,7 @@ I/O for Gmsh's msh format (version 4.0, as used by Gmsh 4.1.5), cf. . """ + from __future__ import annotations from functools import partial diff --git a/src/meshio/gmsh/_gmsh41.py b/src/meshio/gmsh/_gmsh41.py index 4529fe4c8..3e305a17f 100644 --- a/src/meshio/gmsh/_gmsh41.py +++ b/src/meshio/gmsh/_gmsh41.py @@ -2,6 +2,7 @@ I/O for Gmsh's msh format (version 4.1, as used by Gmsh 4.2.2+), cf. . """ + from functools import partial import numpy as np @@ -209,13 +210,15 @@ def _read_elements( (num_ele,) = fromfile(f, c_size_t, 1) for physical_name, cell_set in cell_sets.items(): cell_set[k] = np.arange( - num_ele - if ( - physical_tags - and field_data[physical_name][1] == dim - and field_data[physical_name][0] in physical_tags[dim][tag] - ) - else 0, + ( + num_ele + if ( + physical_tags + and field_data[physical_name][1] == dim + and field_data[physical_name][0] in physical_tags[dim][tag] + ) + else 0 + ), dtype=type(num_ele), ) tpe = _gmsh_to_meshio_type[type_ele] diff --git a/src/meshio/h5m/_h5m.py b/src/meshio/h5m/_h5m.py index 274fd6a81..62a790a05 100644 --- a/src/meshio/h5m/_h5m.py +++ b/src/meshio/h5m/_h5m.py @@ -2,6 +2,7 @@ I/O for h5m, cf. . """ + from datetime import datetime import numpy as np diff --git a/src/meshio/mdpa/_mdpa.py b/src/meshio/mdpa/_mdpa.py index e6640be92..afa39eca1 100644 --- a/src/meshio/mdpa/_mdpa.py +++ b/src/meshio/mdpa/_mdpa.py @@ -5,6 +5,7 @@ The MDPA format is unsuitable for fast consumption, this is why: . """ + import numpy as np from .._common import num_nodes_per_cell, raw_from_cell_data, warn diff --git a/src/meshio/med/_med.py b/src/meshio/med/_med.py index 301322466..0cdd35ce3 100644 --- a/src/meshio/med/_med.py +++ b/src/meshio/med/_med.py @@ -2,6 +2,7 @@ I/O for MED/Salome, cf. . """ + import numpy as np from .._common import num_nodes_per_cell @@ -28,7 +29,7 @@ "wedge15": "P15", } med_to_meshio_type = {v: k for k, v in meshio_to_med_type.items()} -numpy_void_str = np.string_("") +numpy_void_str = np.bytes_("") def read(filename): @@ -237,8 +238,8 @@ def write(filename, mesh): med_mesh.attrs.create("SRT", 1) # sorting type MED_SORT_ITDT # component names: names = ["X", "Y", "Z"][: mesh.points.shape[1]] - med_mesh.attrs.create("NOM", np.string_("".join(f"{name:<16}" for name in names))) - med_mesh.attrs.create("DES", np.string_("Mesh created with meshio")) + med_mesh.attrs.create("NOM", np.bytes_("".join(f"{name:<16}" for name in names))) + med_mesh.attrs.create("DES", np.bytes_("Mesh created with meshio")) med_mesh.attrs.create("TYP", 0) # mesh type (MED_NON_STRUCTURE) # Time-step @@ -254,7 +255,7 @@ def write(filename, mesh): nodes_group.attrs.create("CGT", 1) nodes_group.attrs.create("CGS", 1) profile = "MED_NO_PROFILE_INTERNAL" - nodes_group.attrs.create("PFL", np.string_(profile)) + nodes_group.attrs.create("PFL", np.bytes_(profile)) coo = nodes_group.create_dataset("COO", data=mesh.points.flatten(order="F")) coo.attrs.create("CGT", 1) coo.attrs.create("NBR", len(mesh.points)) @@ -277,7 +278,7 @@ def write(filename, mesh): med_cells = cells_group.create_group(med_type) med_cells.attrs.create("CGT", 1) med_cells.attrs.create("CGS", 1) - med_cells.attrs.create("PFL", np.string_(profile)) + med_cells.attrs.create("PFL", np.bytes_(profile)) nod = med_cells.create_dataset("NOD", data=cells.flatten(order="F") + 1) nod.attrs.create("CGT", 1) nod.attrs.create("NBR", len(cells)) @@ -375,21 +376,21 @@ def _write_data( # Field try: # a same MED field may contain fields of different natures field = fields.create_group(name) - field.attrs.create("MAI", np.string_(mesh_name)) + field.attrs.create("MAI", np.bytes_(mesh_name)) field.attrs.create("TYP", 6) # MED_FLOAT64 field.attrs.create("UNI", numpy_void_str) # physical unit field.attrs.create("UNT", numpy_void_str) # time unit n_components = 1 if data.ndim == 1 else data.shape[-1] field.attrs.create("NCO", n_components) # number of components # names = _create_component_names(n_components) - # field.attrs.create("NOM", np.string_("".join(f"{name:<16}" for name in names))) + # field.attrs.create("NOM", np.bytes_("".join(f"{name:<16}" for name in names))) if field_name: field.attrs.create( - "NOM", np.string_("".join(f"{name:<16}" for name in field_name)) + "NOM", np.bytes_("".join(f"{name:<16}" for name in field_name)) ) else: - field.attrs.create("NOM", np.string_(f"{'':<16}")) + field.attrs.create("NOM", np.bytes_(f"{'':<16}")) # Time-step step = "0000000000000000000100000000000000000001" @@ -414,7 +415,7 @@ def _write_data( typ = time_step.create_group("MAI." + med_type) typ.attrs.create("GAU", numpy_void_str) # no associated Gauss points - typ.attrs.create("PFL", np.string_(profile)) + typ.attrs.create("PFL", np.bytes_(profile)) profile = typ.create_group(profile) profile.attrs.create("NBR", len(data)) # number of data if supp == "ELNO": diff --git a/src/meshio/medit/_medit.py b/src/meshio/medit/_medit.py index 2fc461804..272bd16e6 100644 --- a/src/meshio/medit/_medit.py +++ b/src/meshio/medit/_medit.py @@ -3,6 +3,7 @@ Latest official up-to-date documentation and a reference C implementation at """ + import struct from ctypes import c_double, c_float diff --git a/src/meshio/nastran/_nastran.py b/src/meshio/nastran/_nastran.py index 06bb96717..0e1313c9d 100644 --- a/src/meshio/nastran/_nastran.py +++ b/src/meshio/nastran/_nastran.py @@ -1,6 +1,7 @@ """ I/O for Nastran bulk data. """ + from __future__ import annotations import numpy as np diff --git a/src/meshio/netgen/_netgen.py b/src/meshio/netgen/_netgen.py index de31abd27..cae1bd726 100644 --- a/src/meshio/netgen/_netgen.py +++ b/src/meshio/netgen/_netgen.py @@ -2,6 +2,7 @@ I/O for Netgen mesh files . """ + import numpy as np from ..__about__ import __version__ diff --git a/src/meshio/neuroglancer/_neuroglancer.py b/src/meshio/neuroglancer/_neuroglancer.py index 6fee55a5e..ad48cc29f 100644 --- a/src/meshio/neuroglancer/_neuroglancer.py +++ b/src/meshio/neuroglancer/_neuroglancer.py @@ -3,6 +3,7 @@ Adapted from https://github.com/HumanBrainProject/neuroglancer-scripts/blob/1fcabb613a715ba17c65d52596dec3d687ca3318/src/neuroglancer_scripts/mesh.py (MIT license) """ + import struct import numpy as np @@ -57,7 +58,10 @@ def read_buffer(file): if len(buf) != 4 * 3 * num_vertices: raise ReadError("The precomputed mesh data is too short") flat_vertices = np.frombuffer(buf, ". """ + import datetime import numpy as np diff --git a/src/meshio/off/_off.py b/src/meshio/off/_off.py index 05bc5f17b..c3b670b16 100644 --- a/src/meshio/off/_off.py +++ b/src/meshio/off/_off.py @@ -3,6 +3,7 @@ , . """ + import numpy as np from .._common import warn diff --git a/src/meshio/permas/_permas.py b/src/meshio/permas/_permas.py index f9ef0248c..dda02a3ad 100644 --- a/src/meshio/permas/_permas.py +++ b/src/meshio/permas/_permas.py @@ -1,6 +1,7 @@ """ I/O for PERMAS dat files. """ + import numpy as np from ..__about__ import __version__ diff --git a/src/meshio/ply/_ply.py b/src/meshio/ply/_ply.py index 4a4336d5f..4393cbc3f 100644 --- a/src/meshio/ply/_ply.py +++ b/src/meshio/ply/_ply.py @@ -3,6 +3,7 @@ . . """ + import collections import datetime import re @@ -296,11 +297,13 @@ def _read_binary( # Convert strings to proper numpy dtypes dts = [ ( - endianness + ply_to_numpy_dtype_string[dtype[0]], - endianness + ply_to_numpy_dtype_string[dtype[1]], + ( + endianness + ply_to_numpy_dtype_string[dtype[0]], + endianness + ply_to_numpy_dtype_string[dtype[1]], + ) + if isinstance(dtype, tuple) + else endianness + ply_to_numpy_dtype_string[dtype] ) - if isinstance(dtype, tuple) - else endianness + ply_to_numpy_dtype_string[dtype] for dtype in cell_data_dtypes ] @@ -311,7 +314,7 @@ def _read_binary( buffer_position = 0 cell_data = {} - for (name, dt) in zip(cell_data_names, dts): + for name, dt in zip(cell_data_names, dts): if isinstance(dt, tuple): buffer_increment, cell_data[name] = _read_binary_list( buffer[buffer_position:], dt[0], dt[1], num_cells, endianness @@ -370,7 +373,7 @@ def parse_ragged(start, num_cells): # `block_dtype` to include the initial counts in each row avoids any # wasteful copy operations. blocks = [] - for (start, end) in block_bounds: + for start, end in block_bounds: if start == end: # This should only happen if the element was empty to begin with. continue diff --git a/src/meshio/stl/_stl.py b/src/meshio/stl/_stl.py index dd7c3bfa8..8be0eed99 100644 --- a/src/meshio/stl/_stl.py +++ b/src/meshio/stl/_stl.py @@ -2,6 +2,7 @@ I/O for the STL format, cf. . """ + from __future__ import annotations import os diff --git a/src/meshio/su2/_su2.py b/src/meshio/su2/_su2.py index fc8631515..b925171ec 100644 --- a/src/meshio/su2/_su2.py +++ b/src/meshio/su2/_su2.py @@ -2,6 +2,7 @@ I/O SU2 mesh format """ + from itertools import chain, islice import numpy as np diff --git a/src/meshio/tecplot/_tecplot.py b/src/meshio/tecplot/_tecplot.py index 0bdf42bb9..4acf2c3ff 100644 --- a/src/meshio/tecplot/_tecplot.py +++ b/src/meshio/tecplot/_tecplot.py @@ -3,6 +3,7 @@ , . """ + import numpy as np from ..__about__ import __version__ as version diff --git a/src/meshio/tetgen/_tetgen.py b/src/meshio/tetgen/_tetgen.py index 9fa1f400a..c869496b4 100644 --- a/src/meshio/tetgen/_tetgen.py +++ b/src/meshio/tetgen/_tetgen.py @@ -2,6 +2,7 @@ I/O for the TetGen file format, c.f. """ + import pathlib import numpy as np diff --git a/src/meshio/ugrid/_ugrid.py b/src/meshio/ugrid/_ugrid.py index 738ff7ec5..6fa57c09f 100644 --- a/src/meshio/ugrid/_ugrid.py +++ b/src/meshio/ugrid/_ugrid.py @@ -7,6 +7,7 @@ Node ordering described in [3] """ + import numpy as np from .._common import _pick_first_int_data, warn diff --git a/src/meshio/vtk/_vtk_42.py b/src/meshio/vtk/_vtk_42.py index 4f23c9c94..f3cb46916 100644 --- a/src/meshio/vtk/_vtk_42.py +++ b/src/meshio/vtk/_vtk_42.py @@ -1,6 +1,7 @@ """ I/O for VTK . """ + from functools import reduce import numpy as np diff --git a/src/meshio/vtu/_vtu.py b/src/meshio/vtu/_vtu.py index 6a90fcd96..be80904a1 100644 --- a/src/meshio/vtu/_vtu.py +++ b/src/meshio/vtu/_vtu.py @@ -3,6 +3,7 @@ """ + import base64 import re import sys diff --git a/src/meshio/xdmf/__init__.py b/src/meshio/xdmf/__init__.py index 4cc4ca6c3..17dd2769a 100644 --- a/src/meshio/xdmf/__init__.py +++ b/src/meshio/xdmf/__init__.py @@ -2,6 +2,7 @@ I/O for XDMF. https://xdmf.org/index.php/XDMF_Model_and_Format """ + from .main import read, write from .time_series import TimeSeriesReader, TimeSeriesWriter diff --git a/src/meshio/xdmf/main.py b/src/meshio/xdmf/main.py index 438104d12..4d8c39d24 100644 --- a/src/meshio/xdmf/main.py +++ b/src/meshio/xdmf/main.py @@ -2,6 +2,7 @@ I/O for XDMF. https://xdmf.org/index.php/XDMF_Model_and_Format """ + import os import pathlib from io import BytesIO