diff --git a/pkgs/development/python-modules/fipy/default.nix b/pkgs/development/python-modules/fipy/default.nix index ab670e557da4..57835019d5de 100644 --- a/pkgs/development/python-modules/fipy/default.nix +++ b/pkgs/development/python-modules/fipy/default.nix @@ -39,6 +39,14 @@ buildPythonPackage rec { ] ++ lib.optionals isPy27 [ pysparse ] ++ lib.optionals (!stdenv.isDarwin) [ gmsh ]; + # Reading version string from Gmsh is broken in latest release of FiPy + # This issue is repaired on master branch of FiPy + # Fixed with: https://github.com/usnistgov/fipy/pull/848/files + # Remove patch with next release. + patches = [ ./gmsh.patch ]; + + checkInputs = lib.optionals (!stdenv.isDarwin) [ gmsh ]; + checkPhase = '' export OMPI_MCA_plm_rsh_agent=${openssh}/bin/ssh ${python.interpreter} setup.py test --modules diff --git a/pkgs/development/python-modules/fipy/gmsh.patch b/pkgs/development/python-modules/fipy/gmsh.patch new file mode 100644 index 000000000000..7e7b687ac8c6 --- /dev/null +++ b/pkgs/development/python-modules/fipy/gmsh.patch @@ -0,0 +1,182 @@ +diff --git a/fipy/meshes/gmshMesh.py b/fipy/meshes/gmshMesh.py +index fc3ff6c8..d529d532 100755 +--- a/fipy/meshes/gmshMesh.py ++++ b/fipy/meshes/gmshMesh.py +@@ -13,11 +13,11 @@ import sys + import tempfile + from textwrap import dedent + import warnings +-from distutils.version import StrictVersion + + from fipy.tools import numerix as nx + from fipy.tools import parallelComm + from fipy.tools import serialComm ++from fipy.tools.version import Version, parse_version + from fipy.tests.doctestPlus import register_skipper + + from fipy.meshes.mesh import Mesh +@@ -38,7 +38,7 @@ def _checkForGmsh(): + hasGmsh = True + try: + version = _gmshVersion(communicator=parallelComm) +- hasGmsh = version >= StrictVersion("2.0") ++ hasGmsh = version >= Version("2.0") + except Exception: + hasGmsh = False + return hasGmsh +@@ -68,6 +68,7 @@ def gmshVersion(communicator=parallelComm): + while True: + try: + # gmsh returns version in stderr (Why?!?) ++ # (newer versions of gmsh return the version in stdout) + # spyder on Windows throws + # OSError: [WinError 6] The handle is invalid + # if we don't PIPE stdout, too +@@ -77,8 +78,11 @@ def gmshVersion(communicator=parallelComm): + break + + try: +- out, verStr = p.communicate() +- verStr = verStr.decode('ascii').strip() ++ out, err = p.communicate() ++ verStr = err.decode('ascii').strip() ++ if not verStr: ++ # newer versions of gmsh return the version in stdout ++ verStr = out.decode('ascii').strip() + break + except IOError: + # some weird conflict with things like PyQT can cause +@@ -93,12 +97,12 @@ def gmshVersion(communicator=parallelComm): + def _gmshVersion(communicator=parallelComm): + version = gmshVersion(communicator) or "0.0" + try: +- version = StrictVersion(version) ++ version = parse_version(version) + except ValueError: + # gmsh returns the version string in stderr, + # which means it's often unparsable due to irrelevant warnings + # assume it's OK and move on +- version = StrictVersion("3.0") ++ version = Version("3.0") + + return version + +@@ -133,7 +137,7 @@ def openMSHFile(name, dimensions=None, coordDimensions=None, communicator=parall + + # Enforce gmsh version to be either >= 2 or 2.5, based on Nproc. + version = _gmshVersion(communicator=communicator) +- if version < StrictVersion("2.0"): ++ if version < Version("2.0"): + raise EnvironmentError("Gmsh version must be >= 2.0.") + + # If we're being passed a .msh file, leave it be. Otherwise, +@@ -176,9 +180,11 @@ def openMSHFile(name, dimensions=None, coordDimensions=None, communicator=parall + gmshFlags = ["-%d" % dimensions, "-nopopup"] + + if communicator.Nproc > 1: +- if not (StrictVersion("2.5") < version <= StrictVersion("4.0")): +- warnstr = "Cannot partition with Gmsh version < 2.5 or >= 4.0. " \ +- + "Reverting to serial." ++ if ((version < Version("2.5")) ++ or (Version("4.0") <= version < Version("4.5.2"))): ++ warnstr = ("Cannot partition with Gmsh version < 2.5 " ++ "or 4.0 <= version < 4.5.2. " ++ "Reverting to serial.") + warnings.warn(warnstr, RuntimeWarning, stacklevel=2) + communicator = serialComm + +@@ -188,13 +194,13 @@ def openMSHFile(name, dimensions=None, coordDimensions=None, communicator=parall + raise ValueError("'dimensions' must be specified to generate a mesh from a geometry script") + else: # gmsh version is adequate for partitioning + gmshFlags += ["-part", "%d" % communicator.Nproc] +- if version >= StrictVersion("4.0"): ++ if version >= Version("4.0"): + # Gmsh 4.x needs to be told to generate ghost cells +- # Unfortunately, the ghosts are broken ++ # Unfortunately, the ghosts are broken in Gmsh 4.0--4.5.1 + # https://gitlab.onelab.info/gmsh/gmsh/issues/733 + gmshFlags += ["-part_ghosts"] + +- gmshFlags += ["-format", "msh2"] ++ gmshFlags += ["-format", "msh2", "-smooth", "8"] + + if background is not None: + if communicator.procID == 0: +@@ -1387,6 +1393,11 @@ class _GmshTopology(_MeshTopology): + class Gmsh2D(Mesh2D): + """Construct a 2D Mesh using Gmsh + ++ If called in parallel, the mesh will be partitioned based on the value ++ of `parallelComm.Nproc`. If an `MSH` file is supplied, it must have ++ been previously partitioned with the number of partitions matching ++ `parallelComm.Nproc`. ++ + >>> radius = 5. + >>> side = 4. + >>> squaredCircle = Gmsh2D(''' +@@ -1875,6 +1886,11 @@ class Gmsh2D(Mesh2D): + class Gmsh2DIn3DSpace(Gmsh2D): + """Create a topologically 2D Mesh in 3D coordinates using Gmsh + ++ If called in parallel, the mesh will be partitioned based on the value ++ of `parallelComm.Nproc`. If an `MSH` file is supplied, it must have ++ been previously partitioned with the number of partitions matching ++ `parallelComm.Nproc`. ++ + Parameters + ---------- + arg : str +@@ -1959,6 +1975,11 @@ class Gmsh2DIn3DSpace(Gmsh2D): + class Gmsh3D(Mesh): + """Create a 3D Mesh using Gmsh + ++ If called in parallel, the mesh will be partitioned based on the value ++ of `parallelComm.Nproc`. If an `MSH` file is supplied, it must have ++ been previously partitioned with the number of partitions matching ++ `parallelComm.Nproc`. ++ + Parameters + ---------- + arg : str +@@ -2225,7 +2246,7 @@ class GmshGrid2D(Gmsh2D): + width = nx * dx + numLayers = int(ny / float(dy)) + +- if _gmshVersion() < StrictVersion("2.7"): ++ if _gmshVersion() < Version("2.7"): + # kludge: must offset cellSize by `eps` to work properly + eps = float(dx)/(nx * 10) + else: +@@ -2299,7 +2320,7 @@ class GmshGrid3D(Gmsh3D): + width = nx * dx + depth = nz * dz + +- if _gmshVersion() < StrictVersion("2.7"): ++ if _gmshVersion() < Version("2.7"): + # kludge: must offset cellSize by `eps` to work properly + eps = float(dx)/(nx * 10) + else: +diff --git a/fipy/tools/version.py b/fipy/tools/version.py +new file mode 100644 +index 00000000..93d89c18 +--- /dev/null ++++ b/fipy/tools/version.py +@@ -0,0 +1,18 @@ ++"""Shim for version checking ++ ++`distutils.version` is deprecated, but `packaging.version` is unavailable ++in Python 2.7 ++""" ++from __future__ import unicode_literals ++ ++__docformat__ = 'restructuredtext' ++ ++ ++__all__ = ["Version", "parse_version"] ++from future.utils import text_to_native_str ++__all__ = [text_to_native_str(n) for n in __all__] ++ ++try: ++ from packaging.version import Version, parse as parse_version ++except ImportError: ++ from distutils.version import StrictVersion as Version, StrictVersion as parse_version