Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPython to GMT Legacy Tests CI environment #2283

Merged
merged 16 commits into from
Dec 31, 2022
Merged

Conversation

weiji14
Copy link
Member

@weiji14 weiji14 commented Dec 28, 2022

Description of proposed changes

To fix errors like pygmt.exceptions.GMTError: Notebook display is selected, but IPython is not available. Make sure you have IPython installed, or run the script in a Jupyter notebook in the GMT Legacy Tests (i.e. GMT 6.3 Continuous Integration tests ran on Wednesday).

Note that the addition <IPython.core.display.Image object> to the doctests will fix both make test_no_image and make fulltest.

Addresses #2281 (comment), patches #1833.

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If wrapping a new module, open a 'Wrap new GMT module' issue and submit reasonably-sized PRs.
  • If adding new functionality, add an example to docstrings or tutorials.
  • Use underscores (not hyphens) in names of Python files and directories.

Slash Commands

You can write slash commands (/command) in the first line of a comment to perform
specific operations. Supported slash commands are:

  • /format: automatically format and lint the code
  • /test-gmt-dev: run full tests on the latest GMT development version

To fix errors like `pygmt.exceptions.GMTError: Notebook display is selected, but IPython is not available. Make sure you have IPython installed, or run the script in a Jupyter notebook`.
@weiji14 weiji14 added maintenance Boring but important stuff for the core devs skip-changelog Skip adding Pull Request to changelog labels Dec 28, 2022
@weiji14 weiji14 added this to the 0.8.0 milestone Dec 28, 2022
@weiji14 weiji14 self-assigned this Dec 28, 2022
@weiji14
Copy link
Member Author

weiji14 commented Dec 28, 2022

Traceback for the 22 failing tests from https://github.com/GenericMappingTools/pygmt/actions/runs/3796568197/jobs/6456779355#step:11:720. Most should be fixed by #2281, some look like actual differences in functions between GMT 6.3 and 6.4, others are to do with the <IPython.core.display.Image object> output.

_______________________ [doctest] pygmt.src.coast.coast ________________________
256 ...     frame="a",
257 ...     # Set the color of the land to "darkgreen"
258 ...     land="darkgreen",
259 ...     # Set the color of the water to "lightblue"
260 ...     water="lightblue",
261 ...     # Draw national borders with a 1-point black line
262 ...     borders="1/1p,black",
263 ... )
264 >>> # Show the plot
265 >>> fig.show()
Expected nothing
Got:
    <IPython.core.display.Image object>

/home/runner/work/pygmt/pygmt/pygmt/src/coast.py:265: DocTestFailure
_____________________ [doctest] pygmt.src.grd2cpt.grd2cpt ______________________
197 >>> # load the 30 arc-minutes grid with "gridline" registration
198 >>> grid = pygmt.datasets.load_earth_relief("30m", registration="gridline")
199 >>> # create a plot
200 >>> fig = pygmt.Figure()
201 >>> # create a CPT from the grid object with grd2cpt
202 >>> pygmt.grd2cpt(grid=grid)
203 >>> # plot the grid object, the CPT will be automatically used
204 >>> fig.grdimage(grid=grid)
205 >>> # show the plot
206 >>> fig.show()
Expected nothing
Got:
    <IPython.core.display.Image object>

/home/runner/work/pygmt/pygmt/pygmt/src/grd2cpt.py:206: DocTestFailure
_____________________ [doctest] pygmt.src.grd2xyz.grd2xyz ______________________
247 -------
248 >>> import pygmt
249 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
250 >>> # and a y-range of 15 to 25
251 >>> grid = pygmt.datasets.load_earth_relief(
252 ...     resolution="30m", region=[10, 30, 15, 25]
253 ... )
254 >>> # Create a pandas DataFrame with the xyz data from an input grid
255 >>> xyz_dataframe = pygmt.grd2xyz(grid=grid, output_type="pandas")
256 >>> xyz_dataframe.head(n=2)
Differences (unified diff with -expected +actual):
    @@ -1,3 +1,3 @@
    -     lon    lat  elevation
    -0  10.25  24.75      903.5
    -1  10.75  24.75      820.0
    +    lon   lat  elevation
    +0  10.0  25.0      863.0
    +1  10.5  25.0      985.5

/home/runner/work/pygmt/pygmt/pygmt/src/grd2xyz.py:256: DocTestFailure
_____________________ [doctest] pygmt.src.grdclip.grdclip ______________________
103 Example
104 -------
105 >>> import pygmt
106 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
107 >>> # and a y-range of 15 to 25
108 >>> grid = pygmt.datasets.load_earth_relief(
109 ...     resolution="30m", region=[10, 30, 15, 25]
110 ... )
111 >>> # Report the minimum and maximum data values
112 >>> [grid.data.min(), grid.data.max()]
Expected:
    [179.0, 2103.0]
Got:
    [170.0, 2275.5]

/home/runner/work/pygmt/pygmt/pygmt/src/grdclip.py:112: DocTestFailure
__________________ [doctest] pygmt.src.grdcontour.grdcontour ___________________
174 ...     interval=250,
175 ...     # set the interval for annotated contour lines at 1,000 meters
176 ...     annotation=1000,
177 ...     # add a frame for the plot
178 ...     frame="a",
179 ...     # set the projection to Mercator for the 10 cm figure
180 ...     projection="M10c",
181 ... )
182 >>> # show the plot
183 >>> fig.show()
Expected nothing
Got:
    <IPython.core.display.Image object>

/home/runner/work/pygmt/pygmt/pygmt/src/grdcontour.py:183: DocTestFailure
----------------------------- Captured stderr call -----------------------------
Notice: NOTICE]: Remote data courtesy of GMT data server oceania [http://oceania.generic-mapping-tools.org]
Notice: NOTICE]: SRTM15 Earth Relief at 15x15 arc minutes reduced by Gaussian Cartesian filtering (27.8 km fullwidth) [Tozer et al., 2019].
Notice: NOTICE]:   -> Download grid file [1.4M]: earth_relief_15m_g.grd
_____________ [doctest] pygmt.src.grdhisteq.grdhisteq.compute_bins _____________
329 >>> import pygmt
330 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to
331 >>> # 30, and a y-range of 15 to 25
332 >>> grid = pygmt.datasets.load_earth_relief(
333 ...     resolution="30m", region=[10, 30, 15, 25]
334 ... )
335 >>> # Find elevation intervals that splits the data range into 5
336 >>> # divisions, each of which have an equal area in the original grid.
337 >>> bins = pygmt.grdhisteq.compute_bins(grid=grid, divisions=5)
338 >>> print(bins)
Differences (unified diff with -expected +actual):
    @@ -1,7 +1,7 @@
             start    stop
    -bin_id
    -0       179.0   397.5
    -1       397.5   475.5
    -2       475.5   573.5
    -3       573.5   710.5
    -4       710.5  2103.0
    +bin_id               
    +0       170.0   389.0
    +1       389.0   470.5
    +2       470.5   571.0
    +3       571.0   705.0
    +4       705.0  2275.5

/home/runner/work/pygmt/pygmt/pygmt/src/grdhisteq.py:338: DocTestFailure
____________________ [doctest] pygmt.src.grdimage.grdimage _____________________
245 >>> import pygmt
246 >>> # load the 30 arc-minutes grid with "gridline" registration
247 >>> grid = pygmt.datasets.load_earth_relief("30m", registration="gridline")
248 >>> # create a new plot with pygmt.Figure()
249 >>> fig = pygmt.Figure()
250 >>> # pass in the grid and set the CPT to "geo"
251 >>> # set the projection to Mollweide and the size to 10 cm
252 >>> fig.grdimage(grid=grid, cmap="geo", projection="W10c", frame="ag")
253 >>> # show the plot
254 >>> fig.show()
Expected nothing
Got:
    <IPython.core.display.Image object>

/home/runner/work/pygmt/pygmt/pygmt/src/grdimage.py:254: DocTestFailure
___________________ [doctest] pygmt.src.grdvolume.grdvolume ____________________
104 ...     resolution="30m", region=[10, 30, 15, 25]
105 ... )
106 >>> # Create a pandas dataframe that contains the contour, area, volume,
107 >>> # and maximum mean height above the plane specified by the given
108 >>> # contour and below the surface; set the minimum contour z-value to
109 >>> # 200, the maximum to 400, and the interval to 50.
110 >>> output_dataframe = pygmt.grdvolume(
111 ...     grid=grid, contour=[200, 400, 50], output_type="pandas"
112 ... )
113 >>> print(output_dataframe)
Differences (unified diff with -expected +actual):
    @@ -1,6 +1,6 @@
    -         0             1             2           3
    -    0  200  2.144285e+12  7.972228e+14  371.789489
    -    1  250  2.104042e+12  6.908183e+14  328.329232
    -    2  300  2.014978e+12  5.877195e+14  291.675420
    -    3  350  1.892109e+12  4.897545e+14  258.840510
    -    4  400  1.744792e+12  3.988316e+14  228.584026
    +     0             1             2           3
    +0  200  2.318187e+12  8.533727e+14  368.120722
    +1  250  2.272471e+12  7.383936e+14  324.929840
    +2  300  2.162074e+12  6.273066e+14  290.141086
    +3  350  2.018302e+12  5.222640e+14  258.764032
    +4  400  1.857370e+12  4.252699e+14  228.963499

/home/runner/work/pygmt/pygmt/pygmt/src/grdvolume.py:113: DocTestFailure
_______________________ [doctest] pygmt.src.solar.solar ________________________
129 ...     terminator="day_night",
130 ...     # pass the datetime object
131 ...     terminator_datetime=date,
132 ...     # fill the night-section with navyblue at 75% transparency
133 ...     fill="navyblue@75",
134 ...     # draw the terminator with a 1-point black line
135 ...     pen="1p,black",
136 ... )
137 >>> # show the plot
138 >>> fig.show()
Expected nothing
Got:
    <IPython.core.display.Image object>

/home/runner/work/pygmt/pygmt/pygmt/src/solar.py:138: DocTestFailure
________________________ test_earth_relief_fails[gebco] ________________________

data_source = 'gebco'

    @pytest.mark.parametrize("data_source", ["igpp", "gebco", "gebcosi", "synbath"])
    def test_earth_relief_fails(data_source):
        """
        Make sure earth relief fails for invalid resolutions.
        """
        resolutions = "1m 1d bla 60d 001m 03".split()
        resolutions.append(60)
        for resolution in resolutions:
            with pytest.raises(GMTInvalidInput):
>               load_earth_relief(resolution=resolution, data_source=data_source)

../pygmt/tests/test_datasets_earth_relief.py:20: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../pygmt/helpers/decorators.py:734: in new_module
    return module_func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

resolution = '1m', region = None, registration = None, data_source = 'gebco'
use_srtm = False

    @kwargs_to_strings(region="sequence")
    def load_earth_relief(
        resolution="01d",
        region=None,
        registration=None,
        data_source="igpp",
        use_srtm=False,
    ):
        r"""
        Load Earth relief grids (topography and bathymetry) in various resolutions.
    
        The grids are downloaded to a user data directory
        (usually a subdirectory under ~/.gmt/server/earth/) the first time you
        invoke this function. Afterwards, it will load the grid from the data
        directory. So you'll need an internet connection the first time around.
    
        This module downloads the grids that can also be accessed by
        passing in the file name **@**\ *earth_relief_type*\_\ *res*\[_\ *reg*] to
        any grid plotting/processing function. *earth_relief_type* is the GMT name
        for the dataset. The available options are **earth_relief**\,
        **earth_gebco**\, **earth_gebcosi**\, and **earth_synbath**\. *res* is the
        grid resolution (see below), and *reg* is grid registration type
        (**p** for pixel registration or **g** for gridline registration).
    
        Refer to :gmt-datasets:`earth-relief.html` for more details about available
        datasets, including version information and references.
    
        Parameters
        ----------
        resolution : str
            The grid resolution. The suffix ``d``, ``m`` and ``s`` stand for
            arc-degrees, arc-minutes, and arc-seconds. It can be ``"01d"``,
            ``"30m"``, ``"20m"``, ``"15m"``, ``"10m"``, ``"06m"``, ``"05m"``,
            ``"04m"``, ``"03m"``, ``"02m"``, ``"01m"``, ``"30s"``, ``"15s"``,
            ``"03s"``, or ``"01s"``.
    
        region : str or list
            The subregion of the grid to load, in the form of a list
            [*xmin*, *xmax*, *ymin*, *ymax*] or a string *xmin/xmax/ymin/ymax*.
            Required for Earth relief grids with resolutions higher than 5
            arc-minutes (i.e., ``"05m"``).
    
        registration : str
            Grid registration type. Either ``"pixel"`` for pixel registration or
            ``"gridline"`` for gridline registration. Default is ``"gridline"``
            for all resolutions except ``"15s"`` which is ``"pixel"`` only.
    
        data_source : str
            Select the source for the Earth relief data.
    
            Available options:
    
            - **igpp** : IGPP Global Earth Relief [Default option]. See
              :gmt-datasets:`earth-relief.html`.
    
            - **synbath** : IGPP Global Earth Relief dataset that uses
              stastical properties of young seafloor to provide more realistic
              relief of young areas with small seamounts.
    
            - **gebco** : GEBCO Global Earth Relief with only observed relief and
              inferred relief via altimetric gravity. See
              :gmt-datasets:`earth-gebco.html`.
    
            - **gebcosi** : GEBCO Global Earth Relief that gives sub-ice (si)
              elevations.
    
        use_srtm : bool
            By default, the land-only SRTM tiles from NASA are used to generate the
            ``"03s"`` and ``"01s"`` grids, and the missing ocean values are filled
            by up-sampling the SRTM15 tiles which have a resolution of 15
            arc-seconds (i.e., ``"15s"``). If True, will only load the original
            land-only SRTM tiles. Only works when ``data_source="igpp"``.
    
        Returns
        -------
        grid : :class:`xarray.DataArray`
            The Earth relief grid. Coordinates are latitude and longitude in
            degrees. Relief is in meters.
    
        Note
        ----
        The :class:`xarray.DataArray` grid doesn't support slice operation, for
        Earth relief data with resolutions of 5 arc-minutes or higher, which are
        stored as smaller tiles.
    
        Examples
        --------
    
        >>> from pygmt.datasets import load_earth_relief
        >>> # load the default grid (gridline-registered 1 arc-degree grid)
        >>> grid = load_earth_relief()
        >>> # load the 30 arc-minutes grid with "gridline" registration
        >>> grid = load_earth_relief(resolution="30m", registration="gridline")
        >>> # load high-resolution (5 arc-minutes) grid for a specific region
        >>> grid = load_earth_relief(
        ...     resolution="05m",
        ...     region=[120, 160, 30, 60],
        ...     registration="gridline",
        ... )
        >>> # load the original 3 arc-seconds land-only SRTM tiles from NASA
        >>> grid = load_earth_relief(
        ...     resolution="03s",
        ...     region=[135, 136, 35, 36],
        ...     registration="gridline",
        ...     use_srtm=True,
        ... )
        """
        # resolutions of original land-only SRTM tiles from NASA
        land_only_srtm_resolutions = ["03s", "01s"]
    
        earth_relief_sources = {
            "igpp": "earth_relief_",
            "gebco": "earth_gebco_",
            "gebcosi": "earth_gebcosi_",
            "synbath": "earth_synbath_",
        }
        if data_source not in earth_relief_sources:
            raise GMTInvalidInput(
                f"Invalid earth relief 'data_source' {data_source}, "
                "valid values are 'igpp', 'gebco', 'gebcosi' and 'synbath'."
            )
        if data_source != "igpp":
            with Session() as lib:
                if Version(lib.info["version"]) < Version("6.4.0"):
>                   raise GMTVersionError(
                        f"The {data_source} option is not available for GMT"
                        " versions before 6.4.0."
                    )
E                   pygmt.exceptions.GMTVersionError: The gebco option is not available for GMT versions before 6.4.0.

../pygmt/datasets/earth_relief.py:140: GMTVersionError
_______________________ test_earth_relief_fails[gebcosi] _______________________

data_source = 'gebcosi'

    @pytest.mark.parametrize("data_source", ["igpp", "gebco", "gebcosi", "synbath"])
    def test_earth_relief_fails(data_source):
        """
        Make sure earth relief fails for invalid resolutions.
        """
        resolutions = "1m 1d bla 60d 001m 03".split()
        resolutions.append(60)
        for resolution in resolutions:
            with pytest.raises(GMTInvalidInput):
>               load_earth_relief(resolution=resolution, data_source=data_source)

../pygmt/tests/test_datasets_earth_relief.py:20: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../pygmt/helpers/decorators.py:734: in new_module
    return module_func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

resolution = '1m', region = None, registration = None, data_source = 'gebcosi'
use_srtm = False

    @kwargs_to_strings(region="sequence")
    def load_earth_relief(
        resolution="01d",
        region=None,
        registration=None,
        data_source="igpp",
        use_srtm=False,
    ):
        r"""
        Load Earth relief grids (topography and bathymetry) in various resolutions.
    
        The grids are downloaded to a user data directory
        (usually a subdirectory under ~/.gmt/server/earth/) the first time you
        invoke this function. Afterwards, it will load the grid from the data
        directory. So you'll need an internet connection the first time around.
    
        This module downloads the grids that can also be accessed by
        passing in the file name **@**\ *earth_relief_type*\_\ *res*\[_\ *reg*] to
        any grid plotting/processing function. *earth_relief_type* is the GMT name
        for the dataset. The available options are **earth_relief**\,
        **earth_gebco**\, **earth_gebcosi**\, and **earth_synbath**\. *res* is the
        grid resolution (see below), and *reg* is grid registration type
        (**p** for pixel registration or **g** for gridline registration).
    
        Refer to :gmt-datasets:`earth-relief.html` for more details about available
        datasets, including version information and references.
    
        Parameters
        ----------
        resolution : str
            The grid resolution. The suffix ``d``, ``m`` and ``s`` stand for
            arc-degrees, arc-minutes, and arc-seconds. It can be ``"01d"``,
            ``"30m"``, ``"20m"``, ``"15m"``, ``"10m"``, ``"06m"``, ``"05m"``,
            ``"04m"``, ``"03m"``, ``"02m"``, ``"01m"``, ``"30s"``, ``"15s"``,
            ``"03s"``, or ``"01s"``.
    
        region : str or list
            The subregion of the grid to load, in the form of a list
            [*xmin*, *xmax*, *ymin*, *ymax*] or a string *xmin/xmax/ymin/ymax*.
            Required for Earth relief grids with resolutions higher than 5
            arc-minutes (i.e., ``"05m"``).
    
        registration : str
            Grid registration type. Either ``"pixel"`` for pixel registration or
            ``"gridline"`` for gridline registration. Default is ``"gridline"``
            for all resolutions except ``"15s"`` which is ``"pixel"`` only.
    
        data_source : str
            Select the source for the Earth relief data.
    
            Available options:
    
            - **igpp** : IGPP Global Earth Relief [Default option]. See
              :gmt-datasets:`earth-relief.html`.
    
            - **synbath** : IGPP Global Earth Relief dataset that uses
              stastical properties of young seafloor to provide more realistic
              relief of young areas with small seamounts.
    
            - **gebco** : GEBCO Global Earth Relief with only observed relief and
              inferred relief via altimetric gravity. See
              :gmt-datasets:`earth-gebco.html`.
    
            - **gebcosi** : GEBCO Global Earth Relief that gives sub-ice (si)
              elevations.
    
        use_srtm : bool
            By default, the land-only SRTM tiles from NASA are used to generate the
            ``"03s"`` and ``"01s"`` grids, and the missing ocean values are filled
            by up-sampling the SRTM15 tiles which have a resolution of 15
            arc-seconds (i.e., ``"15s"``). If True, will only load the original
            land-only SRTM tiles. Only works when ``data_source="igpp"``.
    
        Returns
        -------
        grid : :class:`xarray.DataArray`
            The Earth relief grid. Coordinates are latitude and longitude in
            degrees. Relief is in meters.
    
        Note
        ----
        The :class:`xarray.DataArray` grid doesn't support slice operation, for
        Earth relief data with resolutions of 5 arc-minutes or higher, which are
        stored as smaller tiles.
    
        Examples
        --------
    
        >>> from pygmt.datasets import load_earth_relief
        >>> # load the default grid (gridline-registered 1 arc-degree grid)
        >>> grid = load_earth_relief()
        >>> # load the 30 arc-minutes grid with "gridline" registration
        >>> grid = load_earth_relief(resolution="30m", registration="gridline")
        >>> # load high-resolution (5 arc-minutes) grid for a specific region
        >>> grid = load_earth_relief(
        ...     resolution="05m",
        ...     region=[120, 160, 30, 60],
        ...     registration="gridline",
        ... )
        >>> # load the original 3 arc-seconds land-only SRTM tiles from NASA
        >>> grid = load_earth_relief(
        ...     resolution="03s",
        ...     region=[135, 136, 35, 36],
        ...     registration="gridline",
        ...     use_srtm=True,
        ... )
        """
        # resolutions of original land-only SRTM tiles from NASA
        land_only_srtm_resolutions = ["03s", "01s"]
    
        earth_relief_sources = {
            "igpp": "earth_relief_",
            "gebco": "earth_gebco_",
            "gebcosi": "earth_gebcosi_",
            "synbath": "earth_synbath_",
        }
        if data_source not in earth_relief_sources:
            raise GMTInvalidInput(
                f"Invalid earth relief 'data_source' {data_source}, "
                "valid values are 'igpp', 'gebco', 'gebcosi' and 'synbath'."
            )
        if data_source != "igpp":
            with Session() as lib:
                if Version(lib.info["version"]) < Version("6.4.0"):
        grid : :class:`xarray.DataArray`
            The Earth relief grid. Coordinates are latitude and longitude in
            degrees. Relief is in meters.
    
        Note
        ----
        The :class:`xarray.DataArray` grid doesn't support slice operation, for
        Earth relief data with resolutions of 5 arc-minutes or higher, which are
        stored as smaller tiles.
    
        Examples
        --------
    
        >>> from pygmt.datasets import load_earth_relief
        >>> # load the default grid (gridline-registered 1 arc-degree grid)
        >>> grid = load_earth_relief()
        >>> # load the 30 arc-minutes grid with "gridline" registration
        >>> grid = load_earth_relief(resolution="30m", registration="gridline")
        >>> # load high-resolution (5 arc-minutes) grid for a specific region
        >>> grid = load_earth_relief(
        ...     resolution="05m",
        ...     region=[120, 160, 30, 60],
        ...     registration="gridline",
        ... )
        >>> # load the original 3 arc-seconds land-only SRTM tiles from NASA
        >>> grid = load_earth_relief(
        ...     resolution="03s",
        ...     region=[135, 136, 35, 36],
        ...     registration="gridline",
        ...     use_srtm=True,
        ... )
        """
        # resolutions of original land-only SRTM tiles from NASA
        land_only_srtm_resolutions = ["03s", "01s"]
    
        earth_relief_sources = {
            "igpp": "earth_relief_",
            "gebco": "earth_gebco_",
            "gebcosi": "earth_gebcosi_",
            "synbath": "earth_synbath_",
        }
        if data_source not in earth_relief_sources:
            raise GMTInvalidInput(
                f"Invalid earth relief 'data_source' {data_source}, "
                "valid values are 'igpp', 'gebco', 'gebcosi' and 'synbath'."
            )
        if data_source != "igpp":
            with Session() as lib:
                if Version(lib.info["version"]) < Version("6.4.0"):
>                   raise GMTVersionError(
                        f"The {data_source} option is not available for GMT"
                        " versions before 6.4.0."
                    )
E                   pygmt.exceptions.GMTVersionError: The synbath option is not available for GMT versions before 6.4.0.

../pygmt/datasets/earth_relief.py:140: GMTVersionError

@yvonnefroehlich yvonnefroehlich mentioned this pull request Dec 28, 2022
65 tasks
@weiji14 weiji14 changed the title Add IPython to GMT Legacy Tests CI environment Skip some doctests in GMT Legacy Tests CI Dec 29, 2022
@weiji14
Copy link
Member Author

weiji14 commented Dec 29, 2022

Thinking about using doctestplus (added in #1790) to skip the failing inline tests on GMT 6.3, instead of installing ipython. That means we're testing GMT 6.3 less comprehensively, but the alternative would be to handle different outputs between GMT 6.3 and GMT 6.4 for certain functions. Thoughts?

@weiji14
Copy link
Member Author

weiji14 commented Dec 29, 2022

It's past midnight for me so I won't work on this until ~8hours later. Feel free to push any changes and/or merge if required. To be honest, we probably don't need this in PyGMT v0.8.0 since it's non user-facing, but will leave it up to you @seisman and @yvonnefroehlich.

@seisman
Copy link
Member

seisman commented Dec 29, 2022

Traceback for the 22 failing tests from GenericMappingTools/pygmt/actions/runs/3796568197/jobs/6456779355#step:11:720. Most should be fixed by #2281, some look like actual differences in functions between GMT 6.3 and 6.4, others are to do with the <IPython.core.display.Image object> output.

Actually, most of the failing inline tests are due to the changes of default registration returned by load_earth_relief (i.e., #1929).

Take the grd2xyz inline example as an example.

Here is the diff result:

_____________________ [doctest] pygmt.src.grd2xyz.grd2xyz ______________________
247 -------
248 >>> import pygmt
249 >>> # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
250 >>> # and a y-range of 15 to 25
251 >>> grid = pygmt.datasets.load_earth_relief(
252 ...     resolution="30m", region=[10, 30, 15, 25]
253 ... )
254 >>> # Create a pandas DataFrame with the xyz data from an input grid
255 >>> xyz_dataframe = pygmt.grd2xyz(grid=grid, output_type="pandas")
256 >>> xyz_dataframe.head(n=2)
Differences (unified diff with -expected +actual):
    @@ -1,3 +1,3 @@
    -     lon    lat  elevation
    -0  10.25  24.75      903.5
    -1  10.75  24.75      820.0
    +    lon   lat  elevation
    +0  10.0  25.0      863.0
    +1  10.5  25.0      985.5

This inline example was added in PR #1713 on Jan 29, 2022. At that time, we were still using GMT 6.3.0, so the default grid registration is "pixel" (c.f. #1929) and the output of the inline example was correct.

After we bumped to GMT 6.4, the default grid registration changed to "gridline", so the output of the inline example is outdated and should be updated.

@seisman
Copy link
Member

seisman commented Dec 29, 2022

Here is the output for different grid registrations:

In [7]: import pygmt
   ...: # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
   ...: # and a y-range of 15 to 25
   ...: grid = pygmt.datasets.load_earth_relief(
   ...:     resolution="30m", region=[10, 30, 15, 25], registration="pixel"
   ...: )
   ...: # Create a pandas DataFrame with the xyz data from an input grid
   ...: xyz_dataframe = pygmt.grd2xyz(grid=grid, output_type="pandas")
   ...: xyz_dataframe.head(n=2)
Out[7]: 
     lon    lat  elevation
0  10.25  24.75      903.5
1  10.75  24.75      820.0

In [8]: import pygmt
   ...: # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
   ...: # and a y-range of 15 to 25
   ...: grid = pygmt.datasets.load_earth_relief(
   ...:     resolution="30m", region=[10, 30, 15, 25], registration="gridline"
   ...: )
   ...: # Create a pandas DataFrame with the xyz data from an input grid
   ...: xyz_dataframe = pygmt.grd2xyz(grid=grid, output_type="pandas")
   ...: xyz_dataframe.head(n=2)
Out[8]: 
    lon   lat  elevation
0  10.0  25.0      863.0
1  10.5  25.0      985.5

In [9]: import pygmt
   ...: # Load a grid of @earth_relief_30m data, with an x-range of 10 to 30,
   ...: # and a y-range of 15 to 25
   ...: grid = pygmt.datasets.load_earth_relief(
   ...:     resolution="30m", region=[10, 30, 15, 25]
   ...: )
   ...: # Create a pandas DataFrame with the xyz data from an input grid
   ...: xyz_dataframe = pygmt.grd2xyz(grid=grid, output_type="pandas")
   ...: xyz_dataframe.head(n=2)
Out[9]: 
    lon   lat  elevation
0  10.0  25.0      863.0
1  10.5  25.0      985.5

@seisman
Copy link
Member

seisman commented Dec 29, 2022

I think we should still run the inline doctests because these inline doctests can help us tracking if there are any upstream changes in GMT 6.3/6.4. Commit a5fbe5a reverts the change from doctest-modules to doctest-plus.

After #2284 is merged, we should only see the 5 failures due to the missing IPython, which can be fixed later.

So I'm changing the milestone to 0.9.0.

@seisman seisman modified the milestones: 0.8.0, 0.9.0 Dec 29, 2022
seisman and others added 4 commits December 29, 2022 17:52
To fix errors like `pygmt.exceptions.GMTError: Notebook display is selected, but IPython is not available. Make sure you have IPython installed, or run the script in a Jupyter notebook`.
@weiji14 weiji14 changed the title Skip some doctests in GMT Legacy Tests CI Add IPython to GMT Legacy Tests CI environment Dec 30, 2022
@weiji14 weiji14 marked this pull request as ready for review December 30, 2022 13:50
@weiji14
Copy link
Member Author

weiji14 commented Dec 30, 2022

After #2284 is merged, we should only see the 5 failures due to the missing IPython, which can be fixed later.

Ok, I've re-added ipython in 5e170ac, but the 5 doctests failed with a new error:

206 >>> fig.show()
Expected nothing
Got:
    <IPython.core.display.Image object>

So I've added the <IPython.core.display.Image object> string in commit 2901e36 to fix this. As it turns out, this was a problem for both make test_no_images used in GMT Legacy Tests and make fulltest used in the regular full Tests (with docstrings) ran on Wednesday.

However, the make fulltest run on Wednesday added in #1833 doesn't actually run the full tests 😅 I think there might be a problem with the if-statement here:

# Run full tests including doctests on Wednesday
- name: Run full tests
if: github.event_name == 'schedule' && github.event.schedule == '0 0 * * 3'
run: make fulltest PYTEST_EXTRA="-r P"

Let me see if I can find the correct syntax. The github.event.schedule == '0 0 * * 3' equality might be too strict.

Hopefully this is the correct syntax/logic.
@seisman
Copy link
Member

seisman commented Dec 30, 2022

Do you think we should split this PR into two or three smaller PRs?

@weiji14
Copy link
Member Author

weiji14 commented Dec 30, 2022

Do you think we should split this PR into two or three smaller PRs?

Let's do two, I can cherry-pick out the patches to .github/workflows/ci_tests.yaml.

Edit: done in #2288.

@seisman seisman merged commit 198ebb9 into main Dec 31, 2022
@seisman seisman deleted the ci/tests_legacy_ipython branch December 31, 2022 01:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Boring but important stuff for the core devs skip-changelog Skip adding Pull Request to changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants