Repository: GenericMappingTools/pygmt

Issue:
No validation that 'unit' and 'scaling' aren't both set for grdproject.py
### Description of the problem

The documentation for `grdproject.py` states that `unit` and `scaling` cannot both be set. I noticed there was no internal check to make sure both aren't present.  I wrote a test for it, but I'm not getting any errors when I run it with both `scaling` and `unit` set.

```
def test_grdproject_unit_scaling(grid):
    with GMTTempFile(suffix=".nc") as tmpfile:
        result = grdproject(
                grid=grid,
                projection="M10c",
                outgrid=tmpfile.name,
                spacing=3,
                unit="i",
                region=[-53, -51, -20, -17],
                )
        assert result is None  # return value is None
        assert Path(tmpfile.name).stat().st_size > 0  # check that outgrid exists

```

Is the docstring incorrect, or am I missing issues with both of these units set.

### Minimal Complete Verifiable Example

```python
if kwargs.get("M", unit) and kwargs.get("F", scaling):
        raise GMTInvalidInput("Cannot use both 'unit' and 'scaling'.")
```

### Full error message

```python-traceback

```

### System information

```bash
PyGMT information:
  version: v0.3.0.dev2627+g8d5b10ba5
System information:
  python: 3.14.2 | packaged by conda-forge | (main, Dec  6 2025, 11:21:58) [GCC 14.3.0]
  executable: /envs/pygmt/bin/python
  machine: Linux-6.17.12-300.fc43.x86_64-x86_64-with-glibc2.42
Dependency information:
  numpy: 2.4.0
  pandas: 2.3.3
  xarray: 2025.12.0
  packaging: 25.0
  contextily: 1.7.0
  geopandas: 1.1.2
  IPython: 9.8.0
  pyarrow: 22.0.0
  rioxarray: 0.20.0
  gdal: 3.12.1
  ghostscript: 10.06.0
GMT library information:
  version: 6.6.0
  padding: 2
  share dir: /envs/pygmt/share/gmt
  plugin dir: /envs/pygmt/lib/gmt/plugins
  library path: /envs/pygmt/lib/libgmt.so
  cores: 8
  grid layout: rows
  image layout: 
  binary version: 6.6.0

```

Discussion hints:

Solution patch:
diff --git a/pygmt/src/grdproject.py b/pygmt/src/grdproject.py
index 13eb49856be..de8fd12c8a5 100644
--- a/pygmt/src/grdproject.py
+++ b/pygmt/src/grdproject.py
@@ -120,6 +120,10 @@ def grdproject(  # noqa: PLR0913
         msg = "Parameter 'projection' must be specified."
         raise GMTInvalidInput(msg)
 
+    if kwargs.get("M", unit) is not None and kwargs.get("F", scaling) is not False:
+        msg = "Cannot use both 'unit' and 'scaling'."
+        raise GMTInvalidInput(msg)
+
     aliasdict = AliasSystem(
         C=Alias(center, name="center", sep="/", size=2),
         D=Alias(spacing, name="spacing", sep="/", size=2),


Test patch:
diff --git a/pygmt/tests/test_grdproject.py b/pygmt/tests/test_grdproject.py
index 8d4a1f70a21..8a5560448c5 100644
--- a/pygmt/tests/test_grdproject.py
+++ b/pygmt/tests/test_grdproject.py
@@ -81,6 +81,22 @@ def test_grdproject_no_outgrid(grid, projection, expected_grid):
     xr.testing.assert_allclose(a=result, b=expected_grid)
 
 
+def test_grdproject_unit_scaling(grid):
+    """
+    Test that the input validation to prevent passing both 'unit' and
+    'scaling' is performed.
+    """
+    with pytest.raises(GMTInvalidInput):
+        grdproject(
+            grid=grid,
+            projection="M10c",
+            spacing=3,
+            unit="i",
+            scaling="k",
+            region=[-53, -51, -20, -17],
+        )
+
+
 def test_grdproject_fails(grid):
     """
     Check that grdproject fails correctly.