Skip to content

Commit

Permalink
Fix deepcopy bug in CRS
Browse files Browse the repository at this point in the history
  • Loading branch information
lgolston committed Mar 22, 2024
1 parent 75ec0fa commit 3342177
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
if: matrix.python-version == '3.9' && matrix.os == 'ubuntu-latest'
id: minimum-packages
run: |
pip install cython==0.29.24 matplotlib==3.5.3 numpy==1.21 owslib==0.24.1 pyproj==3.1 scipy==1.6.3 shapely==1.7.1 pyshp==2.3.1
pip install cython==0.29.24 matplotlib==3.5.3 numpy==1.21 owslib==0.24.1 pyproj==3.3.1 scipy==1.6.3 shapely==1.7.1 pyshp==2.3.1
- name: Coverage packages
id: coverage
Expand Down
2 changes: 1 addition & 1 deletion INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Further information about the required dependencies can be found here:
**pyshp** 2.3 or later (https://pypi.python.org/pypi/pyshp)
Pure Python read/write support for ESRI Shapefile format.

**pyproj** 3.1.0 or later (https://github.com/pyproj4/pyproj/)
**pyproj** 3.3.1 or later (https://github.com/pyproj4/pyproj/)
Python interface to PROJ (cartographic projections and coordinate transformations library).

Optional Dependencies
Expand Down
4 changes: 2 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ dependencies:
- numpy>=1.21
- shapely>=1.7.1
- pyshp>=2.3
- pyproj>=3.1.0
- pyproj>=3.3.1
# The testing label has the proper version of freetype included
- conda-forge/label/testing::matplotlib-base>=3.4
- conda-forge/label/testing::matplotlib-base>=3.5

# OWS
- owslib>=0.24.1
Expand Down
3 changes: 3 additions & 0 deletions lib/cartopy/_epsg.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ def __init__(self, code):

def __repr__(self):
return f'_EPSGProjection({self.epsg_code})'

def __reduce__(self):
return self.__class__, (self.epsg_code, )
18 changes: 12 additions & 6 deletions lib/cartopy/crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ def __init__(self, proj4_params, globe=None):
See :class:`~cartopy.crs.Globe` for details.
"""
self.input = (proj4_params, globe)

# for compatibility with pyproj.CRS and rasterio.crs.CRS
try:
proj4_params = proj4_params.to_wkt()
Expand Down Expand Up @@ -209,13 +211,17 @@ def __hash__(self):

def __reduce__(self):
"""
Implement the __reduce__ API so that unpickling produces a stateless
instance of this class (e.g. an empty tuple). The state will then be
added via __getstate__ and __setstate__.
We are forced to this approach because a CRS does not store
the constructor keyword arguments in its state.
Implement the __reduce__ method used when pickling or performing deepcopy.
"""
return self.__class__, (), self.__getstate__()
if type(self) is CRS:
# State can be reproduced by the proj4_params and globe inputs.
return self.__class__, self.input
else:
# Produces a stateless instance of this class (e.g. an empty tuple).
# The state will then be added via __getstate__ and __setstate__.
# We are forced to this approach because a CRS does not store
# the constructor keyword arguments in its state.
return self.__class__, (), self.__getstate__()

def __getstate__(self):
"""Return the full state of this instance for reconstruction
Expand Down
10 changes: 5 additions & 5 deletions lib/cartopy/tests/test_crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,11 @@ def test_utm(self):

@pytest.fixture(params=[
[ccrs.PlateCarree, {}],
[ccrs.PlateCarree, dict(
central_longitude=1.23)],
[ccrs.NorthPolarStereo, dict(
central_longitude=42.5,
globe=ccrs.Globe(ellipse="helmert"))],
[ccrs.PlateCarree, dict(central_longitude=1.23)],
[ccrs.NorthPolarStereo, dict(central_longitude=42.5,
globe=ccrs.Globe(ellipse="helmert"))],
[ccrs.CRS, dict(proj4_params="3088")],
[ccrs.epsg, dict(code="3088")]
])
def proj_to_copy(request):
cls, kwargs = request.param
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dependencies = [
"shapely>=1.7",
"packaging>=20",
"pyshp>=2.3",
"pyproj>=3.1.0",
"pyproj>=3.3.1",
]
dynamic = ["version"]

Expand Down

0 comments on commit 3342177

Please sign in to comment.