diff -Nru python-geopandas-0.8.0/CHANGELOG.md python-geopandas-0.8.1/CHANGELOG.md --- python-geopandas-0.8.0/CHANGELOG.md 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/CHANGELOG.md 2020-07-15 17:54:36.000000000 +0000 @@ -1,6 +1,19 @@ Changelog ========= + +Version 0.8.1 (July 15, 2020) +----------------------------- + +Small bug-fix release: + +- Fix a regression in the `plot()` method when visualizing with a + JenksCaspallSampled or FisherJenksSampled scheme (#1486). +- Fix spurious warning in `GeoDataFrame.to_postgis` (#1497). +- Fix the un-pickling with `pd.read_pickle` of files written with older + GeoPandas versions (#1511). + + Version 0.8.0 (June 24, 2020) ----------------------------- diff -Nru python-geopandas-0.8.0/debian/changelog python-geopandas-0.8.1/debian/changelog --- python-geopandas-0.8.0/debian/changelog 2020-06-24 13:50:39.000000000 +0000 +++ python-geopandas-0.8.1/debian/changelog 2020-07-16 03:39:56.000000000 +0000 @@ -1,3 +1,10 @@ +python-geopandas (0.8.1-1) unstable; urgency=medium + + * Team upload. + * New upstream release. + + -- Bas Couwenberg Thu, 16 Jul 2020 05:39:56 +0200 + python-geopandas (0.8.0-1) unstable; urgency=medium * Team upload. diff -Nru python-geopandas-0.8.0/geopandas/array.py python-geopandas-0.8.1/geopandas/array.py --- python-geopandas-0.8.0/geopandas/array.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/array.py 2020-07-15 17:54:36.000000000 +0000 @@ -384,6 +384,13 @@ self.data = geoms self.base = None + else: + + def __setstate__(self, state): + if "_crs" not in state: + state["_crs"] = None + self.__dict__.update(state) + # ------------------------------------------------------------------------- # Geometry related methods # ------------------------------------------------------------------------- diff -Nru python-geopandas-0.8.0/geopandas/geodataframe.py python-geopandas-0.8.1/geopandas/geodataframe.py --- python-geopandas-0.8.0/geopandas/geodataframe.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/geodataframe.py 2020-07-15 17:54:36.000000000 +0000 @@ -329,6 +329,28 @@ # column called 'geometry' without geometry self._crs = None if not value else CRS.from_user_input(value) + def __setstate__(self, state): + # overriding DataFrame method for compat with older pickles (CRS handling) + if isinstance(state, dict): + if "_metadata" in state and "crs" in state["_metadata"]: + metadata = state["_metadata"] + metadata[metadata.index("crs")] = "_crs" + if "crs" in state and "_crs" not in state: + crs = state.pop("crs") + state["_crs"] = CRS.from_user_input(crs) if crs is not None else crs + + super().__setstate__(state) + + # for some versions that didn't yet have CRS at array level -> crs is set + # at GeoDataFrame level with '_crs' (and not 'crs'), so without propagating + # to the GeoSeries/GeometryArray + try: + if self.crs is not None: + if self.geometry.values.crs is None: + self.crs = self.crs + except Exception: + pass + @classmethod def from_file(cls, filename, **kwargs): """Alternate constructor to create a ``GeoDataFrame`` from a file. diff -Nru python-geopandas-0.8.0/geopandas/io/sql.py python-geopandas-0.8.1/geopandas/io/sql.py --- python-geopandas-0.8.0/geopandas/io/sql.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/io/sql.py 2020-07-15 17:54:36.000000000 +0000 @@ -248,8 +248,12 @@ geoms = [dumps(geom, srid=srid, hex=True) for geom in gdf[geom_name]] - gdf[geom_name] = geoms - return gdf + # The gdf will warn that the geometry column doesn't hold in-memory geometries + # now that they are EWKB, so convert back to a regular dataframe to avoid warning + # the user that the dtypes are unexpected. + df = pd.DataFrame(gdf, copy=False) + df[geom_name] = geoms + return df def _psql_insert_copy(tbl, conn, keys, data_iter): Binary files /tmp/tmppKZ1bh/ALVjC0rfVf/python-geopandas-0.8.0/geopandas/io/tests/data/pickle/0.5.1_pd-0.25.3_py-3.7.3_x86_64_linux.pickle and /tmp/tmppKZ1bh/lCGwhaNDfT/python-geopandas-0.8.1/geopandas/io/tests/data/pickle/0.5.1_pd-0.25.3_py-3.7.3_x86_64_linux.pickle differ Binary files /tmp/tmppKZ1bh/ALVjC0rfVf/python-geopandas-0.8.0/geopandas/io/tests/data/pickle/0.6.3_pd-0.25.3_py-3.8.0_x86_64_linux.pickle and /tmp/tmppKZ1bh/lCGwhaNDfT/python-geopandas-0.8.1/geopandas/io/tests/data/pickle/0.6.3_pd-0.25.3_py-3.8.0_x86_64_linux.pickle differ Binary files /tmp/tmppKZ1bh/ALVjC0rfVf/python-geopandas-0.8.0/geopandas/io/tests/data/pickle/0.7.0_pd-1.0.4_py-3.7.6_x86_64_linux.pickle and /tmp/tmppKZ1bh/lCGwhaNDfT/python-geopandas-0.8.1/geopandas/io/tests/data/pickle/0.7.0_pd-1.0.4_py-3.7.6_x86_64_linux.pickle differ Binary files /tmp/tmppKZ1bh/ALVjC0rfVf/python-geopandas-0.8.0/geopandas/io/tests/data/pickle/0.8.0_pd-1.0.5_py-3.8.3_x86_64_linux.pickle and /tmp/tmppKZ1bh/lCGwhaNDfT/python-geopandas-0.8.1/geopandas/io/tests/data/pickle/0.8.0_pd-1.0.5_py-3.8.3_x86_64_linux.pickle differ diff -Nru python-geopandas-0.8.0/geopandas/io/tests/generate_legacy_storage_files.py python-geopandas-0.8.1/geopandas/io/tests/generate_legacy_storage_files.py --- python-geopandas-0.8.0/geopandas/io/tests/generate_legacy_storage_files.py 1970-01-01 00:00:00.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/io/tests/generate_legacy_storage_files.py 2020-07-15 17:54:36.000000000 +0000 @@ -0,0 +1,98 @@ +""" +Script to create the data and write legacy storage (pickle) files. + +Based on pandas' generate_legacy_storage_files.py script. + +To use this script, create an environment for which you want to +generate pickles, activate the environment, and run this script as: + +$ python geopandas/geopandas/io/tests/generate_legacy_storage_files.py \ + geopandas/geopandas/io/tests/data/pickle/ pickle + +This script generates a storage file for the current arch, system, + +The idea here is you are using the *current* version of the +generate_legacy_storage_files with an *older* version of geopandas to +generate a pickle file. We will then check this file into a current +branch, and test using test_pickle.py. This will load the *older* +pickles and test versus the current data that is generated +(with master). These are then compared. + +""" +import os +import pickle +import platform +import sys + +import pandas as pd + +import geopandas +from shapely.geometry import Point + + +def create_pickle_data(): + """ create the pickle data """ + + # custom geometry column name + gdf_the_geom = geopandas.GeoDataFrame( + {"a": [1, 2, 3], "the_geom": [Point(1, 1), Point(2, 2), Point(3, 3)]}, + geometry="the_geom", + ) + + # with crs + gdf_crs = geopandas.GeoDataFrame( + {"a": [0.1, 0.2, 0.3], "geometry": [Point(1, 1), Point(2, 2), Point(3, 3)]}, + crs="EPSG:4326", + ) + + return dict(gdf_the_geom=gdf_the_geom, gdf_crs=gdf_crs) + + +def platform_name(): + return "_".join( + [ + str(geopandas.__version__), + "pd-" + str(pd.__version__), + "py-" + str(platform.python_version()), + str(platform.machine()), + str(platform.system().lower()), + ] + ) + + +def write_legacy_pickles(output_dir): + print( + "This script generates a storage file for the current arch, system, " + "and python version" + ) + print("geopandas version: {}").format(geopandas.__version__) + print(" output dir : {}".format(output_dir)) + print(" storage format: pickle") + + pth = "{}.pickle".format(platform_name()) + + fh = open(os.path.join(output_dir, pth), "wb") + pickle.dump(create_pickle_data(), fh, pickle.DEFAULT_PROTOCOL) + fh.close() + + print("created pickle file: {}".format(pth)) + + +def main(): + if len(sys.argv) != 3: + exit( + "Specify output directory and storage type: generate_legacy_" + "storage_files.py " + ) + + output_dir = str(sys.argv[1]) + storage_type = str(sys.argv[2]) + + if storage_type == "pickle": + write_legacy_pickles(output_dir=output_dir) + else: + exit("storage_type must be one of {'pickle'}") + + +if __name__ == "__main__": + main() diff -Nru python-geopandas-0.8.0/geopandas/io/tests/test_pickle.py python-geopandas-0.8.1/geopandas/io/tests/test_pickle.py --- python-geopandas-0.8.0/geopandas/io/tests/test_pickle.py 1970-01-01 00:00:00.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/io/tests/test_pickle.py 2020-07-15 17:54:36.000000000 +0000 @@ -0,0 +1,60 @@ +""" +See generate_legacy_storage_files.py for the creation of the legacy files. + +""" +from distutils.version import LooseVersion +import glob +import os +import pathlib + +import pandas as pd + +import pyproj + +import pytest +from geopandas.testing import assert_geodataframe_equal +from geopandas import _compat as compat + + +DATA_PATH = pathlib.Path(os.path.dirname(__file__)) / "data" + + +@pytest.fixture(scope="module") +def current_pickle_data(): + # our current version pickle data + from .generate_legacy_storage_files import create_pickle_data + + return create_pickle_data() + + +files = glob.glob(str(DATA_PATH / "pickle" / "*.pickle")) + + +@pytest.fixture(params=files, ids=[p.split("/")[-1] for p in files]) +def legacy_pickle(request): + return request.param + + +@pytest.mark.skipif( + compat.USE_PYGEOS or (str(pyproj.__version__) < LooseVersion("2.4")), + reason=( + "pygeos-based unpickling currently only works for pygeos-written files; " + "old pyproj versions can't read pickles from newer pyproj versions" + ), +) +def test_legacy_pickles(current_pickle_data, legacy_pickle): + result = pd.read_pickle(legacy_pickle) + + for name, value in result.items(): + expected = current_pickle_data[name] + assert_geodataframe_equal(value, expected) + + +def test_round_trip_current(tmpdir, current_pickle_data): + data = current_pickle_data + + for name, value in data.items(): + path = str(tmpdir / "{}.pickle".format(name)) + value.to_pickle(path) + result = pd.read_pickle(path) + assert_geodataframe_equal(result, value) diff -Nru python-geopandas-0.8.0/geopandas/plotting.py python-geopandas-0.8.1/geopandas/plotting.py --- python-geopandas-0.8.0/geopandas/plotting.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/plotting.py 2020-07-15 17:54:36.000000000 +0000 @@ -916,7 +916,7 @@ if "k" not in spec.args: del classification_kwds["k"] try: - binning = scheme_class(values, **classification_kwds) + binning = scheme_class(np.asarray(values), **classification_kwds) except TypeError: raise TypeError("Invalid keyword argument for %r " % scheme) return binning diff -Nru python-geopandas-0.8.0/geopandas/tests/test_extension_array.py python-geopandas-0.8.1/geopandas/tests/test_extension_array.py --- python-geopandas-0.8.0/geopandas/tests/test_extension_array.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/tests/test_extension_array.py 2020-07-15 17:54:36.000000000 +0000 @@ -497,6 +497,18 @@ def test_argsort_missing_array(self): pass + @no_sorting + def test_argmin_argmax(self): + pass + + @no_sorting + def test_argmin_argmax_empty_array(self): + pass + + @no_sorting + def test_argmin_argmax_all_na(self): + pass + class TestCasting(extension_tests.BaseCastingTests): pass diff -Nru python-geopandas-0.8.0/geopandas/tests/test_plotting.py python-geopandas-0.8.1/geopandas/tests/test_plotting.py --- python-geopandas-0.8.0/geopandas/tests/test_plotting.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/tests/test_plotting.py 2020-07-15 17:54:36.000000000 +0000 @@ -902,6 +902,8 @@ import mapclassify # noqa except ImportError: pytest.importorskip("mapclassify") + cls.classifiers = list(mapclassify.classifiers.CLASSIFIERS) + cls.classifiers.remove("UserDefined") pth = get_path("naturalearth_lowres") cls.df = read_file(pth) cls.df["NEGATIVES"] = np.linspace(-10, 10, len(cls.df.index)) @@ -970,6 +972,11 @@ ax = self.df.plot(column="NEGATIVES", scheme=scheme, k=3, legend=True) assert len(ax.get_legend().get_texts()) == 3 + def test_schemes(self): + # test if all available classifiers pass + for scheme in self.classifiers: + self.df.plot(column="pop_est", scheme=scheme, legend=True) + def test_classification_kwds(self): ax = self.df.plot( column="pop_est", diff -Nru python-geopandas-0.8.0/geopandas/_version.py python-geopandas-0.8.1/geopandas/_version.py --- python-geopandas-0.8.0/geopandas/_version.py 2020-06-24 13:26:54.000000000 +0000 +++ python-geopandas-0.8.1/geopandas/_version.py 2020-07-15 17:54:36.000000000 +0000 @@ -22,8 +22,8 @@ # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). - git_refnames = " (HEAD -> master, tag: v0.8.0)" - git_full = "0d2c621516d8fc0f6eddac7aeb6bf6d9fea78bb9" + git_refnames = " (tag: v0.8.1, 0.8.x)" + git_full = "03546f483e358b6565b11333f576e1bc68df1b57" keywords = {"refnames": git_refnames, "full": git_full} return keywords