Repository: regionmask/regionmask

Issue:
test on python 3.12
All dependencies are ready and the tests pass. So it should just be a matter of updating everything that is needed.

Discussion:
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/regionmask/regionmask/pull/494?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) Report
> Merging [#494](https://app.codecov.io/gh/regionmask/regionmask/pull/494?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) (3a725e0) into [main](https://app.codecov.io/gh/regionmask/regionmask/commit/e9ddf7aad514c8563662c0323d8a80e8bb35e993?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) (e9ddf7a) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main     #494   +/-   ##
=======================================
  Coverage   98.79%   98.79%           
=======================================
  Files          17       17           
  Lines        1330     1330           
=======================================
  Hits         1314     1314           
  Misses         16       16           
```

| [Flag](https://app.codecov.io/gh/regionmask/regionmask/pull/494/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) | Coverage Δ | |
|---|---|---|
| [bare-minimum](https://app.codecov.io/gh/regionmask/regionmask/pull/494/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) | `91.87% <ø> (ø)` | |
| [min-all-deps](https://app.codecov.io/gh/regionmask/regionmask/pull/494/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) | `?` | |
| [shapely_lt_2](https://app.codecov.io/gh/regionmask/regionmask/pull/494/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) | `95.18% <ø> (ø)` | |
| [unittests](https://app.codecov.io/gh/regionmask/regionmask/pull/494/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask) | `98.79% <ø> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=regionmask#carryforward-flags-in-the-pull-request-comment) to find out more.




Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index ac4facf..b9765a1 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -23,7 +23,7 @@ jobs:
       matrix:
         os: ["ubuntu-latest"]
         # Bookend python versions
-        python-version: ["3.9", "3.11"]
+        python-version: ["3.9", "3.12"]
     steps:
       - uses: actions/checkout@v4
         with:
diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml
index 6c2b3d6..e5a3b70 100644
--- a/.github/workflows/linting.yaml
+++ b/.github/workflows/linting.yaml
@@ -23,7 +23,7 @@ jobs:
       matrix:
         os: ["ubuntu-latest"]
         # Bookend python versions
-        python-version: ["3.11"]
+        python-version: ["3.12"]
     steps:
       - uses: actions/checkout@v4
         with:
diff --git a/.github/workflows/upstream-dev-ci.yaml b/.github/workflows/upstream-dev-ci.yaml
index 0841085..2f11651 100644
--- a/.github/workflows/upstream-dev-ci.yaml
+++ b/.github/workflows/upstream-dev-ci.yaml
@@ -33,7 +33,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ["3.11"]
+        python-version: ["3.12"]
     steps:
       - uses: actions/checkout@v4
         with:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 5bcd1f9..39baca4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -26,12 +26,15 @@ Breaking Changes
 Enhancements
 ~~~~~~~~~~~~
 
+- Add python 3.12 to list of supported versions (:pull:`494`).
+
 New regions
 ~~~~~~~~~~~
 
 Bug Fixes
 ~~~~~~~~~
 
+- Ensure correct masks are created for `float32` coordinates (:issue:`489`, :pull:`493`).
 - Fixed the default value of ``overlap`` of :py:func:`from_geopandas` to ``None`` (:issue:`453`, :pull:`470`).
 
 Docs
diff --git a/ci/requirements/docs.yml b/ci/requirements/docs.yml
index af14e8e..40d3cea 100644
--- a/ci/requirements/docs.yml
+++ b/ci/requirements/docs.yml
@@ -5,7 +5,7 @@ channels:
   - nodefaults
 
 dependencies:
-  - python=3.11
+  - python=3.12
 # regionmask dependencies
   - cartopy
   - geopandas
diff --git a/regionmask/core/mask.py b/regionmask/core/mask.py
index cf1f85e..eba2571 100644
--- a/regionmask/core/mask.py
+++ b/regionmask/core/mask.py
@@ -204,8 +204,8 @@ def _mask(
                 "be converted to degree?"
             )
 
-    lon_arr = np.asarray(lon)
-    lat_arr = np.asarray(lat)
+    lon_arr = np.asarray(lon, dtype=float)
+    lat_arr = np.asarray(lat, dtype=float)
 
     # automatically detect whether wrapping is necessary
     if wrap_lon is None:
diff --git a/setup.cfg b/setup.cfg
index 32ae80f..acdf717 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -17,6 +17,7 @@ classifiers =
     Programming Language :: Python :: 3.9
     Programming Language :: Python :: 3.10
     Programming Language :: Python :: 3.11
+    Programming Language :: Python :: 3.12
     Topic :: Scientific/Engineering
     Topic :: Scientific/Engineering :: Atmospheric Science
     Topic :: Scientific/Engineering :: GIS


Test patch:
diff --git a/regionmask/tests/test_mask.py b/regionmask/tests/test_mask.py
index 8996f0e..b279a1c 100644
--- a/regionmask/tests/test_mask.py
+++ b/regionmask/tests/test_mask.py
@@ -964,12 +964,29 @@ def test_mask_whole_grid(method, regions, lon):
     mask = regions.mask(lon, lat, method=method)
 
     assert (mask == 0).all()
+    assert mask.lon.dtype == int
+    assert mask.lat.dtype == int
 
     # with wrap_lon=False the edges are not masked
     mask = regions.mask(lon, lat, method=method, wrap_lon=False)
     assert mask.sel(lat=-90).isnull().all()
 
 
+@pytest.mark.parametrize("method", MASK_METHODS)
+@pytest.mark.parametrize("regions", [r_GLOB_180, r_GLOB_360])
+@pytest.mark.parametrize("lon", [lon180, lon360])
+def test_mask_whole_grid_float32(method, regions, lon):
+
+    lat = np.arange(90, -91, -10, dtype=np.float32)
+    lon = lon.astype(np.float32)  # creates a copy
+    mask = regions.mask(lon, lat, method=method)
+
+    assert (mask == 0).all()
+
+    assert mask.lon.dtype == np.float32
+    assert mask.lat.dtype == np.float32
+
+
 @pytest.mark.parametrize("regions", [r_GLOB_180, r_GLOB_360])
 @pytest.mark.parametrize("lon", [lon180, lon360])
 def test_mask_whole_grid_nan_lon(regions, lon):