diff --git a/src/harmonica/_forward/ellipsoids/ellipsoids.py b/src/harmonica/_forward/ellipsoids/ellipsoids.py index 174e034e5..80d49a686 100644 --- a/src/harmonica/_forward/ellipsoids/ellipsoids.py +++ b/src/harmonica/_forward/ellipsoids/ellipsoids.py @@ -16,11 +16,6 @@ from ..utils import get_rotation_matrix -try: - import pyvista -except ImportError: # pragma: no cover - pyvista = None - class Ellipsoid: """ @@ -313,12 +308,9 @@ def to_pyvista(self, **kwargs): ellipsoid : pyvista.PolyData A PyVista's parametric ellipsoid. """ - if pyvista is None: - msg = ( - "Missing optional dependency 'pyvista' required for " - "exporting ellipsoids to PyVista." - ) - raise ImportError(msg) + # Lazy load optional dependency + import pyvista # noqa: PLC0415 + ellipsoid = pyvista.ParametricEllipsoid( xradius=self.a, yradius=self.b, zradius=self.c, **kwargs ) diff --git a/src/harmonica/_forward/utils.py b/src/harmonica/_forward/utils.py index aa1b46264..6270b3632 100644 --- a/src/harmonica/_forward/utils.py +++ b/src/harmonica/_forward/utils.py @@ -14,12 +14,6 @@ from numba import jit from scipy.spatial.transform import Rotation -# Attempt to import numba_progress -try: - from numba_progress import ProgressBar -except ImportError: # pragma: no cover - ProgressBar = None - def distance(point_p, point_q, coordinate_system="cartesian", ellipsoid=None): """ @@ -384,12 +378,17 @@ def initialize_progressbar(total, use_progressbar): # Return None if progressbar is not desired if not use_progressbar: return contextlib.nullcontext() - # Raise error if numba_progress is not installed - if ProgressBar is None: - msg = ( - "Missing optional dependency 'numba_progress' required if progressbar=True" - ) - raise ImportError(msg) + + # Lazily load optional dependency + try: + from numba_progress import ProgressBar # noqa: PLC0415 + except ImportError as original: # pragma: nocover + error = ImportError( + "Cannot import the optional dependency 'numba_progress'. " + "It must be installed to be able to show a progressbar." + ) # pragma: nocover + raise error from original # pragma: nocover + return ProgressBar(total=total) diff --git a/src/harmonica/visualization/_prism.py b/src/harmonica/visualization/_prism.py index 68ccf35ce..7a4451b0a 100644 --- a/src/harmonica/visualization/_prism.py +++ b/src/harmonica/visualization/_prism.py @@ -10,13 +10,6 @@ import numpy as np -try: - import pyvista -except ImportError: # pragma: no cover - pyvista = None -else: - import vtk - def prism_to_pyvista(prisms, properties=None): """ @@ -71,12 +64,10 @@ def prism_to_pyvista(prisms, properties=None): >>> pv_grid.plot() # doctest: +SKIP """ - # Check if pyvista are installed - if pyvista is None: - msg = ( - "Missing optional dependency 'pyvista' required for building pyvista grids." - ) - raise ImportError(msg) + # Lazily import optional dependencies + import pyvista # noqa: PLC0415 + import vtk # noqa: PLC0415 + # Get prisms and number of prisms prisms = np.atleast_2d(prisms) n_prisms = prisms.shape[0] diff --git a/test/ellipsoids/test_ellipsoids.py b/test/ellipsoids/test_ellipsoids.py index 1fd09092e..dd56daa1d 100644 --- a/test/ellipsoids/test_ellipsoids.py +++ b/test/ellipsoids/test_ellipsoids.py @@ -9,7 +9,6 @@ """ import re -from unittest.mock import patch import numpy as np import pytest @@ -212,14 +211,6 @@ def ellipsoid(self): center = (43.0, -72.0, 105) return Ellipsoid(a, b, c, yaw=yaw, pitch=pitch, roll=roll, center=center) - @patch("harmonica._forward.ellipsoids.ellipsoids.pyvista", None) - def test_pyvista_missing_error(self, ellipsoid): - """ - Check if error is raised when pyvista is not installed. - """ - with pytest.raises(ImportError): - ellipsoid.to_pyvista() - def test_pyvista_object(self, ellipsoid): """ Check if method works as expected. diff --git a/test/test_forward_utils.py b/test/test_forward_utils.py index 2d8a69b8d..1e20d7891 100644 --- a/test/test_forward_utils.py +++ b/test/test_forward_utils.py @@ -8,8 +8,6 @@ Test utils functions for forward modelling. """ -from unittest.mock import patch - import boule as bl import numpy as np import numpy.testing as npt @@ -131,16 +129,3 @@ def test_initialize_progressbar(use_progressbar): assert isinstance(progress_proxy, ProgressBar) else: assert progress_proxy is None - - -@patch("harmonica._forward.utils.ProgressBar", None) -@pytest.mark.parametrize("use_progressbar", [True, False]) -def test_initialize_progressbar_import_error(use_progressbar): - """Test if it raises ImportError when numba_progress is missing.""" - if use_progressbar: - with pytest.raises(ImportError): # noqa: SIM117 - with initialize_progressbar(3, use_progressbar) as progress_proxy: - pass # pragma: no cover (won't reach this code) - else: - with initialize_progressbar(3, use_progressbar) as progress_proxy: - assert progress_proxy is None diff --git a/test/test_prism.py b/test/test_prism.py index c6330ae64..38463f50e 100644 --- a/test/test_prism.py +++ b/test/test_prism.py @@ -9,7 +9,6 @@ """ import re -from unittest.mock import patch import bordado as bd import numpy as np @@ -377,18 +376,6 @@ def test_progress_bar(self, coordinates, prisms, densities, field): ) npt.assert_allclose(result_progress_true, result_progress_false) - @patch("harmonica._forward.utils.ProgressBar", None) - def test_numba_progress_missing_error(self, coordinates, prisms, densities): - """ - Check if error is raised when progresbar=True and numba_progress - package is not installed. - """ - # Check if error is raised - with pytest.raises(ImportError): - prism_gravity( - coordinates, prisms, densities, field="potential", progressbar=True - ) - class TestSingularPoints: """ diff --git a/test/test_prism_layer.py b/test/test_prism_layer.py index 60620a128..9ee5141ff 100644 --- a/test/test_prism_layer.py +++ b/test/test_prism_layer.py @@ -9,7 +9,6 @@ """ import re -from unittest.mock import patch import bordado as bd import numpy as np @@ -420,24 +419,6 @@ def test_progress_bar(dummy_layer): npt.assert_allclose(result_progress_true, result_progress_false) -@patch("harmonica._forward.utils.ProgressBar", None) -def test_numba_progress_missing_error(dummy_layer): - """ - Check if error is raised when progressbar=True and numba_progress package - is not installed. - """ - coordinates = bd.grid_coordinates( - (1, 3, 7, 10), spacing=1, non_dimensional_coords=30.0 - ) - (easting, northing), surface, reference, density = dummy_layer - layer = prism_layer( - (easting, northing), surface, reference, properties={"density": density} - ) - # Check if error is raised - with pytest.raises(ImportError): - layer.prism_layer.gravity(coordinates, field="g_z", progressbar=True) - - def test_gravity_discarded_thin_prisms(dummy_layer): """ Check if gravity of prism layer after discarding thin prisms is correct. diff --git a/test/test_tesseroid.py b/test/test_tesseroid.py index 9f4e2865e..80d18158a 100644 --- a/test/test_tesseroid.py +++ b/test/test_tesseroid.py @@ -9,7 +9,6 @@ """ import re -from unittest.mock import patch import bordado as bd import boule @@ -808,15 +807,3 @@ def test_progress_bar(self, coordinates, tesseroids, densities, field): coordinates, tesseroids, densities, field=field, progressbar=False ) npt.assert_allclose(result_progress_true, result_progress_false) - - @patch("harmonica._forward.utils.ProgressBar", None) - def test_numba_progress_missing_error(self, coordinates, tesseroids, densities): - """ - Check if error is raised when progresbar=True and numba_progress - package is not installed. - """ - # Check if error is raised - with pytest.raises(ImportError): - tesseroid_gravity( - coordinates, tesseroids, densities, field="potential", progressbar=True - ) diff --git a/test/test_tesseroid_layer.py b/test/test_tesseroid_layer.py index 6504aed27..40f18badc 100644 --- a/test/test_tesseroid_layer.py +++ b/test/test_tesseroid_layer.py @@ -9,7 +9,6 @@ """ import warnings -from unittest.mock import patch import bordado as bd import boule @@ -493,24 +492,6 @@ def test_progress_bar(dummy_layer): npt.assert_allclose(result_progress_true, result_progress_false) -@patch("harmonica._forward.utils.ProgressBar", None) -def test_numba_progress_missing_error(dummy_layer): - """ - Check if error is raised when progressbar=True and numba_progress package - is not installed. - """ - (longitude, latitude), surface, reference, density = dummy_layer - coordinates = bd.grid_coordinates( - (-10, 10, -10, 10), spacing=7, non_dimensional_coords=(surface[0] + 10e3) - ) - layer = tesseroid_layer( - (longitude, latitude), surface, reference, properties={"density": density} - ) - # Check if error is raised - with pytest.raises(ImportError): - layer.tesseroid_layer.gravity(coordinates, field="g_z", progressbar=True) - - def test_gravity_discarded_thin_tesseroids(dummy_layer): """ Check if gravity of tesseroid layer after discarding thin tesseroids is correct. diff --git a/test/test_tesseroid_variable_density.py b/test/test_tesseroid_variable_density.py index 4707028b9..f7f38065f 100644 --- a/test/test_tesseroid_variable_density.py +++ b/test/test_tesseroid_variable_density.py @@ -8,8 +8,6 @@ Test forward modelling for tesseroids with variable density. """ -from unittest.mock import patch - import bordado as bd import numpy as np import numpy.testing as npt @@ -569,15 +567,3 @@ def test_progress_bar(self, coordinates, tesseroids, densities, field): coordinates, tesseroids, densities, field=field, progressbar=False ) npt.assert_allclose(result_progress_true, result_progress_false) - - @patch("harmonica._forward.utils.ProgressBar", None) - def test_numba_progress_missing_error(self, coordinates, tesseroids, densities): - """ - Check if error is raised when progresbar=True and numba_progress - package is not installed. - """ - # Check if error is raised - with pytest.raises(ImportError): - tesseroid_gravity( - coordinates, tesseroids, densities, field="potential", progressbar=True - ) diff --git a/test/test_visualizations.py b/test/test_visualizations.py index 31338c619..84b598b94 100644 --- a/test/test_visualizations.py +++ b/test/test_visualizations.py @@ -9,7 +9,6 @@ """ import re -from unittest.mock import patch import numpy as np import numpy.testing as npt @@ -24,17 +23,6 @@ pyvista = None -@patch("harmonica.visualization._prism.pyvista", None) -def test_prism_to_pyvista_missing_pyvista(): - """ - Check error raise after calling prism_to_pyvista when pyvista is missing. - """ - prism = [0, 1, 0, 1, 0, 1] - with pytest.raises(ImportError) as exception: - prism_to_pyvista(prism) - assert "'pyvista'" in str(exception.value) - - @pytest.fixture(name="prisms") def fixture_prisms(): """ @@ -124,13 +112,3 @@ def test_prism_to_pyvista_error_2d_property(prisms, density): ) with pytest.raises(ValueError, match=msg): prism_to_pyvista(prisms, properties={name: density_2d}) - - -@patch("harmonica.visualization._prism.pyvista", None) -def test_prisms_pyvista_missing_error(prisms, density): - """ - Check if prism_to_pyvista raises error if pyvista is missing. - """ - # Check if error is raised - with pytest.raises(ImportError): - prism_to_pyvista(prisms, properties={"density": density})