Skip to content

Commit

Permalink
Cython 3.1+ fixes (#1452)
Browse files Browse the repository at this point in the history
* MNT: Avoid borrowed Python reference error

In the Geod init there is an unsafe usage of inline if/else to cast
the values. This is only used for the repr, so just live with the
extra ".0" in the display rather than casting integers.

* MNT: Fix unsafe C derivates and str/bytes casting issues with Cython 3.1+

- Avoid Unsafe C derivative of temporary Python reference
  These are in the Geod repr and c_authority casting to a temp variable
- Explicitly cstrencode when bytes are expected instead of strings

* CI: Add Cython latest installation to a workflow
  • Loading branch information
greglucas authored Oct 10, 2024
1 parent f00ae91 commit 39cf3c9
Show file tree
Hide file tree
Showing 6 changed files with 9 additions and 11 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test_proj_latest.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test PROJ Latest
name: Test PROJ and Cython Latest

on:
push:
Expand Down Expand Up @@ -41,7 +41,7 @@ jobs:
shell: bash
run: |
python -V
python -m pip install cython
python -m pip install --upgrade --pre --only-binary :all: -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython
python -m pip install -e .
python -m pip install -r requirements-test.txt
pyproj -v
Expand Down
4 changes: 2 additions & 2 deletions pyproj/_crs.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2352,13 +2352,13 @@ cdef class _CRS(Base):
self._coordinate_operation = None
self._type_name = None

def __init__(self, const char *proj_string):
def __init__(self, str proj_string):
self.context = pyproj_context_create()
self._context_manager = get_context_manager()
# initialize projection
self.projobj = proj_create(
self.context,
proj_string,
cstrencode(proj_string),
)
if self.projobj == NULL:
raise CRSError(f"Invalid projection: {proj_string}")
Expand Down
5 changes: 1 addition & 4 deletions pyproj/_geod.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,7 @@ cdef class Geod:
geod_init(&self._geod_geodesic, <double> a, <double> f)
self.a = a
self.f = f
# convert 'a' only for initstring
a_str = int(a) if a.is_integer() else a
f_str = int(f) if f.is_integer() else f
self.initstring = f"+a={a_str} +f={f_str}"
self.initstring = f"+{a=} +{f=}"
self.sphere = sphere
self.b = b
self.es = es
Expand Down
3 changes: 2 additions & 1 deletion pyproj/_transformer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ cdef class _TransformerGroup:
double north_lat_degree

if authority is not None:
c_authority = authority
tmp = cstrencode(authority)
c_authority = tmp

try:
operation_factory_context = proj_create_operation_factory_context(
Expand Down
2 changes: 1 addition & 1 deletion pyproj/database.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ def get_database_metadata(str key not None):
cdef const char* metadata = NULL
metadata = proj_context_get_database_metadata(
pyproj_context_create(),
cstrdecode(key),
cstrencode(key),
)
if metadata == NULL:
return None
Expand Down
2 changes: 1 addition & 1 deletion test/test_proj.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def test_repr(self):
def test_sphere(self):
# ellipse is Venus 2000 (IAU2000:29900), which is a sphere
g = Geod("+a=6051800 +b=6051800")
self.assertEqual(repr(g), "Geod('+a=6051800 +f=0')")
self.assertEqual(repr(g), "Geod('+a=6051800.0 +f=0.0')")

# test __repr__ for Geod object
def test_ellps_name_round_trip(self):
Expand Down

0 comments on commit 39cf3c9

Please sign in to comment.