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

Use Python 3.10 in Continuous Integration tests #1577

Merged
merged 28 commits into from
Dec 27, 2021
Merged

Use Python 3.10 in Continuous Integration tests #1577

merged 28 commits into from
Dec 27, 2021

Conversation

weiji14
Copy link
Member

@weiji14 weiji14 commented Oct 8, 2021

Description of proposed changes

Python 3.10 has been released on 7 October 2021, changelog is at https://docs.python.org/3.10/whatsnew/3.10.html. See previous PR for Python 3.9 at #689. This PR is part 2/2 for adding Python 3.10 support, see also the sister PR at #1591.

Note: Updating only the "GMT Dev Tests" GitHub Actions continuous integration workflows that used Python 3.9 to use Python 3.10 now.

Reminder: Set Python 3.10 Github Actions CI as a required check. Will do this once Python 3.10 gets more adoption across the Python ecosystem.

Fixes #

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 adding new functionality, add an example to docstrings or tutorials.

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

Python 3.10 has been released on 7 October 2021, see changelog
at https://docs.python.org/3.10/whatsnew/3.10.html. Updating all
the GitHub Actions continuous integration workflows that used
Python 3.9 to use Python 3.10 now. Also updated setup.py to
include Python 3.10 classifier.
@weiji14 weiji14 added the maintenance Boring but important stuff for the core devs label Oct 8, 2021
@weiji14 weiji14 added this to the 0.5.0 milestone Oct 8, 2021
@weiji14 weiji14 self-assigned this Oct 8, 2021
Copy link
Member Author

@weiji14 weiji14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup mamba step is erroring at https://github.com/GenericMappingTools/pygmt/runs/3833784779?check_suite_focus=true#step:4:795 with package python-3.10.0-h62f1059_0_cpython requires pip, but none of the providers can be installed, which is weird because pip on conda-forge is noarch so it should be installable. Will try again in the coming days.

setup.py Outdated Show resolved Hide resolved
@weiji14 weiji14 mentioned this pull request Oct 8, 2021
35 tasks
@weiji14 weiji14 marked this pull request as ready for review October 12, 2021 21:10
@weiji14
Copy link
Member Author

weiji14 commented Oct 12, 2021

Ok, I've changed the CI scripts to only install Python 3.10 on the "GMT Dev Tests" workflow because there isn't a Python 3.10 miniconda/mambaforge installer yet (the reason for why things didn't work as mentioned in #1577 (review)).

The next problem is that dvc=2.7.4 on conda-forge isn't installable with Python 3.10 yet 😅, hence the error - package dvc-2.3.0-py36h5fab9bb_0 requires python_abi 3.6.* *_cp36m, but none of the providers can be installed at https://github.com/GenericMappingTools/pygmt/runs/3875604794?check_suite_focus=true#step:7:45. So might need dvc>2.8 which does have Python 3.10 support to be released on conda-forge, wait for conda-forge/dvc-feedstock#241 (edit: done ✔️). Plus we'll need to unpin dvc for PyGMT (wait for #1559, edit: done ✔️).

Edit: Also need to wait for Python 3.10 migration on conda-forge (see conda-forge/conda-forge-pinning-feedstock#2008), because of package python-3.10.0-h1248fe1_0_cpython requires pip, but none of the providers can be installed, see related issue at pydata/xarray#5844 (comment).

Note that PyGMT should technically support Python 3.10 already since we've moved to noarch builds (conda-forge/pygmt-feedstock#13), so this Pull Request is just about making sure that our Continuous Integration tests pass on Python 3.10.

Workaround missing Python 3.10 packages for dvc
on conda-forge.
@weiji14
Copy link
Member Author

weiji14 commented Oct 16, 2021

/test-gmt-dev

Edit: there is something wrong with the /test-gmt-dev command implemented in #831, it is using the commit on the main branch rather than this PR's branch, see https://github.com/GenericMappingTools/pygmt/runs/3913143857?check_suite_focus=true#step:15:14 where Python 3.9 is still being installed, and the commit title is 'Unpin dvc version from 2.3.0' which is from the main branch.

@weiji14 weiji14 marked this pull request as draft October 16, 2021 08:08
@weiji14 weiji14 marked this pull request as ready for review October 16, 2021 08:16
@weiji14 weiji14 marked this pull request as draft October 16, 2021 08:51
@maxrjones
Copy link
Member

Edit: there is something wrong with the /test-gmt-dev command implemented in #831, it is using the commit on the main branch rather than this PR's branch, see https://github.com/GenericMappingTools/pygmt/runs/3913143857?check_suite_focus=true#step:15:14 where Python 3.9 is still being installed, and the commit title is 'Unpin dvc version from 2.3.0' which is from the main branch.

I think ref: ${{ github.event.client_payload.pull_request.head.ref }} may be v1 syntax and need to be more similar toref: ${{ github.event.pull_request.head.sha }}, based on https://github.com/actions/checkout#checkout-pull-request-head-commit-instead-of-merge-commit and https://frontside.com/blog/2020-05-26-github-actions-pull_request/#how-does-pull_request-affect-actionscheckout.

@weiji14
Copy link
Member Author

weiji14 commented Oct 21, 2021

/test-gmt-dev

Edit: I thought 95e318c worked, but running /test-gmt-dev still uses Python 3.9 instead of Python 3.10 somehow (see https://github.com/GenericMappingTools/pygmt/runs/3958847986?check_suite_focus=true#step:15:14). Need to investigate more on what is happening with ci_test_dev.yaml.

@weiji14 weiji14 marked this pull request as ready for review October 21, 2021 02:18
@weiji14 weiji14 marked this pull request as draft October 21, 2021 02:26
@weiji14
Copy link
Member Author

weiji14 commented Nov 5, 2021

One more step closer 😆 Have managed to resolve the aiohttp problem mentioned in #1577 (comment) by installing the pre-built aiohttp=3.8.0 binary package with commit 20854ee. Conda/pip installs work, and GMT can be compiled from source, but...

There are some unit tests in test_geopandas.py that break because fiona (a dependency of geopandas that handles I/O) doesn't have pre-compiled wheels for Python 3.10, and is giving an undefined symbol: _PyGen_Send error, see Toblerity/Fiona#1043. Log errors from https://github.com/GenericMappingTools/pygmt/runs/4113539173?check_suite_focus=true#step:15:577 pasted below:

_______________________ test_geopandas_info_geodataframe _______________________

gdf =                                                        geometry
multipolygon  MULTIPOLYGON (((0.00000 0.00000, 20.0000...      POLYGON ((20.00000 10.00000, 23.00000 10.00000...
linestring    LINESTRING (20.00000 15.00000, 30.00000 15.00000)

    def test_geopandas_info_geodataframe(gdf):
        """
        Check that info can return the bounding box region from a
        geopandas.GeoDataFrame.
        """
>       output = info(data=gdf, per_column=True)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/info.py:87: in info
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: in tempfile_from_geojson
    geojson.to_file(**ogrgmt_kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/geodataframe.py:1114: in to_file
    _to_file(self, filename, driver, schema, index, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:355: in _to_file
    _check_fiona("'to_file' method")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = "'to_file' method"

    def _check_fiona(func):
        if fiona is None:
>           raise ImportError(
                f"the {func} requires the 'fiona' package, but it is not installed or does "
                f"not import correctly.\nImporting fiona resulted in: {fiona_import_error}"
            )
E           ImportError: the 'to_file' method requires the 'fiona' package, but it is not installed or does not import correctly.
E           Importing fiona resulted in: /usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/ogrext.cpython-310-x86_64-linux-gnu.so: undefined symbol: _PyGen_Send

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:80: ImportError
______________ test_geopandas_info_shapely[multipolygon-desired0] ______________

geojson = <shapely.geometry.multipolygon.MultiPolygon object at 0x7f605c927d90>

    @contextmanager
    def tempfile_from_geojson(geojson):
        """
        Saves any geo-like Python object which implements ``__geo_interface__``
        (e.g. a geopandas.GeoDataFrame or shapely.geometry) to a temporary OGR_GMT
        text file.
    
        Parameters
        ----------
        geojson : geopandas.GeoDataFrame
            A geopandas GeoDataFrame, or any geo-like Python object which
            implements __geo_interface__, i.e. a GeoJSON.
    
        Yields
        ------
        tmpfilename : str
            A temporary OGR_GMT format file holding the geographical data.
            E.g. '1a2b3c4d5e6.gmt'.
        """
        with GMTTempFile(suffix=".gmt") as tmpfile:
            os.remove(tmpfile.name)  # ensure file is deleted first
            ogrgmt_kwargs = dict(filename=tmpfile.name, driver="OGR_GMT", mode="w")
            try:
                # Using geopandas.to_file to directly export to OGR_GMT format
>               geojson.to_file(**ogrgmt_kwargs)
E               AttributeError: 'MultiPolygon' object has no attribute 'to_file'

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: AttributeError

During handling of the above exception, another exception occurred:

gdf =                                                        geometry
multipolygon  MULTIPOLYGON (((0.00000 0.00000, 20.0000...      POLYGON ((20.00000 10.00000, 23.00000 10.00000...
linestring    LINESTRING (20.00000 15.00000, 30.00000 15.00000)
geomtype = 'multipolygon', desired = [0.0, 35.0, 0.0, 20.0]

    @pytest.mark.parametrize(
        "geomtype,desired",
        [
            ("multipolygon", [0.0, 35.0, 0.0, 20.0]),
            ("polygon", [20.0, 23.0, 10.0, 14.0]),
            ("linestring", [20.0, 30.0, 15.0, 15.0]),
        ],
    )
    def test_geopandas_info_shapely(gdf, geomtype, desired):
        """
        Check that info can return the bounding box region from a shapely.geometry
        object that has a __geo_interface__ property.
        """
        geom = gdf.loc[geomtype].geometry
>       output = info(data=geom, per_column=True)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:65: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/info.py:87: in info
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:140: in tempfile_from_geojson
    import fiona
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    # -*- coding: utf-8 -*-
    
    """
    Fiona is OGR's neat, nimble API.
    
    Fiona provides a minimal, uncomplicated Python interface to the open
    source GIS community's most trusted geodata access library and
    integrates readily with other Python GIS packages such as pyproj, Rtree
    and Shapely.
    
    How minimal? Fiona can read features as mappings from shapefiles or
    other GIS vector formats and write mappings as features to files using
    the same formats. That's all. There aren't any feature or geometry
    classes. Features and their geometries are just data.
    
    A Fiona feature is a Python mapping inspired by the GeoJSON format. It
    has `id`, 'geometry`, and `properties` keys. The value of `id` is
    a string identifier unique within the feature's parent collection. The
    `geometry` is another mapping with `type` and `coordinates` keys. The
    `properties` of a feature is another mapping corresponding to its
    attribute table. For example:
    
      {'id': '1',
       'geometry': {'type': 'Point', 'coordinates': (0.0, 0.0)},
       'properties': {'label': u'Null Island'} }
    
    is a Fiona feature with a point geometry and one property.
    
    Features are read and written using objects returned by the
    ``collection`` function. These ``Collection`` objects are a lot like
    Python ``file`` objects. A ``Collection`` opened in reading mode serves
    as an iterator over features. One opened in a writing mode provides
    a ``write`` method.
    
    Usage
    -----
    
    Here's an example of reading a select few polygon features from
    a shapefile and for each, picking off the first vertex of the exterior
    ring of the polygon and using that as the point geometry for a new
    feature writing to a "points.shp" file.
    
      >>> import fiona
      >>> with fiona.open('docs/data/test_uk.shp', 'r') as inp:
      ...     output_schema = inp.schema.copy()
      ...     output_schema['geometry'] = 'Point'
      ...     with collection(
      ...             "points.shp", "w",
      ...             crs=inp.crs,
      ...             driver="ESRI Shapefile",
      ...             schema=output_schema
      ...             ) as out:
      ...         for f in inp.filter(
      ...                 bbox=(-5.0, 55.0, 0.0, 60.0)
      ...                 ):
      ...             value = f['geometry']['coordinates'][0][0]
      ...             f['geometry'] = {
      ...                 'type': 'Point', 'coordinates': value}
      ...             out.write(f)
    
    Because Fiona collections are context managers, they are closed and (in
    writing modes) flush contents to disk when their ``with`` blocks end.
    """
    
    from contextlib import contextmanager
    import logging
    import os
    import sys
    import warnings
    import platform
    from six import string_types
    
    try:
        from pathlib import Path
    except ImportError:  # pragma: no cover
        class Path:
            pass
    
    # TODO: remove this? Or at least move it, flake8 complains.
    if sys.platform == "win32":
        libdir = os.path.join(os.path.dirname(__file__), ".libs")
        os.environ["PATH"] = os.environ["PATH"] + ";" + libdir
    
    import fiona._loading
>   with fiona._loading.add_gdal_dll_directories():
E   AttributeError: partially initialized module 'fiona' has no attribute '_loading' (most likely due to a circular import)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/__init__.py:85: AttributeError
________________ test_geopandas_info_shapely[polygon-desired1] _________________

geojson = <shapely.geometry.polygon.Polygon object at 0x7f605c927730>

    @contextmanager
    def tempfile_from_geojson(geojson):
        """
        Saves any geo-like Python object which implements ``__geo_interface__``
        (e.g. a geopandas.GeoDataFrame or shapely.geometry) to a temporary OGR_GMT
        text file.
    
        Parameters
        ----------
        geojson : geopandas.GeoDataFrame
            A geopandas GeoDataFrame, or any geo-like Python object which
            implements __geo_interface__, i.e. a GeoJSON.
    
        Yields
        ------
        tmpfilename : str
            A temporary OGR_GMT format file holding the geographical data.
            E.g. '1a2b3c4d5e6.gmt'.
        """
        with GMTTempFile(suffix=".gmt") as tmpfile:
            os.remove(tmpfile.name)  # ensure file is deleted first
            ogrgmt_kwargs = dict(filename=tmpfile.name, driver="OGR_GMT", mode="w")
            try:
                # Using geopandas.to_file to directly export to OGR_GMT format
>               geojson.to_file(**ogrgmt_kwargs)
E               AttributeError: 'Polygon' object has no attribute 'to_file'

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: AttributeError

During handling of the above exception, another exception occurred:

gdf =                                                        geometry
multipolygon  MULTIPOLYGON (((0.00000 0.00000, 20.0000...      POLYGON ((20.00000 10.00000, 23.00000 10.00000...
linestring    LINESTRING (20.00000 15.00000, 30.00000 15.00000)
geomtype = 'polygon', desired = [20.0, 23.0, 10.0, 14.0]

    @pytest.mark.parametrize(
        "geomtype,desired",
        [
            ("multipolygon", [0.0, 35.0, 0.0, 20.0]),
            ("polygon", [20.0, 23.0, 10.0, 14.0]),
            ("linestring", [20.0, 30.0, 15.0, 15.0]),
        ],
    )
    def test_geopandas_info_shapely(gdf, geomtype, desired):
        """
        Check that info can return the bounding box region from a shapely.geometry
        object that has a __geo_interface__ property.
        """
        geom = gdf.loc[geomtype].geometry
>       output = info(data=geom, per_column=True)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:65: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/info.py:87: in info
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:140: in tempfile_from_geojson
    import fiona
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    # -*- coding: utf-8 -*-
    
    """
    Fiona is OGR's neat, nimble API.
    
    Fiona provides a minimal, uncomplicated Python interface to the open
    source GIS community's most trusted geodata access library and
    integrates readily with other Python GIS packages such as pyproj, Rtree
    and Shapely.
    
    How minimal? Fiona can read features as mappings from shapefiles or
    other GIS vector formats and write mappings as features to files using
    the same formats. That's all. There aren't any feature or geometry
    classes. Features and their geometries are just data.
    
    A Fiona feature is a Python mapping inspired by the GeoJSON format. It
    has `id`, 'geometry`, and `properties` keys. The value of `id` is
    a string identifier unique within the feature's parent collection. The
    `geometry` is another mapping with `type` and `coordinates` keys. The
    `properties` of a feature is another mapping corresponding to its
    attribute table. For example:
    
      {'id': '1',
       'geometry': {'type': 'Point', 'coordinates': (0.0, 0.0)},
       'properties': {'label': u'Null Island'} }
    
    is a Fiona feature with a point geometry and one property.
    
    Features are read and written using objects returned by the
    ``collection`` function. These ``Collection`` objects are a lot like
    Python ``file`` objects. A ``Collection`` opened in reading mode serves
    as an iterator over features. One opened in a writing mode provides
    a ``write`` method.
    
    Usage
    -----
    
    Here's an example of reading a select few polygon features from
    a shapefile and for each, picking off the first vertex of the exterior
    ring of the polygon and using that as the point geometry for a new
    feature writing to a "points.shp" file.
    
      >>> import fiona
      >>> with fiona.open('docs/data/test_uk.shp', 'r') as inp:
      ...     output_schema = inp.schema.copy()
      ...     output_schema['geometry'] = 'Point'
      ...     with collection(
      ...             "points.shp", "w",
      ...             crs=inp.crs,
      ...             driver="ESRI Shapefile",
      ...             schema=output_schema
      ...             ) as out:
      ...         for f in inp.filter(
      ...                 bbox=(-5.0, 55.0, 0.0, 60.0)
      ...                 ):
      ...             value = f['geometry']['coordinates'][0][0]
      ...             f['geometry'] = {
      ...                 'type': 'Point', 'coordinates': value}
      ...             out.write(f)
    
    Because Fiona collections are context managers, they are closed and (in
    writing modes) flush contents to disk when their ``with`` blocks end.
    """
    
    from contextlib import contextmanager
    import logging
    import os
    import sys
    import warnings
    import platform
    from six import string_types
    
    try:
        from pathlib import Path
    except ImportError:  # pragma: no cover
        class Path:
            pass
    
    # TODO: remove this? Or at least move it, flake8 complains.
    if sys.platform == "win32":
        libdir = os.path.join(os.path.dirname(__file__), ".libs")
        os.environ["PATH"] = os.environ["PATH"] + ";" + libdir
    
    import fiona._loading
>   with fiona._loading.add_gdal_dll_directories():
E   AttributeError: partially initialized module 'fiona' has no attribute '_loading' (most likely due to a circular import)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/__init__.py:85: AttributeError
_______________ test_geopandas_info_shapely[linestring-desired2] _______________

geojson = <shapely.geometry.linestring.LineString object at 0x7f605c926e60>

    @contextmanager
    def tempfile_from_geojson(geojson):
        """
        Saves any geo-like Python object which implements ``__geo_interface__``
        (e.g. a geopandas.GeoDataFrame or shapely.geometry) to a temporary OGR_GMT
        text file.
    
        Parameters
        ----------
        geojson : geopandas.GeoDataFrame
            A geopandas GeoDataFrame, or any geo-like Python object which
            implements __geo_interface__, i.e. a GeoJSON.
    
        Yields
        ------
        tmpfilename : str
            A temporary OGR_GMT format file holding the geographical data.
            E.g. '1a2b3c4d5e6.gmt'.
        """
        with GMTTempFile(suffix=".gmt") as tmpfile:
            os.remove(tmpfile.name)  # ensure file is deleted first
            ogrgmt_kwargs = dict(filename=tmpfile.name, driver="OGR_GMT", mode="w")
            try:
                # Using geopandas.to_file to directly export to OGR_GMT format
>               geojson.to_file(**ogrgmt_kwargs)
E               AttributeError: 'LineString' object has no attribute 'to_file'

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: AttributeError

During handling of the above exception, another exception occurred:

gdf =                                                        geometry
multipolygon  MULTIPOLYGON (((0.00000 0.00000, 20.0000...      POLYGON ((20.00000 10.00000, 23.00000 10.00000...
linestring    LINESTRING (20.00000 15.00000, 30.00000 15.00000)
geomtype = 'linestring', desired = [20.0, 30.0, 15.0, 15.0]

    @pytest.mark.parametrize(
        "geomtype,desired",
        [
            ("multipolygon", [0.0, 35.0, 0.0, 20.0]),
            ("polygon", [20.0, 23.0, 10.0, 14.0]),
            ("linestring", [20.0, 30.0, 15.0, 15.0]),
        ],
    )
    def test_geopandas_info_shapely(gdf, geomtype, desired):
        """
        Check that info can return the bounding box region from a shapely.geometry
        object that has a __geo_interface__ property.
        """
        geom = gdf.loc[geomtype].geometry
>       output = info(data=geom, per_column=True)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:65: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/info.py:87: in info
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:140: in tempfile_from_geojson
    import fiona
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    # -*- coding: utf-8 -*-
    
    """
    Fiona is OGR's neat, nimble API.
    
    Fiona provides a minimal, uncomplicated Python interface to the open
    source GIS community's most trusted geodata access library and
    integrates readily with other Python GIS packages such as pyproj, Rtree
    and Shapely.
    
    How minimal? Fiona can read features as mappings from shapefiles or
    other GIS vector formats and write mappings as features to files using
    the same formats. That's all. There aren't any feature or geometry
    classes. Features and their geometries are just data.
    
    A Fiona feature is a Python mapping inspired by the GeoJSON format. It
    has `id`, 'geometry`, and `properties` keys. The value of `id` is
    a string identifier unique within the feature's parent collection. The
    `geometry` is another mapping with `type` and `coordinates` keys. The
    `properties` of a feature is another mapping corresponding to its
    attribute table. For example:
    
      {'id': '1',
       'geometry': {'type': 'Point', 'coordinates': (0.0, 0.0)},
       'properties': {'label': u'Null Island'} }
    
    is a Fiona feature with a point geometry and one property.
    
    Features are read and written using objects returned by the
    ``collection`` function. These ``Collection`` objects are a lot like
    Python ``file`` objects. A ``Collection`` opened in reading mode serves
    as an iterator over features. One opened in a writing mode provides
    a ``write`` method.
    
    Usage
    -----
    
    Here's an example of reading a select few polygon features from
    a shapefile and for each, picking off the first vertex of the exterior
    ring of the polygon and using that as the point geometry for a new
    feature writing to a "points.shp" file.
    
      >>> import fiona
      >>> with fiona.open('docs/data/test_uk.shp', 'r') as inp:
      ...     output_schema = inp.schema.copy()
      ...     output_schema['geometry'] = 'Point'
      ...     with collection(
      ...             "points.shp", "w",
      ...             crs=inp.crs,
      ...             driver="ESRI Shapefile",
      ...             schema=output_schema
      ...             ) as out:
      ...         for f in inp.filter(
      ...                 bbox=(-5.0, 55.0, 0.0, 60.0)
      ...                 ):
      ...             value = f['geometry']['coordinates'][0][0]
      ...             f['geometry'] = {
      ...                 'type': 'Point', 'coordinates': value}
      ...             out.write(f)
    
    Because Fiona collections are context managers, they are closed and (in
    writing modes) flush contents to disk when their ``with`` blocks end.
    """
    
    from contextlib import contextmanager
    import logging
    import os
    import sys
    import warnings
    import platform
    from six import string_types
    
    try:
        from pathlib import Path
    except ImportError:  # pragma: no cover
        class Path:
            pass
    
    # TODO: remove this? Or at least move it, flake8 complains.
    if sys.platform == "win32":
        libdir = os.path.join(os.path.dirname(__file__), ".libs")
        os.environ["PATH"] = os.environ["PATH"] + ";" + libdir
    
    import fiona._loading
>   with fiona._loading.add_gdal_dll_directories():
E   AttributeError: partially initialized module 'fiona' has no attribute '_loading' (most likely due to a circular import)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/__init__.py:85: AttributeError
______________________ test_geopandas_plot_default_square ______________________

    @pytest.mark.mpl_image_compare
    def test_geopandas_plot_default_square():
        """
        Check the default behavior of plotting a geopandas DataFrame with Point
        geometry in 2d.
        """
        point = shapely.geometry.Point(1, 2)
        gdf = gpd.GeoDataFrame(geometry=[point])
        fig = Figure()
>       fig.plot(data=gdf, region=[0, 2, 1, 3], projection="X2c", frame=True)

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:78: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:873: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/plot.py:273: in plot
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: in tempfile_from_geojson
    geojson.to_file(**ogrgmt_kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/geodataframe.py:1114: in to_file
    _to_file(self, filename, driver, schema, index, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:355: in _to_file
    _check_fiona("'to_file' method")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = "'to_file' method"

    def _check_fiona(func):
        if fiona is None:
>           raise ImportError(
                f"the {func} requires the 'fiona' package, but it is not installed or does "
                f"not import correctly.\nImporting fiona resulted in: {fiona_import_error}"
            )
E           ImportError: the 'to_file' method requires the 'fiona' package, but it is not installed or does not import correctly.
E           Importing fiona resulted in: /usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/ogrext.cpython-310-x86_64-linux-gnu.so: undefined symbol: _PyGen_Send

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:80: ImportError
______________________ test_geopandas_plot3d_default_cube ______________________

    @pytest.mark.mpl_image_compare
    def test_geopandas_plot3d_default_cube():
        """
        Check the default behavior of plotting a geopandas DataFrame with
        MultiPoint geometry in 3d.
        """
        multipoint = shapely.geometry.MultiPoint([(0.5, 0.5, 0.5), (1.5, 1.5, 1.5)])
        gdf = gpd.GeoDataFrame(geometry=[multipoint])
        fig = Figure()
>       fig.plot3d(
            data=gdf,
            perspective=[315, 25],
            region=[0, 2, 0, 2, 0, 2],
            projection="X2c",
            frame=["WsNeZ1", "xag", "yag", "zag"],
            zscale=1.5,
        )

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:873: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/plot3d.py:249: in plot3d
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: in tempfile_from_geojson
    geojson.to_file(**ogrgmt_kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/geodataframe.py:1114: in to_file
    _to_file(self, filename, driver, schema, index, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:355: in _to_file
    _check_fiona("'to_file' method")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = "'to_file' method"

    def _check_fiona(func):
        if fiona is None:
>           raise ImportError(
                f"the {func} requires the 'fiona' package, but it is not installed or does "
                f"not import correctly.\nImporting fiona resulted in: {fiona_import_error}"
            )
E           ImportError: the 'to_file' method requires the 'fiona' package, but it is not installed or does not import correctly.
E           Importing fiona resulted in: /usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/ogrext.cpython-310-x86_64-linux-gnu.so: undefined symbol: _PyGen_Send

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:80: ImportError
____________________ test_geopandas_plot_non_default_circle ____________________

    @pytest.mark.mpl_image_compare
    def test_geopandas_plot_non_default_circle():
        """
        Check the default behavior of plotting geopandas DataFrame with Point
        geometry in 2d.
        """
        point = shapely.geometry.Point(1, 2)
        gdf = gpd.GeoDataFrame(geometry=[point])
        fig = Figure()
>       fig.plot(data=gdf, region=[0, 2, 1, 3], projection="X2c", frame=True, style="c0.2c")

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:111: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:873: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/plot.py:273: in plot
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: in tempfile_from_geojson
    geojson.to_file(**ogrgmt_kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/geodataframe.py:1114: in to_file
    _to_file(self, filename, driver, schema, index, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:355: in _to_file
    _check_fiona("'to_file' method")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = "'to_file' method"

    def _check_fiona(func):
        if fiona is None:
>           raise ImportError(
                f"the {func} requires the 'fiona' package, but it is not installed or does "
                f"not import correctly.\nImporting fiona resulted in: {fiona_import_error}"
            )
E           ImportError: the 'to_file' method requires the 'fiona' package, but it is not installed or does not import correctly.
E           Importing fiona resulted in: /usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/ogrext.cpython-310-x86_64-linux-gnu.so: undefined symbol: _PyGen_Send

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:80: ImportError
___________________ test_geopandas_plot3d_non_default_circle ___________________

    @pytest.mark.mpl_image_compare
    def test_geopandas_plot3d_non_default_circle():
        """
        Check the default behavior of plotting geopandas DataFrame with MultiPoint
        geometry in 3d.
        """
        multipoint = shapely.geometry.MultiPoint([(0.5, 0.5, 0.5), (1.5, 1.5, 1.5)])
        gdf = gpd.GeoDataFrame(geometry=[multipoint])
        fig = Figure()
>       fig.plot3d(
            data=gdf,
            perspective=[315, 25],
            region=[0, 2, 0, 2, 0, 2],
            projection="X2c",
            frame=["WsNeZ1", "xag", "yag", "zag"],
            zscale=1.5,
            style="c0.2c",
        )

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/tests/test_geopandas.py:124: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:805: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:873: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:586: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/decorators.py:726: in new_module
    return module_func(*args, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/src/plot3d.py:249: in plot3d
    with file_context as fname:
/usr/share/miniconda3/envs/pygmt/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/pygmt/helpers/tempfile.py:134: in tempfile_from_geojson
    geojson.to_file(**ogrgmt_kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/geodataframe.py:1114: in to_file
    _to_file(self, filename, driver, schema, index, **kwargs)
/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:355: in _to_file
    _check_fiona("'to_file' method")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

func = "'to_file' method"

    def _check_fiona(func):
        if fiona is None:
>           raise ImportError(
                f"the {func} requires the 'fiona' package, but it is not installed or does "
                f"not import correctly.\nImporting fiona resulted in: {fiona_import_error}"
            )
E           ImportError: the 'to_file' method requires the 'fiona' package, but it is not installed or does not import correctly.
E           Importing fiona resulted in: /usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/ogrext.cpython-310-x86_64-linux-gnu.so: undefined symbol: _PyGen_Send

/usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/geopandas/io/file.py:80: ImportError

@weiji14
Copy link
Member Author

weiji14 commented Dec 4, 2021

Another month, another update~ The fiona install problem mentioned in #1577 (comment) has been fixed in 0604c95 (by installing geopandas from conda-forge, which pulls in fiona that has been compiled for Python 3.10). GMT Dev Tests using Python 3.10 now works 🎉! The 6 test failures in https://github.com/GenericMappingTools/pygmt/runs/4414366572?check_suite_focus=true#step:15:576 are unrelated, just due to breaking changes in GMT 6.3.

Question: Do we want to get this pull request on testing Python 3.10 in CI merged now-ish, or wait until the GMT 6.3 bump goes through?

Edit: Apparently fiona can't be installed on WIndows Python 3.10 yet... So might need to wait for #1645. Edit 2: Python 3.10 now works across Linux/macOS/Windows on GMT Dev Tests CI 🎉

tomli
mamba install python=${{ matrix.python-version }} \
ninja cmake libblas libcblas liblapack fftw libgdal \
geopandas ghostscript libnetcdf hdf5 zlib curl pcre make
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should install geopandas using pip instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally yes, and I did try it (see 69d4e67), but pip install geopandas doesn't work on Python 3.10 because the fiona dependency doesn't have Python 3.10 wheels yet and the install is not functional:

E           ImportError: the 'to_file' method requires the 'fiona' package, but it is not installed or does not import correctly.
E           Importing fiona resulted in: /usr/share/miniconda3/envs/pygmt/lib/python3.10/site-packages/fiona/ogrext.cpython-310-x86_64-linux-gnu.so: undefined symbol: _PyGen_Send

So I had to revert back to using conda install geopandas in 0604c95.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, Python 3.10 support in fiona is being worked on at Toblerity/Fiona#1049. Seems like the Python 3.10 wheels might take a while to come out, so probably shouldn't wait.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're waiting for the wheels to come out, why shouldn't we wait to upgrade to Python 3.10?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're waiting for the wheels to come out, why shouldn't we wait to upgrade to Python 3.10?

If I'm reading your sentence correctly, no, we don't have to wait for the fiona Python 3.10 wheels to come out. The current state on the main branch is that fiona is installed indirectly via conda install geopandas. @seisman's suggestion was that we use pip install --pre geopandas instead, but that doesn't work because fiona doesn't have Python 3.10 wheels.

Since geopandas/fiona is an optional dependency for PyGMT, I think we can just push ahead with this PR as is (i.e. stick with conda install geopandas), but happy to wait too if there's a good reason to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the new fiona release will take at least another month (Toblerity/Fiona#1053). I think we don't need to wait for it.

@@ -76,7 +76,7 @@ jobs:
uses: conda-incubator/[email protected]
with:
activate-environment: pygmt
python-version: ${{ matrix.python-version }}
# python-version: ${{ matrix.python-version }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any special reason to comment out this line?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup-miniconda action won't work with Python 3.10, because there isn't a miniconda or mambaforge version with Python 3.10 yet (see https://repo.anaconda.com/miniconda/ and https://github.com/conda-forge/miniforge/releases). The Python 3.10 install step happens later below.

@weiji14 weiji14 marked this pull request as ready for review December 20, 2021 07:16
@weiji14 weiji14 requested a review from a team December 21, 2021 07:36
@seisman seisman added the final review call This PR requires final review and approval from a second reviewer label Dec 25, 2021
@weiji14 weiji14 removed the final review call This PR requires final review and approval from a second reviewer label Dec 27, 2021
@weiji14 weiji14 merged commit 90cda7f into main Dec 27, 2021
@weiji14 weiji14 deleted the ci/python-3.10 branch December 27, 2021 21:12
@seisman seisman mentioned this pull request Oct 26, 2022
6 tasks
sixy6e pushed a commit to sixy6e/pygmt that referenced this pull request Dec 21, 2022
…1577)

Updating the "GMT Dev Tests" GitHub Actions continuous integration
workflows that used Python 3.9 to use Python 3.10 now.

* Put quotes around 3.10 so that it doesn't get read as Python 3.1
* Manually install Python 3.10 on ci_tests_dev.yaml
* Use pip to install dvc on ci_tests_dev workflow

Workaround missing Python 3.10 packages for dvc
on conda-forge.

* Install numpy before other deps since it is a build dependency for some
* Prefer older binary pip packages over newer pip packages

Save from having to compile Python 3.10 packages,
and fixes installation issues for some libraries like
`aiohttp` which have outdated pre-release versions.

* Set minimum Python version to 3.8 in README.rst
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants