diff --git a/.github/workflows/code-style.yml b/.github/workflows/code-style.yml index 7632e55..999bb3f 100644 --- a/.github/workflows/code-style.yml +++ b/.github/workflows/code-style.yml @@ -25,13 +25,6 @@ jobs: python -m pip install --progress-bar off .[style] - name: Run Ruff run: ruff check . - - name: Run isort - uses: isort/isort-action@master - - name: Run black - uses: psf/black@stable - with: - options: "--check --verbose" - version: "23.10.1" - name: Run codespell uses: codespell-project/actions-codespell@master with: diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index ee98099..ff80f09 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -23,7 +23,7 @@ jobs: # some tests fail (numerical issues) in older python on mac, so we ... exclude: - os: macos - python-version: 3.9 + python-version: '3.9' name: ${{ matrix.os }} - py${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest defaults: @@ -36,7 +36,6 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - #architecture: 'x64' - name: Install package run: | python -m pip install --progress-bar off --upgrade pip setuptools wheel diff --git a/examples/Test_Plot.ipynb b/examples/Test_Plot.ipynb index 7533386..f843623 100644 --- a/examples/Test_Plot.ipynb +++ b/examples/Test_Plot.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Visualization" + "# Visualization" ] }, { @@ -20,8 +20,10 @@ "metadata": {}, "outputs": [], "source": [ - "from lapy import TriaMesh, TetMesh, Solver, plot, io\n", "import plotly.io as pio\n", + "\n", + "from lapy import Solver, TetMesh, TriaMesh, io, plot\n", + "\n", "pio.renderers.default = \"sphinx_gallery\"" ] }, diff --git a/examples/Test_ShapeDNA.ipynb b/examples/Test_ShapeDNA.ipynb index 0f87744..e646978 100644 --- a/examples/Test_ShapeDNA.ipynb +++ b/examples/Test_ShapeDNA.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# ShapeDNA" + "# ShapeDNA" ] }, { @@ -21,8 +21,7 @@ "outputs": [], "source": [ "# imports\n", - "from lapy import TriaMesh, TetMesh\n", - "from lapy import shapedna" + "from lapy import TetMesh, TriaMesh, shapedna" ] }, { diff --git a/examples/Test_TetMesh_Geodesics.ipynb b/examples/Test_TetMesh_Geodesics.ipynb index 205735b..5710b44 100644 --- a/examples/Test_TetMesh_Geodesics.ipynb +++ b/examples/Test_TetMesh_Geodesics.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# TetMesh Geodesics" + "# TetMesh Geodesics" ] }, { @@ -39,11 +39,14 @@ ], "source": [ "import numpy as np\n", - "from lapy import TetMesh\n", - "from lapy.plot import plot_tet_mesh\n", + "\n", "# import plotly\n", "# plotly.offline.init_notebook_mode(connected=True)\n", "import plotly.io as pio\n", + "\n", + "from lapy import TetMesh\n", + "from lapy.plot import plot_tet_mesh\n", + "\n", "pio.renderers.default = \"sphinx_gallery\"" ] }, @@ -116,6 +119,7 @@ ], "source": [ "from lapy import Solver\n", + "\n", "fem = Solver(T,lump=True)\n", "\n", "evals, evec = fem.eigs(10)\n" @@ -168,8 +172,8 @@ "metadata": {}, "outputs": [], "source": [ - "from lapy.diffgeo import compute_gradient\n", - "from lapy.diffgeo import compute_divergence\n", + "from lapy.diffgeo import compute_divergence, compute_gradient\n", + "\n", "grad = compute_gradient(T,evec[:,evnum])\n", "divx = -compute_divergence(T,grad)\n", "vfunc = Bi*divx\n" @@ -299,6 +303,7 @@ "source": [ "# compute distance\n", "from scipy.sparse.linalg import splu\n", + "\n", "useCholmod = True\n", "try:\n", " from sksparse.cholmod import cholesky\n", @@ -373,8 +378,8 @@ } ], "source": [ - "from lapy.diffgeo import compute_geodesic_f\n", "from lapy import heat\n", + "from lapy.diffgeo import compute_geodesic_f\n", "\n", "tria = T.boundary_tria()\n", "bvert=np.unique(tria.t)\n", @@ -473,7 +478,7 @@ "version": "3" }, "nbsphinx": { - "execute": "always" + "execute": "always" } }, "nbformat": 4, diff --git a/examples/Test_TriaMesh.ipynb b/examples/Test_TriaMesh.ipynb index d858d5e..b07f9af 100644 --- a/examples/Test_TriaMesh.ipynb +++ b/examples/Test_TriaMesh.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Triangle Mesh" + "# Triangle Mesh" ] }, { @@ -14,6 +14,7 @@ "outputs": [], "source": [ "import numpy as np\n", + "\n", "from lapy import TriaMesh" ] }, diff --git a/examples/Test_TriaMesh_Geodesics.ipynb b/examples/Test_TriaMesh_Geodesics.ipynb index 74ae182..744c543 100644 --- a/examples/Test_TriaMesh_Geodesics.ipynb +++ b/examples/Test_TriaMesh_Geodesics.ipynb @@ -86,8 +86,10 @@ "# import plotting functions\n", "# import plotly\n", "# plotly.offline.init_notebook_mode(connected=True)\n", - "from lapy.plot import plot_tria_mesh\n", "import plotly.io as pio\n", + "\n", + "from lapy.plot import plot_tria_mesh\n", + "\n", "pio.renderers.default = \"sphinx_gallery\"" ] }, @@ -139,6 +141,7 @@ "source": [ "# compute first eigenfunction\n", "from lapy import Solver\n", + "\n", "fem = Solver(T,lump=True)\n", "eval, evec = fem.eigs()\n", "vfunc = evec[:,1]\n", @@ -221,8 +224,8 @@ "metadata": {}, "outputs": [], "source": [ - "from lapy.diffgeo import compute_gradient\n", - "from lapy.diffgeo import compute_divergence\n", + "from lapy.diffgeo import compute_divergence, compute_gradient\n", + "\n", "grad = compute_gradient(T,vfunc)\n", "divx = -compute_divergence(T,grad)\n", "plot_tria_mesh(T,Bi*divx,plot_edges=True)" @@ -254,6 +257,7 @@ ], "source": [ "from lapy import heat\n", + "\n", "bvert = T.boundary_loops()\n", "u = heat.diffusion(T,bvert,m=1)" ] @@ -338,6 +342,7 @@ "source": [ "# compute distance\n", "from scipy.sparse.linalg import splu\n", + "\n", "useCholmod = True\n", "try:\n", " from sksparse.cholmod import cholesky\n", @@ -488,6 +493,7 @@ ], "source": [ "from lapy.diffgeo import compute_geodesic_f\n", + "\n", "gf = compute_geodesic_f(T,u)\n", "plot_tria_mesh(T,gf,plot_edges=True,plot_levels=True)" ] @@ -545,6 +551,7 @@ "source": [ "# testing if we can rotate the function\n", "from lapy.diffgeo import compute_rotated_f\n", + "\n", "gf = compute_rotated_f(T,vf)\n", "plot_tria_mesh(T,gf,plot_edges=True,plot_levels=True)" ] diff --git a/lapy/_read_geometry.py b/lapy/_read_geometry.py index 8710ffc..d40d837 100644 --- a/lapy/_read_geometry.py +++ b/lapy/_read_geometry.py @@ -81,7 +81,7 @@ def _read_volume_info(fobj): if not np.array_equal(head, [2, 0, 20]) and not np.array_equal( head, [2, 1, 20] ): - warnings.warn("Unknown extension code.") + warnings.warn("Unknown extension code.", stacklevel=2) return volume_info head = [2, 0, 20] @@ -98,7 +98,7 @@ def _read_volume_info(fobj): ]: pair = fobj.readline().decode("utf-8").split("=") if pair[0].strip() != key or len(pair) != 2: - raise IOError("Error parsing volume info.") + raise OSError("Error parsing volume info.") if key in ("valid", "filename"): volume_info[key] = pair[1].strip() elif key == "volume": @@ -176,7 +176,7 @@ def read_geometry(filepath, read_metadata=False, read_stamp=False): ret = (coords, faces) if read_metadata: if len(volume_info) == 0: - warnings.warn("No volume information contained in the file") + warnings.warn("No volume information contained in the file", stacklevel=2) ret += (volume_info,) if read_stamp: ret += (create_stamp,) diff --git a/lapy/_tet_io.py b/lapy/_tet_io.py index 1d0a093..cd6fdf7 100644 --- a/lapy/_tet_io.py +++ b/lapy/_tet_io.py @@ -29,8 +29,8 @@ def read_gmsh(filename): print("[no .msh file] --> FAILED\n") return try: - f = open(filename, "r") - except IOError: + f = open(filename) + except OSError: print("[file not found or not readable]\n") return line = f.readline() @@ -126,8 +126,8 @@ def read_vtk(filename): if verbose > 0: print("--> VTK format ... ") try: - f = open(filename, "r") - except IOError: + f = open(filename) + except OSError: print("[file not found or not readable]\n") return # skip comments @@ -209,7 +209,7 @@ def write_vtk(tet, filename): # open file try: f = open(filename, "w") - except IOError: + except OSError: print("[File " + filename + " not writable]") return # check data structure diff --git a/lapy/_tria_io.py b/lapy/_tria_io.py index ef795be..366f074 100644 --- a/lapy/_tria_io.py +++ b/lapy/_tria_io.py @@ -29,7 +29,7 @@ def read_fssurf(filename): from ._read_geometry import read_geometry surf = read_geometry(filename, read_metadata=True) - except IOError: + except OSError: print("[file not found or not readable]\n") raise from . import TriaMesh @@ -52,8 +52,8 @@ def read_off(filename): """ getLogger(__name__).debug("--> OFF format ... ") try: - f = open(filename, "r") - except IOError: + f = open(filename) + except OSError: print("[file not found or not readable]\n") raise line = f.readline() @@ -63,7 +63,7 @@ def read_off(filename): msg = "[OFF keyword not found] --> FAILED\n" print(msg) f.close() - raise IOError(msg) + raise OSError(msg) # expect tria and vertex sizes after OFF line: line = f.readline() larr = line.split() @@ -84,7 +84,7 @@ def read_off(filename): msg = "[no triangle data] --> FAILED\n" print(msg) f.close() - raise IOError(msg) + raise OSError(msg) t = t[:, 1:] f.close() getLogger(__name__).info(f" --> DONE ( V: {v.shape[0]} , T: {t.shape[0]} )\n") @@ -108,8 +108,8 @@ def read_vtk(filename): """ getLogger(__name__).debug("--> VTK format ... ") try: - f = open(filename, "r") - except IOError: + f = open(filename) + except OSError: print("[file not found or not readable]\n") raise # skip comments @@ -125,7 +125,7 @@ def read_vtk(filename): if not line.startswith("ASCII"): msg = "[ASCII keyword not found] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) # expect Dataset Polydata line after ASCII: line = f.readline() if not line.startswith("DATASET POLYDATA") and not line.startswith( @@ -136,14 +136,14 @@ def read_vtk(filename): f"--> FAILED\n" ) print(msg) - raise IOError(msg) + raise OSError(msg) # read number of points line = f.readline() larr = line.split() if larr[0] != "POINTS" or (larr[2] != "float" and larr[2] != "double"): msg = f"[read: {line} expected POINTS # float or POINTS # double ] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) pnum = int(larr[1]) # read points as chunk v = np.fromfile(f, "float32", 3 * pnum, " ") @@ -158,29 +158,29 @@ def read_vtk(filename): if npt != 4.0: msg = f"[having: {npt} data per tria, expected trias 3+1] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) t = np.fromfile(f, "int", ttnum, " ") t.shape = (tnum, 4) if t[tnum - 1][0] != 3: msg = "[can only read triangles] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) t = np.delete(t, 0, 1) elif larr[0] == "TRIANGLE_STRIPS": tnum = int(larr[1]) # ttnum = int(larr[2]) tt = [] - for i in range(tnum): + for _i in range(tnum): larr = f.readline().split() if len(larr) == 0: msg = "[error reading triangle strip (i)] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) n = int(larr[0]) if len(larr) != n + 1: msg = "[error reading triangle strip (ii)] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) # create triangles from strip # note that larr tria info starts at index 1 for ii in range(2, n): @@ -193,7 +193,7 @@ def read_vtk(filename): else: msg = f"[read: {line} expected POLYGONS or TRIANGLE_STRIPS] --> FAILED\n" print(msg) - raise IOError(msg) + raise OSError(msg) f.close() getLogger(__name__).info(f" --> DONE ( V: {v.shape[0]} , T: {t.shape[0]} )\n") from . import TriaMesh @@ -281,8 +281,8 @@ def read_gmsh(filename): getLogger(__name__).debug("--> GMSH format ... ") try: - f = open(filename, "r") - except IOError: + f = open(filename) + except OSError: print("[file not found or not readable]\n") raise @@ -359,7 +359,7 @@ def read_gmsh(filename): line = f.readline() assert line.strip() == "$EndNodes" else: - assert environ == "Elements", "Unknown environment '{}'.".format(environ) + assert environ == "Elements", f"Unknown environment '{environ}'." # The first line is the number of elements line = f.readline() total_num_cells = int(line) @@ -476,7 +476,7 @@ def write_vtk(tria, filename): # open file try: f = open(filename, "w") - except IOError: + except OSError: print("[File " + filename + " not writable]") raise # check data structure @@ -512,6 +512,6 @@ def write_fssurf(tria, filename): from nibabel.freesurfer.io import write_geometry write_geometry(filename, tria.v, tria.t, volume_info=tria.fsinfo) - except IOError: + except OSError: print("[File " + filename + " not writable]") raise diff --git a/lapy/conformal.py b/lapy/conformal.py index 4ca31fc..3a54e5f 100644 --- a/lapy/conformal.py +++ b/lapy/conformal.py @@ -83,7 +83,7 @@ def spherical_conformal_map(tria, use_cholmod=False): b = tria.v[p2, :] - tria.v[p0, :] sin1 = np.linalg.norm(np.cross(a, b)) / (np.linalg.norm(a) * np.linalg.norm(b)) ori_h = np.linalg.norm(b) * sin1 - ratio = np.sqrt(((x0 - x1) ** 2 + (y0 - y1) ** 2)) / np.linalg.norm(a) + ratio = np.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2) / np.linalg.norm(a) y2 = ori_h * ratio # compute the coordinates of the third vertex x2 = np.sqrt(np.linalg.norm(b) ** 2 * ratio**2 - y2**2) # should be around (0.5, sqrt(3)/2) if we found an equilateral bigtri diff --git a/lapy/diffgeo.py b/lapy/diffgeo.py index 3732ef3..f41ba1c 100644 --- a/lapy/diffgeo.py +++ b/lapy/diffgeo.py @@ -442,9 +442,9 @@ def tria_mean_curvature_flow( # compute difference dv = trianorm.v - vlast diff = np.trace(np.square(np.matmul(np.transpose(dv), mass.dot(dv)))) - print("Step {} delta: {}".format(x + 1, diff)) + print(f"Step {x + 1} delta: {diff}") if diff < stop_eps: - print("Converged after {} iterations.".format(x + 1)) + print(f"Converged after {x + 1} iterations.") break return trianorm @@ -536,12 +536,12 @@ def get_flipped_area(triax): l31 = abs(cmax3[1] - cmin3[1]) if l11 < l21 or l11 < l31: print("ERROR: direction 1 should be (anterior -posterior) but is not!") - print(" debug info: {} {} {} ".format(l11, l21, l31)) + print(f" debug info: {l11} {l21} {l31} ") # sys.exit(1) raise ValueError("Direction 1 should be anterior - posterior") # only flip direction if necessary - print("ev1 min: {} max {} ".format(cmin1, cmax1)) + print(f"ev1 min: {cmin1} max {cmax1} ") # axis 1 = y is aligned with this function (for brains in FS space) v1 = cmax1 - cmin1 if cmax1[1] < cmin1[1]: @@ -563,7 +563,7 @@ def get_flipped_area(triax): if l33 < l23: print("WARNING: direction 3 wants to swap with 2, but cannot") - print("ev2 min: {} max {} ".format(cmin2, cmax2)) + print(f"ev2 min: {cmin2} max {cmax2} ") # axis 2 = z is aligned with this function (for brains in FS space) v2 = cmax2 - cmin2 if cmax2[2] < cmin2[2]: @@ -571,7 +571,7 @@ def get_flipped_area(triax): print("inverting direction 2 (superior - inferior)") l2 = abs(cmax2[2] - cmin2[2]) - print("ev3 min: {} max {} ".format(cmin3, cmax3)) + print(f"ev3 min: {cmin3} max {cmax3} ") # axis 0 = x is aligned with this function (for brains in FS space) v3 = cmax3 - cmin3 if cmax3[0] < cmin3[0]: @@ -583,13 +583,13 @@ def get_flipped_area(triax): v2 = v2 * (1.0 / np.sqrt(np.sum(v2 * v2))) v3 = v3 * (1.0 / np.sqrt(np.sum(v3 * v3))) spatvol = abs(np.dot(v1, np.cross(v2, v3))) - print("spat vol: {}".format(spatvol)) + print(f"spat vol: {spatvol}") mvol = tria.volume() - print("orig mesh vol {}".format(mvol)) + print(f"orig mesh vol {mvol}") bvol = l1 * l2 * l3 - print("box {}, {}, {} volume: {} ".format(l1, l2, l3, bvol)) - print("box coverage: {}".format(bvol / mvol)) + print(f"box {l1}, {l2}, {l3} volume: {bvol} ") + print(f"box coverage: {bvol / mvol}") # we map evN to -1..0..+1 (keep zero level fixed) # I have the feeling that this helps a little with the stretching @@ -627,7 +627,7 @@ def get_flipped_area(triax): trianew = TriaMesh(vn, tria.t) svol = trianew.area() / (4.0 * math.pi * 10000) - print("sphere area fraction: {} ".format(svol)) + print(f"sphere area fraction: {svol} ") flippedarea = get_flipped_area(trianew) / (4.0 * math.pi * 10000) if flippedarea > 0.95: @@ -635,7 +635,7 @@ def get_flipped_area(triax): # sys.exit(1) raise ValueError("global normal flip") - print("flipped area fraction: {} ".format(flippedarea)) + print(f"flipped area fraction: {flippedarea} ") if svol < 0.99: print("ERROR: sphere area fraction should be above .99, exiting ..") diff --git a/lapy/io.py b/lapy/io.py index cd5a0fc..fd0fea4 100644 --- a/lapy/io.py +++ b/lapy/io.py @@ -25,7 +25,7 @@ def read_vfunc(filename): try: with open(filename) as f: txt = f.readlines() - except IOError: + except OSError: print("[File " + filename + " not found or not readable]") return txt = [x.strip() for x in txt] @@ -54,8 +54,8 @@ def read_ev(filename): """ # open file try: - f = open(filename, "r") - except IOError: + f = open(filename) + except OSError: print("[File " + filename + " not found or not readable]") return # read file (and get rid of all \n) @@ -120,7 +120,7 @@ def read_ev(filename): if ll[i].find("}") >= 0: # '{' and '}' on the same line evals = ll[i].strip().replace("{", "").replace("}", "") else: - evals = str() + evals = "" while ll[i].find("}") < 0: evals = evals + ll[i].strip().replace("{", "").replace("}", "") i = i + 1 @@ -141,7 +141,7 @@ def read_ev(filename): if ll[i].find("}") >= 0: # '{' and '}' on the same line evecs = ll[i].strip().replace("{", "").replace("}", "") else: - evecs = str() + evecs = "" while ll[i].find("}") < 0: evecs = evecs + ll[i].strip().replace("{", "").replace( "}", "" @@ -187,7 +187,7 @@ def write_ev(filename, d): # open file try: f = open(filename, "w") - except IOError: + except OSError: print("[File " + filename + " not writable]") return # check data structure @@ -281,7 +281,7 @@ def write_vfunc(filename, vfunc): """ try: f = open(filename, "w") - except IOError: + except OSError: print("[File " + filename + " not writable]") return f.write("Solution:\n") diff --git a/lapy/plot.py b/lapy/plot.py index 84f7e1d..1db8ecc 100644 --- a/lapy/plot.py +++ b/lapy/plot.py @@ -160,8 +160,8 @@ def _get_colorval(t, colormap): pos = bisect(columns[0], t) # compute param between pos-1 and pos values if len(columns[0]) < pos + 1 or pos == 0: - print("pos: {}".format(pos)) - print("t: {}".format(t)) + print(f"pos: {pos}") + print(f"t: {t}") print(columns[0]) raise ValueError("t not in range?") tt = (t - columns[0][pos - 1]) / (columns[0][pos] - columns[0][pos - 1]) @@ -199,16 +199,16 @@ def _map_z2color(zval, colormap, zmin, zmax): if zmin > zmax: raise ValueError("incorrect relation between zmin and zmax") - t = (zval - zmin) / float((zmax - zmin)) # normalize val + t = (zval - zmin) / float(zmax - zmin) # normalize val if isinstance(colormap, LinearSegmentedColormap): r, g, b, alpha = colormap(t) rgb = ( "rgb(" - + "{:d}".format(int(r * 255 + 0.5)) + + f"{int(r * 255 + 0.5):d}" + "," - + "{:d}".format(int(g * 255 + 0.5)) + + f"{int(g * 255 + 0.5):d}" + "," - + "{:d}".format(int(b * 255 + 0.5)) + + f"{int(b * 255 + 0.5):d}" + ")" ) else: diff --git a/lapy/solver.py b/lapy/solver.py index ce30120..5cbf9d8 100644 --- a/lapy/solver.py +++ b/lapy/solver.py @@ -1,6 +1,6 @@ import importlib import sys -from typing import Optional, Tuple, Union +from typing import Optional, Union import numpy as np from scipy import sparse @@ -50,7 +50,7 @@ def __init__( self, geometry: Union[TriaMesh, TetMesh], lump: bool = False, - aniso: Optional[Union[float, Tuple[float, float]]] = None, + aniso: Optional[Union[float, tuple[float, float]]] = None, aniso_smooth: int = 10, use_cholmod: bool = False, ) -> None: diff --git a/lapy/tria_mesh.py b/lapy/tria_mesh.py index 2f63cd2..8871b7a 100644 --- a/lapy/tria_mesh.py +++ b/lapy/tria_mesh.py @@ -870,7 +870,7 @@ def refine_(self, it=1): it : int Number of iterations. """ - for x in range(it): + for _x in range(it): # make symmetric adj matrix to upper triangle adjtriu = sparse.triu(self.adj_sym, 0, format="csr") # create new vertex index for each edge @@ -997,9 +997,7 @@ def orient_(self): v.data = np.sign(v.data) endt = time.time() print( - "Searched mesh after {} flooding iterations ({} sec).".format( - count, endt - startt - ) + f"Searched mesh after {count} flood iterations ({endt - startt} sec)." ) # get tria indices that need flipping: idx = v.toarray() == -1 @@ -1107,7 +1105,7 @@ def smooth_vfunc(self, vfunc, n=1): adj2 = adj2.multiply(1.0 / rowsum) # apply sparse matrix n times (fast in spite of loop) vout = adj2.dot(vfunc) - for i in range(n - 1): + for _i in range(n - 1): vout = adj2.dot(vout) return vout diff --git a/lapy/utils/_config.py b/lapy/utils/_config.py index d18a31a..44722fd 100644 --- a/lapy/utils/_config.py +++ b/lapy/utils/_config.py @@ -3,7 +3,7 @@ import sys from functools import partial from importlib.metadata import requires, version -from typing import IO, Callable, List, Optional +from typing import IO, Callable, Optional import psutil @@ -68,7 +68,7 @@ def sys_info(fid: Optional[IO] = None, developer: bool = False): _list_dependencies_info(out, ljust, dependencies) -def _list_dependencies_info(out: Callable, ljust: int, dependencies: List[str]): +def _list_dependencies_info(out: Callable, ljust: int, dependencies: list[str]): """List dependencies names and versions. Parameters diff --git a/lapy/utils/_imports.py b/lapy/utils/_imports.py index 4bfd727..637db89 100644 --- a/lapy/utils/_imports.py +++ b/lapy/utils/_imports.py @@ -56,7 +56,7 @@ def import_optional_dependency( raise ImportError( f"Missing optional dependency '{install_name}'. {extra} " f"Use pip or conda to install {install_name}." - ) + ) from None else: return None diff --git a/lapy/utils/tests/test_TetMesh_Geodesics.py b/lapy/utils/tests/test_TetMesh_Geodesics.py index bdc4003..7cdb914 100644 --- a/lapy/utils/tests/test_TetMesh_Geodesics.py +++ b/lapy/utils/tests/test_TetMesh_Geodesics.py @@ -25,7 +25,7 @@ def loaded_data(): Returns: dict: Dictionary containing the expected outcomes data. """ - with open("lapy/utils/tests/expected_outcomes.json", "r") as f: + with open("lapy/utils/tests/expected_outcomes.json") as f: expected_outcomes = json.load(f) return expected_outcomes diff --git a/lapy/utils/tests/test_TriaMesh_Geodesics.py b/lapy/utils/tests/test_TriaMesh_Geodesics.py index 5bedb2b..c06b3bc 100644 --- a/lapy/utils/tests/test_TriaMesh_Geodesics.py +++ b/lapy/utils/tests/test_TriaMesh_Geodesics.py @@ -18,7 +18,7 @@ def loaded_data(): Returns: dict: Dictionary containing the expected outcomes data. """ - with open("lapy/utils/tests/expected_outcomes.json", "r") as f: + with open("lapy/utils/tests/expected_outcomes.json") as f: expected_outcomes = json.load(f) return expected_outcomes diff --git a/lapy/utils/tests/test_shape_DNA.py b/lapy/utils/tests/test_shape_DNA.py index fd7dffa..bf0d94a 100644 --- a/lapy/utils/tests/test_shape_DNA.py +++ b/lapy/utils/tests/test_shape_DNA.py @@ -16,7 +16,7 @@ def loaded_data(): """ Load expected outcomes data from a JSON file as a dictionary. """ - with open("lapy/utils/tests/expected_outcomes.json", "r") as f: + with open("lapy/utils/tests/expected_outcomes.json") as f: expected_outcomes = json.load(f) return expected_outcomes @@ -29,7 +29,7 @@ def test_compute_shapedna(loaded_data): loaded_data (dict): Expected outcomes loaded from a JSON file. Raises: - AssertionError: If computed eigenvalues don't match expected values within tolerance. + AssertionError: If computed eigenvalues don't match within tolerance. """ ev = compute_shapedna(tria, k=3) @@ -50,7 +50,7 @@ def test_normalize_ev_geometry(loaded_data): loaded_data (dict): Expected outcomes from a JSON file. Raises: - AssertionError: If normalized eigenvalues don't match expected values within tolerance. + AssertionError: If normalized eigenvalues don't match within tolerance. """ ev = compute_shapedna(tria, k=3) @@ -76,7 +76,7 @@ def test_reweight_ev(loaded_data): loaded_data (dict): Expected outcomes from a JSON file. Raises: - AssertionError: If reweighted eigenvalues don't match expected values within tolerance. + AssertionError: If reweighted eigenvalues don't match within tolerance. """ ev = compute_shapedna(tria, k=3) @@ -124,7 +124,7 @@ def test_compute_shapedna_tet(loaded_data): loaded_data (dict): Expected outcomes from a JSON file. Raises: - AssertionError: If computed eigenvalues don't match expected values within tolerance. + AssertionError: If computed eigenvalues don't match within tolerance. """ evTet = compute_shapedna(tet, k=3) @@ -148,7 +148,7 @@ def test_normalize_ev_geometry_tet(loaded_data): loaded_data (dict): Expected outcomes from a JSON file. Raises: - AssertionError: If normalized eigenvalues don't match expected values within tolerance. + AssertionError: If normalized eigenvalues don't match within tolerance. """ evTet = compute_shapedna(tet, k=3) @@ -170,13 +170,13 @@ def test_normalize_ev_geometry_tet(loaded_data): def test_reweight_ev_tet(loaded_data): """ - Test reweighted_ev() for tetrahedral meshes and validate reweighted eigenvalues' data type. + Test reweighted_ev() for tetrahedral meshes and validate data type. Args: loaded_data (dict): Expected outcomes from a JSON file. Raises: - AssertionError: If reweighted eigenvalues don't match expected values within tolerance. + AssertionError: If reweighted eigenvalues don't match within tolerance. """ evTet = compute_shapedna(tet, k=3) @@ -195,7 +195,7 @@ def test_reweight_ev_tet(loaded_data): def test_compute_distance_tet(loaded_data): """ - Test compute_distance() for eigenvalues of tetrahedral meshes and validate computed distance. + Test compute_distance() for eigenvalues of tetrahedral meshes. Args: loaded_data (dict): Expected outcomes from a JSON file. diff --git a/lapy/utils/tests/test_tet_mesh.py b/lapy/utils/tests/test_tet_mesh.py index f17a5c7..102ce67 100644 --- a/lapy/utils/tests/test_tet_mesh.py +++ b/lapy/utils/tests/test_tet_mesh.py @@ -46,7 +46,7 @@ def loaded_data(): """ Load expected outcomes data from a JSON file as a dictionary. """ - with open("lapy/utils/tests/expected_outcomes.json", "r") as f: + with open("lapy/utils/tests/expected_outcomes.json") as f: expected_outcomes = json.load(f) return expected_outcomes diff --git a/lapy/utils/tests/test_tria_mesh.py b/lapy/utils/tests/test_tria_mesh.py index 5c8d5f4..d80532b 100644 --- a/lapy/utils/tests/test_tria_mesh.py +++ b/lapy/utils/tests/test_tria_mesh.py @@ -51,7 +51,7 @@ def loaded_data(): Returns: dict: Dictionary containing the expected outcomes data. """ - with open("lapy/utils/tests/expected_outcomes.json", "r") as f: + with open("lapy/utils/tests/expected_outcomes.json") as f: expected_outcomes = json.load(f) return expected_outcomes @@ -104,8 +104,8 @@ def test_euler(tria_mesh_fixture, loaded_data): def test_tria_areas(tria_mesh_fixture, loaded_data): """ - np.testing.assert_array_almost_equal raises an AssertionError if two objects i.e tria_areas and expected_area - are not equal up to desired precision. + np.testing.assert_array_almost_equal raises an AssertionError if two objects + i.e tria_areas and expected_area are not equal up to desired precision. """ expected_area = np.array( loaded_data["expected_outcomes"]["test_tria_mesh"]["expected_area"] @@ -128,26 +128,13 @@ def test_area(tria_mesh_fixture, loaded_data): assert result == pytest.approx(expected_mesh_area) -def test_volume(tria_mesh_fixture): - """ - Testing the volume calculation of the mesh for an unoriented mesh - """ - # Assuming that tria_mesh_fixture is unoriented - try: - tria_mesh_fixture.volume() - except ValueError as e: - assert "Can only compute volume for oriented triangle meshes!" in str(e) - else: - assert False # The function should raise a ValueError - - # Define the test case for non-oriented mesh def test_volume_oriented(tria_mesh_fixture): """ This test is verifying that the T.volume() function raises a ValueError with the error message when the input TriaMesh object is not correctly oriented. - The test will always pass by matching an error because the volume inside the closed mesh, - however, requires the mesh to be correctly oriented + The test will always pass by matching an error because the volume inside the + closed mesh,however, requires the mesh to be correctly oriented """ # Use the appropriate exception that T.volume() raises with pytest.raises( @@ -178,7 +165,7 @@ def test_vertex_areas(tria_mesh_fixture, loaded_data): mesh = tria_mesh_fixture result = mesh.vertex_areas() np.testing.assert_almost_equal(result, expected_vertex_area) - # Verify that the sum of vertex areas is approximately equal to the total surface area + # Verify that the sum of vertex areas is close to the total surface area vertex_areas_sum = np.sum(mesh.vertex_areas()) total_surface_area = mesh.area() assert np.isclose(vertex_areas_sum, total_surface_area) @@ -301,8 +288,9 @@ def test_vertex_normals(tria_mesh_fixture, loaded_data): """ # Calling tria_mesh_fixture.orient_() will modify the tria_mesh_fixture in-place and - # return the number of flipped triangles. However, it won't return a new instance of TriaMesh, so assigning - # the result to mesh like mesh = tria_mesh_fixture.orient_() would not work as expected. + # return the number of flipped triangles. However, it won't return a new instance of + # TriaMesh, so assigning the result to mesh like mesh = tria_mesh_fixture.orient_() + # would not work as expected. # Ensure the mesh is oriented before computing vertex normals tria_mesh_fixture.orient_() diff --git a/lapy/utils/tests/test_visualization_meshes.py b/lapy/utils/tests/test_visualization_meshes.py index 8093c72..686991e 100644 --- a/lapy/utils/tests/test_visualization_meshes.py +++ b/lapy/utils/tests/test_visualization_meshes.py @@ -30,7 +30,7 @@ def loaded_data(): Returns: dict: Dictionary containing the expected outcomes data. """ - with open("lapy/utils/tests/expected_outcomes.json", "r") as f: + with open("lapy/utils/tests/expected_outcomes.json") as f: expected_outcomes = json.load(f) return expected_outcomes diff --git a/pyproject.toml b/pyproject.toml index f48893d..3a003ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,9 +76,7 @@ doc = [ ] style = [ 'bibclean', - 'black', 'codespell', - 'isort', 'pydocstyle[toml]', 'ruff', ] @@ -114,35 +112,6 @@ include-package-data = false include = ['lapy*'] exclude = ['lapy*tests'] -[tool.black] -line-length = 88 -target-version = ['py310'] -include = '\.pyi?$' -extend-exclude = ''' -( - __pycache__ - | .github - | setup.py - | data/ - | doc/ - | examples/ - | tutorials/ -) -''' - -[tool.isort] -profile = 'black' -multi_line_output = 3 -line_length = 88 -py_version = 310 -extend_skip_glob = [ - 'setup.py', - 'data/*', - 'doc/*', - 'examples/*', - 'tutorials/*', -] - [tool.pydocstyle] convention = 'numpy' ignore-decorators = '(copy_doc|property|.*setter|.*getter|pyqtSlot|Slot)' @@ -155,6 +124,7 @@ line-length = 88 extend-exclude = [ "doc", "setup.py", + "tutorials/*", ] [tool.ruff.lint.per-file-ignores]