diff --git a/.ci/build_wheels.sh b/.ci/build_wheels.sh index 14bcc9f6..4c24a3e4 100755 --- a/.ci/build_wheels.sh +++ b/.ci/build_wheels.sh @@ -6,15 +6,6 @@ set -e -x # build based on python version from args PYTHON_VERSION="$1" case $PYTHON_VERSION in -2.7) - PYBIN="/opt/python/cp27-cp27m/bin" - ;; -3.5) - PYBIN="/opt/python/cp35-cp35m/bin" - ;; -3.6) - PYBIN="/opt/python/cp36-cp36m/bin" - ;; 3.7) PYBIN="/opt/python/cp37-cp37m/bin" ;; @@ -31,8 +22,8 @@ esac # build, don't install cd io -"${PYBIN}/pip" install -r requirements_build.txt -"${PYBIN}/python" setup.py bdist_wheel +"${PYBIN}/pip" install build +"${PYBIN}/python" -m build --wheel auditwheel repair dist/ansys_mapdl_reader*.whl rm -f dist/* mv wheelhouse/*manylinux* dist/ diff --git a/.github/workflows/testing-and-deployment.yml b/.github/workflows/testing-and-deployment.yml index ca6623a6..e99894a3 100644 --- a/.github/workflows/testing-and-deployment.yml +++ b/.github/workflows/testing-and-deployment.yml @@ -18,28 +18,31 @@ on: branches: - main +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: - check_style: + stylecheck: name: Style Check runs-on: ubuntu-latest - steps: - uses: actions/checkout@v2 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v2.2.2 with: - python-version: 3.9 - - name: Style - run: | - pip install -r requirements_style.txt --disable-pip-version-check - make + python-version: '3.10' + - name: Install pre-commit + run: pip install pre-commit + - name: Run pre-commit + run: pre-commit run --all-files || ( git status --short ; git diff ; exit 1 ) doc_build: name: Build Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Python uses: actions/setup-python@v2 @@ -55,23 +58,20 @@ jobs: - name: Install ansys-mapdl-reader run: | - pip install -r requirements_build.txt --disable-pip-version-check - python setup.py bdist_wheel - pip install dist/ansys*.whl --disable-pip-version-check + pip install -e . cd tests/ xvfb-run python -c "from ansys.mapdl import reader as pymapdl_reader; print(pymapdl_reader.Report())" - name: Build Documentation run: | - sudo apt install pandoc -qy + sudo apt-get install zip pandoc -qy pip install -r requirements_docs.txt --disable-pip-version-check xvfb-run make -C doc html - sudo apt install zip cd doc/build/html/ zip ../../../${{ env.PACKAGE_NAME }}-HTML.zip ./* - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.PACKAGE_NAME }}-Documentation path: | @@ -97,7 +97,7 @@ jobs: os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 @@ -105,7 +105,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Linux pip cache - uses: actions/cache@v2 + uses: actions/cache@v3 if: ${{ runner.os == 'Linux' }} with: path: ~/.cache/pip @@ -114,7 +114,7 @@ jobs: Python-${{ runner.os }}-${{ matrix.python-version }} - name: Window pip cache - uses: actions/cache@v2 + uses: actions/cache@v3 if: ${{ runner.os == 'Windows' }} with: path: ~\AppData\Local\pip\Cache @@ -136,10 +136,6 @@ jobs: quay.io/pypa/manylinux2014_x86_64 \ /io/.ci/build_wheels.sh ${{ matrix.python-version }} - - name: Install VTK on Python 3.10 - if: matrix.python-version == '3.10' - run: pip install --find-links https://wheels.pyvista.org/ vtk - - name: Build wheel on Windows if: ${{ runner.os == 'Windows' }} run: | @@ -167,7 +163,7 @@ jobs: - name: Get PyVista tools if: ${{ runner.os == 'Windows' }} - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: pyvista/gl-ci-helpers path: pyvista-tools @@ -204,59 +200,30 @@ jobs: name: 'Upload coverage to Codecov' - name: Upload wheel - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.PACKAGE_NAME }}-${{ runner.os }}-${{ matrix.python-version }} path: dist/ retention-days: 7 - # mac_build: - # runs-on: macos-latest - # name: Mac OS Unit Testing - # strategy: - # matrix: - # python-version: ['3.8'] - - # steps: - # - uses: actions/checkout@v2 - - # - name: Set up Python ${{ matrix.python-version }} - # uses: actions/setup-python@v1 - # with: - # python-version: ${{ matrix.python-version }} - - # - name: Build wheels - # uses: joerick/cibuildwheel@v2.0.1 - # env: - # CIBW_BEFORE_BUILD: pip install -r requirements_build.txt - # CIBW_BUILD: cp38-macosx_x86_64 - - # - name: Build wheels - # if: startsWith(github.event.ref, 'refs/tags') - # uses: joerick/cibuildwheel@v2.0.1 - # env: - # CIBW_BEFORE_BUILD: pip install -r requirements_build.txt - # CIBW_SKIP: pp* cp38-macosx_x86_64 - - # - name: Show files - # run: ls -lh wheelhouse - # shell: bash - - # - name: Upload wheels - # uses: actions/upload-artifact@v2 - # with: - # path: wheelhouse/*.whl - - # - name: Install wheel - # run: | - # pip install wheelhouse/*38* - - # - name: Test - # run: | - # pip install -r requirements_test.txt - # cd tests - # pytest -v + mac_build: + if: github.event_name == 'push' && contains(github.ref, 'refs/tags') + name: Build wheels on MacOS + runs-on: macos-latest + + steps: + - uses: actions/checkout@v3 + + - name: Build wheels + uses: pypa/cibuildwheel@v2.8.1 + + - name: List generated wheels + run: | + ls ./wheelhouse/* + - uses: actions/upload-artifact@v3 + with: + path: ./wheelhouse/*.whl pymapdl_tests: name: PyMAPDL Unit Testing @@ -293,7 +260,7 @@ jobs: sudo apt install libgl1-mesa-glx xvfb - name: Linux pip cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.cache/pip key: Python-${{ runner.os }}-3.8-${{ hashFiles('setup.py') }}-${{ hashFiles('requirements_*.txt') }} @@ -340,7 +307,7 @@ jobs: Release: if: github.event_name == 'push' && contains(github.ref, 'refs/tags') - needs: [check_style, doc_build, build, pymapdl_tests] # , mac_build + needs: [stylecheck, doc_build, build, pymapdl_tests, mac_build] runs-on: ubuntu-latest steps: - name: Set up Python diff --git a/doc/source/conf.py b/doc/source/conf.py index 646cb167..7a350708 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -2,9 +2,9 @@ import os import warnings +from ansys_sphinx_theme import pyansys_logo_black import pyvista from sphinx_gallery.sorting import FileNameSortKey -from ansys_sphinx_theme import pyansys_logo_black from ansys.mapdl import reader as pymapdl_reader diff --git a/pyproject.toml b/pyproject.toml index 6a19e417..75a5b04a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,31 @@ [build-system] +build-backend = "setuptools.build_meta" requires = [ - "setuptools>=41.0.0", - "wheel>=0.33.0", - "numpy<=1.22.1", - "cython==0.29.24", -] \ No newline at end of file + "cython>=0.29", + "oldest-supported-numpy", + "setuptools>=45.0", + "wheel>=0.37.0", +] + +[tool.pytest.ini_options] +junit_family= "legacy" +filterwarnings = [ + "ignore::FutureWarning", + "ignore::PendingDeprecationWarning", + "ignore::DeprecationWarning", + # bogus numpy ABI warning (see numpy/#432) + "ignore:.*numpy.dtype size changed.*:RuntimeWarning", + "ignore:.*numpy.ufunc size changed.*:RuntimeWarning", + "ignore:.*Distutils was imported before Setuptools*", +] + +[tool.cibuildwheel] +archs = ["auto64"] # 64-bit only +skip = "pp* *musllinux*" # disable PyPy and musl-based wheels +test-requires = "ansys-mapdl-core>=0.60.4 matplotlib pytest scipy" +test-command = "pytest {project}/tests" + +[tool.cibuildwheel.macos] +# https://cibuildwheel.readthedocs.io/en/stable/faq/#apple-silicon +archs = ["x86_64"] # , "universal2" +test-skip = ["*_arm64", "*_universal2:arm64"] diff --git a/requirements_build.txt b/requirements_build.txt deleted file mode 100644 index 97b2b3a3..00000000 --- a/requirements_build.txt +++ /dev/null @@ -1,6 +0,0 @@ -setuptools>=41.0.0 -wheel>=0.33.0 -numpy<1.20.0;python_version<"3.10" -numpy==1.22.1;python_version>="3.10" -cython==0.29.24 -matplotlib diff --git a/requirements_test.txt b/requirements_test.txt index fc683985..9bfdd1f7 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,8 +1,5 @@ -scipy -pytest +ansys-mapdl-core>=0.60.4 matplotlib pytest pytest-cov -vtk<9.1.0;python_version<"3.10" -pyvista>=0.24.0 -ansys-mapdl-core>=0.60.4 +scipy diff --git a/setup.py b/setup.py index fd269ed2..3ce0ab5b 100644 --- a/setup.py +++ b/setup.py @@ -1,86 +1,14 @@ """Installation file for ansys-mapdl-reader""" from io import open as io_open import os -import platform -import re -import struct -import subprocess -import sys import numpy as np from setuptools import Extension, setup -from setuptools.command.build_ext import build_ext as _build_ext - -# Facilities to install properly on Mac using clang -def is_clang(bin): - proc = subprocess.Popen([bin, "-v"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = proc.communicate() - output = str(b"\n".join([stdout, stderr]).decode("ascii", "ignore")) - return not re.search(r"clang", output) is None - - -class build_ext(_build_ext): - """build class that includes numpy directory""" - - def build_extensions(self): - if os.name != "nt": - binary = self.compiler.compiler[0] - if is_clang(binary): - for e in self.extensions: - e.extra_compile_args.append("-stdlib=libc++") - - if platform.system() == "Darwin": - # get the minor version - mac_version, _, _ = platform.mac_ver() - minor = [int(n) for n in mac_version.split(".")][1] - - # libstdc++ is deprecated in recent versions of XCode - if minor >= 9: - e.extra_compile_args.append("-mmacosx-version-min=10.9") - e.extra_compile_args.append("-stdlib=libc++") - e.extra_link_args.append("-mmacosx-version-min=10.9") - e.extra_link_args.append("-stdlib=libc++") - else: - e.extra_compile_args.append("-mmacosx-version-min=10.7") - e.extra_link_args.append("-mmacosx-version-min=10.7") - - _build_ext.build_extensions(self) - - -def compiler_name(): - """Check compiler and assign compile arguments accordingly""" - import distutils.ccompiler - import re - - comp = distutils.ccompiler.get_default_compiler() - getnext = False - - for a in sys.argv[2:]: - if getnext: - comp = a - getnext = False - continue - # separated by space - if a == "--compiler" or re.search("^-[a-z]*c$", a): - getnext = True - continue - # without space - m = re.search("^--compiler=(.+)", a) - if m is None: - m = re.search("^-[a-z]*c(.+)", a) - if m: - comp = m.group(1) - - return comp - - -# Assign arguments based on compiler -compiler = compiler_name() -if compiler == "unix": - cmp_arg = ["-O3", "-w"] -else: - cmp_arg = ["/Ox", "-w"] +if os.name == "nt": # windows + extra_compile_args = ["/openmp", "/O2", "/w", "/GS"] +elif os.name == "posix": # linux/mac os + extra_compile_args = ["-O3", "-w"] # Get version from version info @@ -91,27 +19,6 @@ def compiler_name(): # execute file from raw string exec(fd.read()) -install_requires = [ - "numpy>=1.16.0", - "pyvista>=0.32.0", - "appdirs>=1.4.0", - "matplotlib>=3.0.0", - "tqdm>=4.45.0", -] - -# perform python version checking -# this is necessary to avoid the new pip package checking as vtk does -# not support Python 32-bit as of 17 June 2021. -is64 = struct.calcsize("P") * 8 == 64 -if not is64: - try: - import vtk # noqa: F401 - except ImportError: - raise RuntimeError( - "\n\n``ansys-mapdl-reader`` requires 64-bit Python due to vtk.\n" - "Please check the version of Python installed at\n" - "%s" % sys.executable - ) setup( name="ansys-mapdl-reader", @@ -137,7 +44,7 @@ def compiler_name(): ], url="https://github.com/pyansys/pymapdl-reader", # Build cython modules - cmdclass={"build_ext": build_ext}, + # cmdclass={"build_ext": build_ext}, include_dirs=[np.get_include()], ext_modules=[ Extension( @@ -146,7 +53,7 @@ def compiler_name(): "ansys/mapdl/reader/cython/_archive.pyx", "ansys/mapdl/reader/cython/archive.c", ], - extra_compile_args=cmp_arg, + extra_compile_args=extra_compile_args, language="c", ), Extension( @@ -156,19 +63,19 @@ def compiler_name(): "ansys/mapdl/reader/cython/reader.c", "ansys/mapdl/reader/cython/vtk_support.c", ], - extra_compile_args=cmp_arg, + extra_compile_args=extra_compile_args, language="c", ), Extension( "ansys.mapdl.reader._relaxmidside", ["ansys/mapdl/reader/cython/_relaxmidside.pyx"], - extra_compile_args=cmp_arg, + extra_compile_args=extra_compile_args, language="c", ), Extension( "ansys.mapdl.reader._cellqual", ["ansys/mapdl/reader/cython/_cellqual.pyx"], - extra_compile_args=cmp_arg, + extra_compile_args=extra_compile_args, language="c", ), Extension( @@ -177,7 +84,7 @@ def compiler_name(): "ansys/mapdl/reader/cython/_binary_reader.pyx", "ansys/mapdl/reader/cython/binary_reader.cpp", ], - extra_compile_args=cmp_arg, + extra_compile_args=extra_compile_args, language="c++", ), ], @@ -193,5 +100,11 @@ def compiler_name(): "sector.cdb", ] }, - install_requires=install_requires, + install_requires=[ + "numpy>=1.16.0", + "pyvista>=0.32.0", + "appdirs>=1.4.0", + "matplotlib>=3.0.0", + "tqdm>=4.45.0", + ], ) diff --git a/tests/test_cyclic.py b/tests/test_cyclic.py index ebcbabab..d4dbf7e6 100644 --- a/tests/test_cyclic.py +++ b/tests/test_cyclic.py @@ -37,6 +37,9 @@ reason="Plotting disabled for these tests", ) +skip_windows = pytest.mark.skipif( + os.name == "nt", reason="Test fails due to OSMESA on Windows" +) # static result x axis @pytest.fixture(scope="module") @@ -109,6 +112,7 @@ def test_non_cyclic(): rst = CyclicResult(examples.rstfile) +@skip_windows @skip_plotting @pytest.mark.skipif(result_z is None, reason="Requires result file") def test_plot_sectors(tmpdir): @@ -119,6 +123,7 @@ def test_plot_sectors(tmpdir): assert os.path.isfile(filename) +@skip_windows @skip_plotting def test_plot_sectors_x(result_x): cpos = result_x.plot_sectors() @@ -126,6 +131,7 @@ def test_plot_sectors_x(result_x): assert isinstance(cpos, CameraPosition) +@skip_windows @skip_plotting @pytest.mark.skipif(result_z is None, reason="Requires result file") def test_plot_z_cyc(): @@ -134,6 +140,7 @@ def test_plot_z_cyc(): assert isinstance(cpos, CameraPosition) +@skip_windows @skip_plotting def test_plot_x_cyc(result_x): cpos = result_x.plot() @@ -141,6 +148,7 @@ def test_plot_x_cyc(result_x): assert isinstance(cpos, CameraPosition) +@skip_windows @skip_plotting def test_plot_component_rotor(cyclic_v182_z_with_comp): cyclic_v182_z_with_comp.plot_nodal_solution( @@ -283,6 +291,7 @@ def test_full_z_nodal_solution_phase(cyclic_v182_z): assert np.allclose(disp[:, mask], tmp) +@skip_windows @skip_plotting def test_full_x_nodal_solution_plot(result_x): result_x.plot_nodal_solution(0) @@ -354,6 +363,7 @@ def test_full_x_principal_nodal_stress(result_x): assert np.allclose(stress[:, mask], tmp, atol=4e-3) # too loose +@skip_windows @skip_plotting @pytest.mark.skipif(not HAS_FFMPEG, reason="requires imageio_ffmpeg") @pytest.mark.skipif(result_z is None, reason="Requires result file") @@ -385,16 +395,19 @@ def test_cyclic_z_harmonic_displacement(): assert np.allclose(disp[:, mask], tmp, atol=1e-5) +@skip_windows @skip_plotting def test_plot_nodal_stress(result_x): result_x.plot_nodal_stress(0, "z") +@skip_windows @skip_plotting def test_plot_nodal_stress(result_x): result_x.plot_nodal_stress(0, "z") +@skip_windows @skip_plotting def test_plot_principal_nodal_stress(result_x): result_x.plot_principal_nodal_stress(0, "seqv") @@ -416,6 +429,7 @@ def test_nodal_elastic_strain_cyclic(result_x): assert np.allclose(stress, stress_ans) +@skip_windows @skip_plotting def test_plot_nodal_elastic_strain(result_x): result_x.plot_nodal_elastic_strain(0, "X") @@ -437,6 +451,7 @@ def test_nodal_temperature(result_x): assert np.allclose(temp[mask], temp_ans[:, mask], equal_nan=True) +@skip_windows @skip_plotting def test_plot_nodal_nodal_temperature(result_x): result_x.plot_nodal_temperature(0) @@ -457,6 +472,7 @@ def test_nodal_thermal_strain_cyclic(result_x): assert np.allclose(strain, strain_ans) +@skip_windows @skip_plotting def test_plot_nodal_thermal_strain(result_x): result_x.plot_nodal_thermal_strain(0, "X")