Repository: geopandas/geopandas
Pull request #2682 (2022-12-21 00:27:21)

BUG: Add name to setup.py for GitHub, re-format text TOML entry
This fixes two things:

1. There is a GitHub bug where the project name is assumed to be in `setup.py` to show dependents in the dependency graph; currently [it is empty](https://github.com/geopandas/geopandas/network/dependents)
2. Re-format the "text" TOML entry to it's own section, as the current form has problems with some packages, e.g. try "tox", and see "toml.decoder.TomlDecodeError: Stuff after closed string. WTF? (line 32 column 1 char 977)". The content of the readme is unchanged.


Patch:
diff --git a/ci/envs/39-pd12-conda-forge.yaml b/ci/envs/39-pd12-conda-forge.yaml
index fc675bf9..73b62ec4 100644
--- a/ci/envs/39-pd12-conda-forge.yaml
+++ b/ci/envs/39-pd12-conda-forge.yaml
@@ -5,6 +5,7 @@ dependencies:
   - python=3.9
   # required
   - pandas=1.2
+  - numpy=1.20 # released 1 month after pandas 1.2
   - shapely
   - fiona
   - pyproj
diff --git a/doc/source/community/contributing.rst b/doc/source/community/contributing.rst
index a17e2790..3e84a09f 100644
--- a/doc/source/community/contributing.rst
+++ b/doc/source/community/contributing.rst
@@ -54,12 +54,12 @@ In particular, when submitting a pull request:
 Seven Steps for Contributing
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-There are seven basic steps to contributing to *GeoPandas*:
+There are seven basic steps to contributing to GeoPandas:
 
-1) Fork the *GeoPandas* git repository
+1) Fork the GeoPandas git repository
 2) Create a development environment
-3) Install *GeoPandas* dependencies
-4) Make a ``development`` build of *GeoPandas*
+3) Install GeoPandas dependencies
+4) Make a ``development`` build of GeoPandas
 5) Make changes to code and add tests
 6) Update the documentation
 7) Submit a Pull Request
@@ -67,10 +67,10 @@ There are seven basic steps to contributing to *GeoPandas*:
 Each of these 7 steps is detailed below.
 
 
-1) Forking the *GeoPandas* repository using Git
+1) Forking the GeoPandas repository using Git
 ------------------------------------------------
 
-To the new user, working with Git is one of the more daunting aspects of contributing to *GeoPandas**.
+To the new user, working with Git is one of the more daunting aspects of contributing to GeoPandas.
 It can very quickly become overwhelming, but sticking to the guidelines below will help keep the process
 straightforward and mostly trouble free.  As always, if you are having difficulties please
 feel free to ask for help.
@@ -107,8 +107,8 @@ want to clone your fork to your machine::
     cd geopandas-yourname
     git remote add upstream git://github.com/geopandas/geopandas.git
 
-This creates the directory `geopandas-yourname` and connects your repository to
-the upstream (main project) *GeoPandas* repository.
+This creates the directory ``geopandas-yourname`` and connects your repository to
+the upstream (main project) GeoPandas repository.
 
 The testing suite will run automatically on GitHub Actions once your pull request is
 submitted. The test suite will also automatically run on your branch so you can
@@ -129,7 +129,7 @@ The above can be simplified to::
 
 This changes your working directory to the shiny-new-feature branch.  Keep any
 changes in this branch specific to one bug or feature so it is clear
-what the branch brings to *GeoPandas*. You can have many shiny-new-features
+what the branch brings to GeoPandas. You can have many shiny-new-features
 and switch in between them using the git checkout command.
 
 To update this branch, you need to retrieve the changes from the main branch::
@@ -147,23 +147,23 @@ after updating.
 
 2) Creating a development environment
 ---------------------------------------
-A development environment is a virtual space where you can keep an independent installation of *GeoPandas*.
+A development environment is a virtual space where you can keep an independent installation of GeoPandas.
 This makes it easy to keep both a stable version of python in one place you use for work, and a development
 version (which you may break while playing with code) in another.
 
-An easy way to create a *GeoPandas* development environment is as follows:
+An easy way to create a GeoPandas development environment is as follows:
 
 - Install either `Anaconda <http://docs.continuum.io/anaconda/>`_ or
   `miniconda <http://conda.pydata.org/miniconda.html>`_
 - Make sure that you have :ref:`cloned the repository <contributing.forking>`
-- ``cd`` to the *geopandas** source directory
+- ``cd`` to the ``geopandas`` source directory
 
 Using the provided environment
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-*GeoPandas* provides an environment which includes the required dependencies for development.
+GeoPandas provides an environment which includes the required dependencies for development.
 The environment file is located in the top level of the repo and is named ``environment-dev.yml``.
-You can create this environment by navigating to the the *GeoPandas* source directory
+You can create this environment by navigating to the the ``geopandas`` source directory
 and running::
 
       conda env create -f environment-dev.yml
@@ -209,8 +209,8 @@ At this point you can easily do a *development* install, as detailed in the next
 3) Installing Dependencies
 --------------------------
 
-To run *GeoPandas* in an development environment, you must first install
-*GeoPandas*'s dependencies. If you used the provided environment in section 2, skip this
+To run GeoPandas in an development environment, you must first install the dependencies of
+GeoPandas. If you used the provided environment in section 2, skip this
 step and continue to section 4. If you created the environment manually, we suggest installing
 dependencies using the following commands (executed after your development environment has been activated)::
 
@@ -223,7 +223,7 @@ This should install all necessary dependencies.
 -----------------------------
 
 Once dependencies are in place, make an in-place build by navigating to the git
-clone of the *GeoPandas* repository and running::
+clone of the GeoPandas repository and running::
 
     python -m pip install -e .
 
@@ -231,7 +231,7 @@ clone of the *GeoPandas* repository and running::
 5) Making changes and writing tests
 -------------------------------------
 
-*GeoPandas* is serious about testing and strongly encourages contributors to embrace
+GeoPandas is serious about testing and strongly encourages contributors to embrace
 `test-driven development (TDD) <http://en.wikipedia.org/wiki/Test-driven_development>`_.
 This development process "relies on the repetition of a very short development cycle:
 first the developer writes an (initially failing) automated test case that defines a desired
@@ -240,10 +240,10 @@ So, before actually writing any code, you should write your tests.  Often the te
 taken from the original GitHub issue.  However, it is always worth considering additional
 use cases and writing corresponding tests.
 
-Adding tests is one of the most common requests after code is pushed to *GeoPandas*.  Therefore,
+Adding tests is one of the most common requests after code is pushed to GeoPandas.  Therefore,
 it is worth getting in the habit of writing tests ahead of time so this is never an issue.
 
-*GeoPandas* uses the `pytest testing system
+GeoPandas uses the `pytest testing system
 <http://doc.pytest.org/en/latest/>`_ and the convenient
 extensions in `numpy.testing
 <http://docs.scipy.org/doc/numpy/reference/routines.testing.html>`_.
@@ -264,15 +264,15 @@ Running the test suite
 ~~~~~~~~~~~~~~~~~~~~~~
 
 The tests can then be run directly inside your Git clone (without having to
-install *GeoPandas*) by typing::
+install GeoPandas) by typing::
 
     pytest
 
 6) Updating the Documentation
 -----------------------------
 
-*GeoPandas* documentation resides in the ``doc`` folder. Changes to the docs are made by
-modifying the appropriate file in the ``source`` folder within ``doc``. *GeoPandas* docs use
+GeoPandas documentation resides in the ``doc`` folder. Changes to the docs are made by
+modifying the appropriate file in the ``source`` folder within ``doc``. GeoPandas docs use
 mixture of reStructuredText syntax for ``rst`` files, `which is explained here
 <http://www.sphinx-doc.org/en/stable/rest.html#rst-primer>`_ and MyST syntax for ``md``
 files `explained here <https://myst-parser.readthedocs.io/en/latest/index.html>`_.
@@ -313,7 +313,7 @@ syntax are usually quite straightforward.
 ------------------------------
 
 Once you've made changes and pushed them to your forked repository, you then
-submit a pull request to have them integrated into the *GeoPandas* code base.
+submit a pull request to have them integrated into the GeoPandas code base.
 
 You can find a pull request (or PR) tutorial in the `GitHub's Help Docs <https://help.github.com/articles/using-pull-requests/>`_.
 
@@ -344,7 +344,7 @@ use the provided development environment in ``environment-dev.yml``, you must fi
    $ python -m pip install pre-commit
 
 From the root of the geopandas repository, you should then install the
-``pre-commit`` included in *GeoPandas*::
+``pre-commit`` included in GeoPandas::
 
    $ pre-commit install
 
diff --git a/doc/source/docs/reference/sindex.rst b/doc/source/docs/reference/sindex.rst
index a1d09461..bb8c0d93 100644
--- a/doc/source/docs/reference/sindex.rst
+++ b/doc/source/docs/reference/sindex.rst
@@ -4,9 +4,9 @@ Spatial index
 .. currentmodule:: geopandas
 
 GeoPandas offers built-in support for spatial indexing using an R-Tree algorithm.
-Depending on the ability to import ``pygeos``, GeoPandas will either use
+Depending on the ability to import PyGEOS, GeoPandas will either use
 ``pygeos.STRtree`` or ``rtree.index.Index``. The main interface for both is the
-same and follows the ``pygeos`` model.
+same and follows the PyGEOS model.
 
 ``GeoSeries.sindex`` creates a spatial index, which can use the methods and
 properties documented below.
@@ -43,7 +43,7 @@ In addition to the methods listed above, the ``rtree``-based spatial index
 (``geopandas.sindex.RTreeIndex``) offers the full capability of
 ``rtree.index.Index`` - see the full API in the `rtree documentation`_.
 
-Similarly, the ``pygeos``-based spatial index
+Similarly, the PyGEOS-based spatial index
 (``geopandas.sindex.PyGEOSSTRTreeIndex``) offers the full capability of
 ``pygeos.STRtree``, including nearest-neighbor queries.
 See the full API in the `PyGEOS STRTree documentation`_.
diff --git a/doc/source/docs/user_guide/aggregation_with_dissolve.rst b/doc/source/docs/user_guide/aggregation_with_dissolve.rst
index 13a52c20..b0fd42ba 100644
--- a/doc/source/docs/user_guide/aggregation_with_dissolve.rst
+++ b/doc/source/docs/user_guide/aggregation_with_dissolve.rst
@@ -12,7 +12,7 @@ Aggregation with dissolve
 
 Spatial data are often more granular than we need. For example, we might have data on sub-national units, but we're actually interested in studying patterns at the level of countries.
 
-In a non-spatial setting, when all we need are summary statistics of the data, we aggregate our data using the :meth:`~pandas.DataFrame.groupby` function. But for spatial data, we sometimes also need to aggregate geometric features. In the *geopandas* library, we can aggregate geometric features using the :meth:`~geopandas.GeoDataFrame.dissolve` function.
+In a non-spatial setting, when all we need are summary statistics of the data, we aggregate our data using the :meth:`~pandas.DataFrame.groupby` function. But for spatial data, we sometimes also need to aggregate geometric features. In the GeoPandas library, we can aggregate geometric features using the :meth:`~geopandas.GeoDataFrame.dissolve` function.
 
 :meth:`~geopandas.GeoDataFrame.dissolve` can be thought of as doing three things:
 
@@ -23,7 +23,7 @@ In a non-spatial setting, when all we need are summary statistics of the data, w
 :meth:`~geopandas.GeoDataFrame.dissolve` Example
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Suppose we are interested in studying continents, but we only have country-level data like the country dataset included in *geopandas*. We can easily convert this to a continent-level dataset.
+Suppose we are interested in studying continents, but we only have country-level data like the country dataset included in GeoPandas. We can easily convert this to a continent-level dataset.
 
 
 First, let's look at the most simple case where we just want continent shapes and names. By default, :meth:`~geopandas.GeoDataFrame.dissolve` will pass ``'first'`` to :ref:`groupby.aggregate <groupby.aggregate>`.
diff --git a/doc/source/docs/user_guide/data_structures.rst b/doc/source/docs/user_guide/data_structures.rst
index bd0badf7..eb1ffc08 100644
--- a/doc/source/docs/user_guide/data_structures.rst
+++ b/doc/source/docs/user_guide/data_structures.rst
@@ -26,7 +26,7 @@ of only one shape (like a single polygon) or multiple shapes that are
 meant to be thought of as one observation (like the many polygons that
 make up the State of Hawaii or a country like Indonesia).
 
-*geopandas* has three basic classes of geometric objects (which are actually *shapely* objects):
+GeoPandas has three basic classes of geometric objects (which are actually *shapely* objects):
 
 * Points / Multi-Points
 * Lines / Multi-Lines
diff --git a/doc/source/docs/user_guide/geocoding.rst b/doc/source/docs/user_guide/geocoding.rst
index 7605e8cc..ce04bea7 100644
--- a/doc/source/docs/user_guide/geocoding.rst
+++ b/doc/source/docs/user_guide/geocoding.rst
@@ -9,11 +9,11 @@
 Geocoding
 ==========
 
-``geopandas`` supports geocoding (i.e., converting place names to
-location on Earth) through `geopy`_, an optional dependency of ``geopandas``.
+GeoPandas supports geocoding (i.e., converting place names to
+location on Earth) through `geopy`_, an optional dependency of GeoPandas.
 The following example shows how to get the
 locations of boroughs in New York City, and plots those locations along
-with the detailed borough boundary file included within ``geopandas``.
+with the detailed borough boundary file included within GeoPandas.
 
 .. _geopy: http://geopy.readthedocs.io/
 
diff --git a/doc/source/docs/user_guide/geometric_manipulations.rst b/doc/source/docs/user_guide/geometric_manipulations.rst
index 6605e732..8c4d46cd 100644
--- a/doc/source/docs/user_guide/geometric_manipulations.rst
+++ b/doc/source/docs/user_guide/geometric_manipulations.rst
@@ -3,7 +3,7 @@
 Geometric manipulations
 ========================
 
-*geopandas* makes available all the tools for geometric manipulations in the `Shapely library <http://shapely.readthedocs.io/en/latest/manual.html>`_.
+GeoPandas makes available all the tools for geometric manipulations in the `Shapely library <http://shapely.readthedocs.io/en/latest/manual.html>`_.
 
 Note that documentation for all set-theoretic tools for creating new shapes using the relationship between two different spatial datasets -- like creating intersections, or differences -- can be found at :doc:`Set operations with overlay <set_operations>`.
 
diff --git a/doc/source/docs/user_guide/io.rst b/doc/source/docs/user_guide/io.rst
index cbcce576..38485b68 100644
--- a/doc/source/docs/user_guide/io.rst
+++ b/doc/source/docs/user_guide/io.rst
@@ -6,12 +6,12 @@ Reading and writing files
 Reading spatial data
 ---------------------
 
-*geopandas* can read almost any vector-based spatial data format including ESRI
+GeoPandas can read almost any vector-based spatial data format including ESRI
 shapefile, GeoJSON files and more using the command::
 
     geopandas.read_file()
 
-which returns a GeoDataFrame object. This is possible because *geopandas* makes
+which returns a GeoDataFrame object. This is possible because GeoPandas makes
 use of the great `Fiona <http://fiona.readthedocs.io/en/latest/manual.html>`_
 library, which in turn makes use of a massive open-source program called
 `GDAL/OGR <http://www.gdal.org/>`_ designed to facilitate spatial data
@@ -40,7 +40,7 @@ these on runtime by updating the `supported_drivers` dictionary like::
 
     fiona.supported_drivers["NAS"] = "raw"
     
-Where supported in :mod:`Fiona`, *geopandas* can also load resources directly from
+Where supported in :mod:`Fiona`, GeoPandas can also load resources directly from
 a web URL, for example for GeoJSON files from `geojson.xyz <http://geojson.xyz/>`_::
 
     url = "http://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_land.geojson"
@@ -227,7 +227,7 @@ by using the :meth:`geopandas.GeoDataFrame.to_postgis` method.
 Spatial databases
 -----------------
 
-*geopandas* can also get data from a PostGIS database using the
+GeoPandas can also get data from a PostGIS database using the
 :func:`geopandas.read_postgis` command.
 
 Writing to PostGIS::
diff --git a/doc/source/docs/user_guide/mapping.rst b/doc/source/docs/user_guide/mapping.rst
index 9af13453..7792b374 100644
--- a/doc/source/docs/user_guide/mapping.rst
+++ b/doc/source/docs/user_guide/mapping.rst
@@ -15,7 +15,7 @@ Mapping and plotting tools
 =========================================
 
 
-*geopandas* provides a high-level interface to the matplotlib_ library for making maps. Mapping shapes is as easy as using the :meth:`~GeoDataFrame.plot()` method on a :class:`GeoSeries` or :class:`GeoDataFrame`.
+GeoPandas provides a high-level interface to the matplotlib_ library for making maps. Mapping shapes is as easy as using the :meth:`~GeoDataFrame.plot()` method on a :class:`GeoSeries` or :class:`GeoDataFrame`.
 
 .. _matplotlib: https://matplotlib.org/stable/
 
@@ -43,7 +43,7 @@ Note that in general, any options one can pass to `pyplot <http://matplotlib.org
 Choropleth maps
 -----------------
 
-*geopandas* makes it easy to create Choropleth maps (maps where the color of each shape is based on the value of an associated variable). Simply use the plot command with the ``column`` argument set to the column whose values you want used to assign colors.
+GeoPandas makes it easy to create Choropleth maps (maps where the color of each shape is based on the value of an associated variable). Simply use the plot command with the ``column`` argument set to the column whose values you want used to assign colors.
 
 .. ipython:: python
    :okwarning:
@@ -205,7 +205,7 @@ Before combining maps, however, remember to always ensure they share a common CR
     fig, ax = plt.subplots()
 
     # set aspect to equal. This is done automatically
-    # when using *geopandas* plot on it's own, but not when
+    # when using GeoPandas plot on it's own, but not when
     # working with pyplot directly.
     ax.set_aspect('equal')
 
diff --git a/doc/source/docs/user_guide/mergingdata.rst b/doc/source/docs/user_guide/mergingdata.rst
index 40021657..c36a5392 100644
--- a/doc/source/docs/user_guide/mergingdata.rst
+++ b/doc/source/docs/user_guide/mergingdata.rst
@@ -10,7 +10,7 @@
 Merging data
 =========================================
 
-There are two ways to combine datasets in *geopandas* -- attribute joins and spatial joins.
+There are two ways to combine datasets in GeoPandas -- attribute joins and spatial joins.
 
 In an attribute join, a :class:`GeoSeries` or :class:`GeoDataFrame` is
 combined with a regular :class:`pandas.Series` or :class:`pandas.DataFrame` based on a
@@ -114,13 +114,13 @@ Binary predicate joins are available via :meth:`GeoDataFrame.sjoin`.
 
 **predicate**
 
-The ``predicate`` argument specifies how ``geopandas`` decides whether or not to join the attributes of one
+The ``predicate`` argument specifies how GeoPandas decides whether or not to join the attributes of one
 object to another, based on their geometric relationship.
 
 The values for ``predicate`` correspond to the names of geometric binary predicates and depend on the spatial
 index implementation.
 
-The default spatial index in ``geopandas`` currently supports the following values for ``predicate`` which are
+The default spatial index in GeoPandas currently supports the following values for ``predicate`` which are
 defined in the
 `Shapely documentation <http://shapely.readthedocs.io/en/latest/manual.html#binary-predicates>`__:
 
diff --git a/doc/source/docs/user_guide/projections.rst b/doc/source/docs/user_guide/projections.rst
index 981152ce..70f824b3 100644
--- a/doc/source/docs/user_guide/projections.rst
+++ b/doc/source/docs/user_guide/projections.rst
@@ -24,7 +24,7 @@ The same CRS can often be referred to in many ways. For example, one of the most
 commonly used CRS is the WGS84 latitude-longitude projection. This can be
 referred to using the authority code ``"EPSG:4326"``.
 
-*geopandas* can accept anything accepted by :meth:`pyproj.CRS.from_user_input() <pyproj.crs.CRS.from_user_input>`:
+GeoPandas can accept anything accepted by :meth:`pyproj.CRS.from_user_input() <pyproj.crs.CRS.from_user_input>`:
 
 - CRS WKT string
 - An authority string (i.e. "epsg:4326")
@@ -38,10 +38,9 @@ referred to using the authority code ``"EPSG:4326"``.
 
 For reference, a few very common projections and their EPSG codes:
 
-* WGS84 Latitude/Longitude: ``"EPSG:4326"``
-* UTM Zones (North): ``"EPSG:32633"``
-* UTM Zones (South): ``"EPSG:32733"``
-
+* WGS84 Latitude/Longitude: EPSG:4326
+* UTM Zones (North): EPSG:32633
+* UTM Zones (South): EPSG:32733
 
 What is the best format to store the CRS information?
 -----------------------------------------------------
@@ -57,11 +56,11 @@ Setting a projection
 
 There are two relevant operations for projections: setting a projection and re-projecting.
 
-Setting a projection may be necessary when for some reason *geopandas* has coordinate data (x-y values), but no information about how those coordinates refer to locations in the real world. Setting a projection is how one tells *geopandas* how to interpret coordinates. If no CRS is set, *geopandas* geometry operations will still work, but coordinate transformations will not be possible and exported files may not be interpreted correctly by other software.
+Setting a projection may be necessary when for some reason GeoPandas has coordinate data (x-y values), but no information about how those coordinates refer to locations in the real world. Setting a projection is how one tells GeoPandas how to interpret coordinates. If no CRS is set, GeoPandas geometry operations will still work, but coordinate transformations will not be possible and exported files may not be interpreted correctly by other software.
 
 Be aware that **most of the time** you don't have to set a projection. Data loaded from a reputable source (using the :func:`geopandas.read_file()` command) *should* always include projection information. You can see an objects current CRS through the :attr:`GeoSeries.crs` attribute.
 
-From time to time, however, you may get data that does not include a projection. In this situation, you have to set the CRS so *geopandas* knows how to interpret the coordinates.
+From time to time, however, you may get data that does not include a projection. In this situation, you have to set the CRS so GeoPandas knows how to interpret the coordinates.
 
 For example, if you convert a spreadsheet of latitudes and longitudes into a
 GeoSeries by hand, you would set the projection by passing the WGS84
diff --git a/doc/source/docs/user_guide/reproject_fiona.rst b/doc/source/docs/user_guide/reproject_fiona.rst
index 79fed3fe..0ea9a19b 100644
--- a/doc/source/docs/user_guide/reproject_fiona.rst
+++ b/doc/source/docs/user_guide/reproject_fiona.rst
@@ -2,9 +2,9 @@ Re-projecting using GDAL with Rasterio and Fiona
 ================================================
 
 The simplest method of re-projecting is :meth:`GeoDataFrame.to_crs`.
-It uses ``pyproj`` as the engine and transforms the points within the geometries.
+It uses pyproj as the engine and transforms the points within the geometries.
 
-These examples demonstrate how to use ``Fiona`` or ``rasterio`` as the engine to re-project your data.
+These examples demonstrate how to use Fiona or rasterio as the engine to re-project your data.
 Fiona and rasterio are powered by GDAL and with algorithms that consider the geometry instead of
 just the points the geometry contains. This is particularly useful for antimeridian cutting.
 However, this also means the transformation is not as fast.
diff --git a/doc/source/docs/user_guide/set_operations.rst b/doc/source/docs/user_guide/set_operations.rst
index 26fee4df..1286b765 100644
--- a/doc/source/docs/user_guide/set_operations.rst
+++ b/doc/source/docs/user_guide/set_operations.rst
@@ -15,7 +15,7 @@ When working with multiple spatial datasets -- especially multiple *polygon* or
 *line* datasets -- users often wish to create new shapes based on places where
 those datasets overlap (or don't overlap). These manipulations are often
 referred using the language of sets -- intersections, unions, and differences.
-These types of operations are made available in the *geopandas* library through
+These types of operations are made available in the GeoPandas library through
 the :meth:`~geopandas.GeoDataFrame.overlay` method.
 
 The basic idea is demonstrated by the graphic below but keep in mind that
diff --git a/geopandas/_compat.py b/geopandas/_compat.py
index 01f6fb6c..d1f132b4 100644
--- a/geopandas/_compat.py
+++ b/geopandas/_compat.py
@@ -20,6 +20,7 @@ PANDAS_GE_115 = Version(pd.__version__) >= Version("1.1.5")
 PANDAS_GE_12 = Version(pd.__version__) >= Version("1.2.0")
 PANDAS_GE_13 = Version(pd.__version__) >= Version("1.3.0")
 PANDAS_GE_14 = Version(pd.__version__) >= Version("1.4.0rc0")
+PANDAS_GE_20 = Version(pd.__version__) >= Version("2.0.0.dev0")
 
 
 # -----------------------------------------------------------------------------
diff --git a/geopandas/_vectorized.py b/geopandas/_vectorized.py
index b1700b49..20aa7332 100644
--- a/geopandas/_vectorized.py
+++ b/geopandas/_vectorized.py
@@ -83,6 +83,9 @@ def _pygeos_to_shapely(geom):
     if pygeos.is_empty(geom) and pygeos.get_type_id(geom) == 0:
         # empty point does not roundtrip through WKB
         return shapely.wkt.loads("POINT EMPTY")
+    elif pygeos.get_type_id(geom) == 2:
+        # linearring does not roundtrip through WKB
+        return shapely.LinearRing(shapely.wkb.loads(pygeos.to_wkb(geom)))
     else:
         return shapely.wkb.loads(pygeos.to_wkb(geom))
 
diff --git a/geopandas/array.py b/geopandas/array.py
index 9f366612..5f472333 100644
--- a/geopandas/array.py
+++ b/geopandas/array.py
@@ -1394,6 +1394,9 @@ class GeometryArray(ExtensionArray):
 
 
 def _get_common_crs(arr_seq):
+    # mask out all None arrays with no crs (most likely auto generated by pandas
+    # from concat with missing column)
+    arr_seq = [ga for ga in arr_seq if not (ga.isna().all() and ga.crs is None)]
 
     crs_set = {arr.crs for arr in arr_seq}
     crs_not_none = [crs for crs in crs_set if crs is not None]
diff --git a/geopandas/base.py b/geopandas/base.py
index 70c40bda..ada4c79d 100644
--- a/geopandas/base.py
+++ b/geopandas/base.py
@@ -308,7 +308,7 @@ GeometryCollection
         >>> gdf = geopandas.GeoDataFrame(d, crs="EPSG:4326")
         >>> gdf
                            geometry
-        0  GEOMETRYCOLLECTION EMPTY
+        0               POINT EMPTY
         1   POINT (2.00000 1.00000)
         2                      None
         >>> gdf.is_empty
@@ -2247,7 +2247,7 @@ GeometryCollection
         0                                                 None
         1    POLYGON ((0.00000 2.00000, 2.00000 2.00000, 1....
         2    MULTILINESTRING ((0.00000 0.00000, 1.00000 1.0...
-        3                                     LINESTRING EMPTY
+        3                                   LINESTRING Z EMPTY
         4                              POINT (0.00000 1.00000)
         5                                                 None
         dtype: geometry
@@ -2362,7 +2362,7 @@ GeometryCollection
         0                                                 None
         1    POLYGON ((0.00000 2.00000, 2.00000 2.00000, 1....
         2    MULTILINESTRING ((0.00000 0.00000, 1.00000 1.0...
-        3                                     LINESTRING EMPTY
+        3                                   LINESTRING Z EMPTY
         4        MULTIPOINT (0.00000 1.00000, 1.00000 1.00000)
         5                                                 None
         dtype: geometry
diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py
index a7a84ee7..ef850187 100644
--- a/geopandas/geoseries.py
+++ b/geopandas/geoseries.py
@@ -673,7 +673,7 @@ class GeoSeries(GeoPandasBase, Series):
         >>> s
         0    POLYGON ((0.00000 0.00000, 1.00000 1.00000, 0....
         1                                                 None
-        2                             GEOMETRYCOLLECTION EMPTY
+        2                                        POLYGON EMPTY
         dtype: geometry
         >>> s.isna()
         0    False
@@ -717,7 +717,7 @@ class GeoSeries(GeoPandasBase, Series):
         >>> s
         0    POLYGON ((0.00000 0.00000, 1.00000 1.00000, 0....
         1                                                 None
-        2                             GEOMETRYCOLLECTION EMPTY
+        2                                        POLYGON EMPTY
         dtype: geometry
         >>> s.notna()
         0     True
diff --git a/pyproject.toml b/pyproject.toml
index a548feab..ff612885 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,20 +16,6 @@ maintainers = [
 license = {text = "BSD 3-Clause"}
 description = "Geographic pandas extensions"
 keywords = ["GIS", "cartography", "pandas", "shapely"]
-readme = {text = """\
-GeoPandas is a project to add support for geographic data to
-`pandas`_ objects.
-
-The goal of GeoPandas is to make working with geospatial data in
-python easier. It combines the capabilities of `pandas`_ and `shapely`_,
-providing geospatial operations in pandas and a high-level interface
-to multiple geometries to shapely. GeoPandas enables you to easily do
-operations in python that would otherwise require a spatial database
-such as PostGIS.
-
-.. _pandas: https://pandas.pydata.org
-.. _shapely: https://shapely.readthedocs.io/en/latest/
-""", content-type = "text/x-rst"}
 classifiers = [
     "Development Status :: 5 - Production/Stable",
     "Intended Audience :: Science/Research",
@@ -48,6 +34,23 @@ dependencies = [
     "shapely >= 1.7",
 ]
 
+[project.readme]
+text = """\
+GeoPandas is a project to add support for geographic data to
+`pandas`_ objects.
+
+The goal of GeoPandas is to make working with geospatial data in
+python easier. It combines the capabilities of `pandas`_ and `shapely`_,
+providing geospatial operations in pandas and a high-level interface
+to multiple geometries to shapely. GeoPandas enables you to easily do
+operations in python that would otherwise require a spatial database
+such as PostGIS.
+
+.. _pandas: https://pandas.pydata.org
+.. _shapely: https://shapely.readthedocs.io/en/latest/
+"""
+content-type = "text/x-rst"
+
 [project.urls]
 Home = "https://geopandas.org"
 Repository = "https://github.com/geopandas/geopandas"
@@ -75,4 +78,4 @@ xfail_strict = true
 filterwarnings = [
     "ignore:distutils Version classes are deprecated.*:DeprecationWarning:pandas.*",
     "ignore:distutils Version classes are deprecated.*:DeprecationWarning:numpy.*"
-]
\ No newline at end of file
+]
diff --git a/setup.py b/setup.py
index 6f675bc9..35da885a 100755
--- a/setup.py
+++ b/setup.py
@@ -15,6 +15,7 @@ import versioneer  # noqa: E402
 
 # see pyproject.toml for static project metadata
 setup(
+    name="geopandas",  # need by GitHub dependency graph
     version=versioneer.get_version(),
     cmdclass=versioneer.get_cmdclass(),
 )


Test patch:
diff --git a/ci/envs/39-latest-conda-forge.yaml b/ci/envs/39-latest-conda-forge.yaml
index 6058f0b9..0dfc4b9c 100644
--- a/ci/envs/39-latest-conda-forge.yaml
+++ b/ci/envs/39-latest-conda-forge.yaml
@@ -1,12 +1,13 @@
 name: test
 channels:
   - conda-forge
-  # - conda-forge/label/shapely_dev
 dependencies:
   - python=3.9
   # required
   - pandas=1.3
-  # - shapely=2
+  - shapely=2
+  - geos
+  - cython
   - fiona
   - pyproj
   # use this build to have one with only shapely 2.0 installed
@@ -34,7 +35,3 @@ dependencies:
   - pyarrow
   # doctest testing
   - pytest-doctestplus
-  - pip
-  - pip:
-      - --pre
-      - shapely==2.0b1
diff --git a/geopandas/io/tests/test_file.py b/geopandas/io/tests/test_file.py
index df616a5e..416935d9 100644
--- a/geopandas/io/tests/test_file.py
+++ b/geopandas/io/tests/test_file.py
@@ -16,6 +16,7 @@ from shapely.geometry import Point, Polygon, box
 
 import geopandas
 from geopandas import GeoDataFrame, read_file
+from geopandas._compat import PANDAS_GE_20
 from geopandas.io.file import _detect_driver, _EXTENSION_TO_DRIVER
 
 from geopandas.testing import assert_geodataframe_equal, assert_geoseries_equal
@@ -309,7 +310,11 @@ def test_read_file_datetime_mixed_offsets(tmpdir):
     if FIONA_GE_1814:
         # Convert mixed timezones to UTC equivalent
         assert is_datetime64_any_dtype(res["date"])
-        assert res["date"].dt.tz == pytz.utc
+        if not PANDAS_GE_20:
+            utc = pytz.utc
+        else:
+            utc = datetime.timezone.utc
+        assert res["date"].dt.tz == utc
     else:
         # old fiona and pyogrio ignore timezones and read as datetimes successfully
         assert is_datetime64_any_dtype(res["date"])
diff --git a/geopandas/tests/test_merge.py b/geopandas/tests/test_merge.py
index 3f65346a..f048b9a6 100644
--- a/geopandas/tests/test_merge.py
+++ b/geopandas/tests/test_merge.py
@@ -1,3 +1,5 @@
+import warnings
+
 import pandas as pd
 import pytest
 from geopandas.testing import assert_geodataframe_equal
@@ -103,6 +105,39 @@ class TestMerging:
                 [self.gdf, self.gdf.set_crs("epsg:4326"), self.gdf.set_crs("epsg:4327")]
             )
 
+    def test_concat_axis0_unaligned_cols(self):
+        # https://github.com/geopandas/geopandas/issues/2679
+        gdf = self.gdf.set_crs("epsg:4326").assign(
+            geom=self.gdf.geometry.set_crs("epsg:4327")
+        )
+        both_geom_cols = gdf[["geom", "geometry"]]
+        single_geom_col = gdf[["geometry"]]
+        with warnings.catch_warnings():
+            warnings.simplefilter("error")
+            pd.concat([both_geom_cols, single_geom_col])
+        # Check order of mismatch doesn't matter
+        with warnings.catch_warnings():
+            warnings.simplefilter("error")
+            pd.concat([single_geom_col, both_geom_cols])
+
+        # Side effect of this fix, explicitly provided all none geoseries
+        # will not be warned for (ideally this would still warn)
+        explicit_all_none_case = gdf[["geometry"]].assign(
+            geom=GeoSeries([None for _ in range(len(gdf))])
+        )
+        with warnings.catch_warnings():
+            warnings.simplefilter("error")
+            pd.concat([both_geom_cols, explicit_all_none_case])
+
+        # Check concat with partially None col is not affected by the special casing
+        # for all None no CRS handling
+        with pytest.warns(
+            UserWarning, match=r"CRS not set for some of the concatenation inputs.*"
+        ):
+            partial_none_case = self.gdf[["geometry"]]
+            partial_none_case.iloc[0] = None
+            pd.concat([single_geom_col, partial_none_case])
+
     def test_concat_axis1(self):
 
         res = pd.concat([self.gdf, self.df], axis=1)
diff --git a/geopandas/tests/test_pandas_methods.py b/geopandas/tests/test_pandas_methods.py
index b29ce854..27d45f1d 100644
--- a/geopandas/tests/test_pandas_methods.py
+++ b/geopandas/tests/test_pandas_methods.py
@@ -5,7 +5,7 @@ from numpy.testing import assert_array_equal
 import pandas as pd
 
 import shapely
-from shapely.geometry import Point, GeometryCollection, LineString
+from shapely.geometry import Point, GeometryCollection, LineString, LinearRing
 
 import geopandas
 from geopandas import GeoDataFrame, GeoSeries
@@ -86,6 +86,24 @@ def test_repr_empty():
     assert "geometry" in df._repr_html_()
 
 
+def test_repr_linearring():
+    # https://github.com/geopandas/geopandas/pull/2689
+    # specifically, checking internal shapely/pygeos/wkt/wkb conversions
+    # preserve LinearRing
+    s = GeoSeries([LinearRing([(0, 0), (1, 1), (1, -1)])])
+    assert "LINEARRING" in str(s.iloc[0])  # shapely scalar repr
+    assert "LINEARRING" in str(s)  # GeoSeries repr
+
+    # check something coercible to linearring is not converted
+    s2 = GeoSeries(
+        [
+            LineString([(0, 0), (1, 1), (1, -1)]),
+            LineString([(0, 0), (1, 1), (1, -1), (0, 0)]),
+        ]
+    )
+    assert "LINEARRING" not in str(s2)
+
+
 def test_indexing(s, df):
 
     # accessing scalar from the geometry (column)
diff --git a/geopandas/tests/test_sindex.py b/geopandas/tests/test_sindex.py
index c3406dce..91a71650 100644
--- a/geopandas/tests/test_sindex.py
+++ b/geopandas/tests/test_sindex.py
@@ -11,7 +11,6 @@ from shapely.geometry import (
 from numpy.testing import assert_array_equal
 
 import geopandas
-import pandas as pd
 from geopandas import _compat as compat
 from geopandas import GeoDataFrame, GeoSeries, read_file, datasets
 
@@ -76,13 +75,15 @@ class TestSeriesSindex:
         s = GeoSeries([t1, t2, sq])
         assert s.sindex.size == 3
 
+    @pytest.mark.filterwarnings("ignore:The series.append method is deprecated")
+    @pytest.mark.skipif(compat.PANDAS_GE_20, reason="append removed in pandas 2.0")
     def test_polygons_append(self):
         t1 = Polygon([(0, 0), (1, 0), (1, 1)])
         t2 = Polygon([(0, 0), (1, 1), (0, 1)])
         sq = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
         s = GeoSeries([t1, t2, sq])
         t = GeoSeries([t1, t2, sq], [3, 4, 5])
-        s = pd.concat([s, t])
+        s = s.append(t)
         assert len(s) == 6
         assert s.sindex.size == 6