Repository: openradar/xradar

Issue:
Deprecated ruff call in CI ?
* xradar version: 0.5.0
* Python version: -
* Operating System: -

### Description

CI of xradar uses ruff in the following way

     ruff .

But this leads to error

     error: `ruff <path>` has been removed. Use `ruff check <path>` instead.
     Error: Process completed with exit code 1.

### What I Did

Submitted a PR


Discussion:
review-notebook-app[bot]: Check out this pull request on&nbsp; <a href="https://app.reviewnb.com/openradar/xradar/pull/177"><img align="absmiddle"  alt="ReviewNB" height="28" class="BotMessageButtonImage" src="https://raw.githubusercontent.com/ReviewNB/support/master/images/button_reviewnb.png"/></a> 

 See visual diffs & provide feedback on Jupyter Notebooks. 

---

 <i>Powered by <a href='https://www.reviewnb.com/?utm_source=gh'>ReviewNB</a></i>
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/openradar/xradar/pull/177?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 89.59%. Comparing base [(`5ed1f43`)](https://app.codecov.io/gh/openradar/xradar/commit/5ed1f43e821fdd12095b2f65e7eac5529a3458ce?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar) to head [(`dd1b62a`)](https://app.codecov.io/gh/openradar/xradar/commit/dd1b62a012515fcacf72ad19860d431fa3588159?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #177      +/-   ##
==========================================
- Coverage   91.32%   89.59%   -1.73%     
==========================================
  Files          21       21              
  Lines        4010     3990      -20     
==========================================
- Hits         3662     3575      -87     
- Misses        348      415      +67     
```

| [Flag](https://app.codecov.io/gh/openradar/xradar/pull/177/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar) | Coverage Δ | |
|---|---|---|
| [notebooktests](https://app.codecov.io/gh/openradar/xradar/pull/177/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar) | `?` | |
| [unittests](https://app.codecov.io/gh/openradar/xradar/pull/177/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar) | `89.59% <100.00%> (-0.06%)` | :arrow_down: |

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=openradar#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/openradar/xradar/pull/177?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=openradar).

kmuehlbauer: Thanks @mgrover1! I've fixed the remaining issues and will merge to unlock #175. 

Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d1a621e..f8c6dcc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,7 +27,7 @@ jobs:
           black --check .
       - name: Lint with ruff
         run: |
-          ruff .
+          ruff check .
 
   build_0:
     name: xradar unit tests - linux
@@ -42,6 +42,7 @@ jobs:
       fail-fast: false
       matrix:
         python-version: ["3.10", "3.11", "3.12"]
+        numpy-version: ["1", "2"]
     steps:
     - uses: actions/checkout@v4
       with:
@@ -55,6 +56,7 @@ jobs:
           cache-environment-key: "${{runner.os}}-${{runner.arch}}-py${{env.PYTHON_VERSION}}-${{env.TODAY}}-${{hashFiles(env.CONDA_ENV_FILE)}}"
           create-args: >-
               python=${{matrix.python-version}}
+              numpy=${{matrix.numpy-version}}
               conda
     - name: Install xradar
       run: |
@@ -88,6 +90,7 @@ jobs:
       fail-fast: false
       matrix:
         python-version: ["3.10", "3.11", "3.12"]
+        numpy-version: ["1", "2"]
     steps:
     - uses: actions/checkout@v4
       with:
@@ -101,6 +104,7 @@ jobs:
           cache-environment-key: "${{runner.os}}-${{runner.arch}}-py${{env.PYTHON_VERSION}}-${{env.TODAY}}-${{hashFiles(env.CONDA_ENV_FILE)}}"
           create-args: >-
               python=${{matrix.python-version}}
+              numpy=${{matrix.numpy-version}}
               conda
     - name: Install xradar
       run: |
diff --git a/docs/history.md b/docs/history.md
index 5c554d4..065b96d 100644
--- a/docs/history.md
+++ b/docs/history.md
@@ -1,9 +1,9 @@
 # History
 
 ## Development Version (unreleased)
-
-* ADD: Add Alfonso to citation doc ({pull}`169`) by [@mgrover1](https://github.com/mgrover1)
-* ENH: Adding global variables and attributes to iris datatree ({pull}`166`) by [@aladinor](https://github.com/aladinor)
+* FIX: Fix use of ruff, CI and numpy2 ({pull}`177`) by [@mgrover1](https://github.com/mgrover1) and [@kmuehlbauer](https://github.com/kmuehlbauer).
+* ADD: Add Alfonso to citation doc ({pull}`169`) by [@mgrover1](https://github.com/mgrover1).
+* ENH: Adding global variables and attributes to iris datatree ({pull}`166`) by [@aladinor](https://github.com/aladinor).
 * FIX: Set fillvalue before applying scale/offset when exporting to odim ({issue}`122`) by [@pavlikp](https://github.com/pavlikp), ({pull}`173`) by [@kmuehlbauer](https://github.com/kmuehlbauer).
 
 ## 0.5.0 (2024-03-28)
diff --git a/examples/notebooks/NexradLevel2.ipynb b/examples/notebooks/NexradLevel2.ipynb
index a4cd1cb..d17b353 100644
--- a/examples/notebooks/NexradLevel2.ipynb
+++ b/examples/notebooks/NexradLevel2.ipynb
@@ -38,13 +38,23 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "filename = DATASETS.fetch(\"KLBB20160601_150025_V06\")"
+    "filename = \"../../../../Downloads/KDMX20200810_154746_V06\""
    ]
   },
   {
-   "cell_type": "markdown",
+   "cell_type": "code",
+   "execution_count": null,
    "id": "4",
    "metadata": {},
+   "outputs": [],
+   "source": [
+    "filename = DATASETS.fetch(\"KATX20130717_195021_V06\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5",
+   "metadata": {},
    "source": [
     "## xr.open_dataset\n",
     "\n",
@@ -54,7 +64,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "5",
+   "id": "6",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -62,9 +72,31 @@
     "display(ds)"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "\n",
+    "np.testing.assert_almost_equal(ds.sweep_fixed_angle.values, 0.4833984)"
+   ]
+  },
   {
    "cell_type": "markdown",
-   "id": "6",
+   "id": "9",
    "metadata": {},
    "source": [
     "### Plot Time vs. Azimuth"
@@ -73,7 +105,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "7",
+   "id": "10",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -82,7 +114,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "8",
+   "id": "11",
    "metadata": {},
    "source": [
     "### Plot Range vs. Time\n",
@@ -93,7 +125,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "9",
+   "id": "12",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -102,7 +134,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "10",
+   "id": "13",
    "metadata": {},
    "source": [
     "### Plot Range vs. Azimuth\n"
@@ -111,7 +143,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "11",
+   "id": "14",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -120,7 +152,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "12",
+   "id": "15",
    "metadata": {},
    "source": [
     "## backend_kwargs\n",
@@ -131,7 +163,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "13",
+   "id": "16",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -141,7 +173,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "14",
+   "id": "17",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -151,7 +183,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "15",
+   "id": "18",
    "metadata": {},
    "source": [
     "## open_nexradlevel2_datatree\n",
@@ -162,7 +194,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "16",
+   "id": "19",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -172,7 +204,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "17",
+   "id": "20",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -182,7 +214,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "18",
+   "id": "21",
    "metadata": {},
    "source": [
     "### Plot Sweep Range vs. Time"
@@ -191,7 +223,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "19",
+   "id": "22",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -200,7 +232,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "20",
+   "id": "23",
    "metadata": {},
    "source": [
     "### Plot Sweep Range vs. Azimuth"
@@ -209,7 +241,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "21",
+   "id": "24",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -219,7 +251,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "22",
+   "id": "25",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -230,7 +262,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "23",
+   "id": "26",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -241,15 +273,53 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "24",
+   "id": "27",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "dtree[\"sweep_0\"][\"sweep_fixed_angle\"].values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "28",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "dtree[\"sweep_1\"][\"sweep_fixed_angle\"].values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "29",
    "metadata": {},
    "outputs": [],
    "source": [
     "dtree = xd.io.open_nexradlevel2_datatree(\n",
-    "    filename, sweep=[\"sweep_1\", \"sweep_2\", \"sweep_8\"]\n",
+    "    filename,\n",
     ")\n",
     "display(dtree)"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "30",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "dtree[\"sweep_1\"]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "31",
+   "metadata": {},
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
@@ -263,7 +333,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.5"
+   "version": "3.11.4"
   }
  },
  "nbformat": 4,
diff --git a/examples/notebooks/ODIM_H5.ipynb b/examples/notebooks/ODIM_H5.ipynb
index 64e36a9..3a7a750 100644
--- a/examples/notebooks/ODIM_H5.ipynb
+++ b/examples/notebooks/ODIM_H5.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "59447ad6-ac47-494e-b696-4335b36b205b",
+   "id": "0",
    "metadata": {},
    "source": [
     "# ODIM_H5"
@@ -11,7 +11,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "6f96b5d8-2b96-4fd7-b8ba-166c34a8dcd2",
+   "id": "1",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -22,7 +22,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "33d50be4-dfe5-4d99-a936-67a9a76bac94",
+   "id": "2",
    "metadata": {},
    "source": [
     "## Download\n",
@@ -33,7 +33,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "d3c6d408-5ab2-43c3-afd1-b3a703ef3b24",
+   "id": "3",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -42,7 +42,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "b987dcfd-5105-4483-932e-71b8002e5f09",
+   "id": "4",
    "metadata": {},
    "source": [
     "## xr.open_dataset\n",
@@ -53,7 +53,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "7675b518-18e4-4ea6-b101-f1bccf603902",
+   "id": "5",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -61,9 +61,19 @@
     "display(ds)"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ds.sweep_fixed_angle.values"
+   ]
+  },
   {
    "cell_type": "markdown",
-   "id": "01ec8c90-2da8-46ae-a0b5-0e1792a79bbe",
+   "id": "7",
    "metadata": {},
    "source": [
     "### Plot Time vs. Azimuth"
@@ -72,7 +82,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "24dfb5f8-de27-46f0-9246-722e5955a345",
+   "id": "8",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -81,7 +91,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "222ca704-d6e1-49e6-84a0-de55df9fdf61",
+   "id": "9",
    "metadata": {},
    "source": [
     "### Plot Range vs. Time"
@@ -90,7 +100,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "34429720-e689-4786-99e3-5af9742d19ad",
+   "id": "10",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -99,7 +109,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "d904cd09-8590-42e2-8dce-41d3949d313c",
+   "id": "11",
    "metadata": {},
    "source": [
     "### Plot Range vs. Azimuth\n",
@@ -110,7 +120,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "6479a374-25ab-42be-b53e-82849b6faffc",
+   "id": "12",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -119,7 +129,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "5deafdf1-9224-459c-8b10-7c501ae13234",
+   "id": "13",
    "metadata": {},
    "source": [
     "## backend_kwargs\n",
@@ -130,7 +140,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "08f12b48-a3b5-43b7-b9a1-87afa9002fb9",
+   "id": "14",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -140,7 +150,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "dd052e96-9666-40ff-8b9b-3723daf68c32",
+   "id": "15",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -150,7 +160,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "9a09378a-11d9-414f-bc23-0b6f01017d12",
+   "id": "16",
    "metadata": {},
    "source": [
     "## open_odim_datatree\n",
@@ -161,7 +171,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "e8485006-ca89-4409-82ab-29ae8f93004a",
+   "id": "17",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -171,7 +181,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "a65f0b48-7197-4f79-bc26-2045cfc59a4a",
+   "id": "18",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -181,7 +191,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "638bc6c0-3293-4661-a5d5-e9aaad14ffe9",
+   "id": "19",
    "metadata": {},
    "source": [
     "### Plot Sweep Range vs. Time"
@@ -190,7 +200,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "f9db8500-7072-451b-84a1-f36767110e16",
+   "id": "20",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -199,7 +209,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "1e44c0fd-02bc-4d2d-ac91-772bdcebe04b",
+   "id": "21",
    "metadata": {},
    "source": [
     "### Plot Sweep Range vs. Azimuth"
@@ -208,7 +218,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "c7aab6b3-aeb0-4ed1-8397-8b505e63464a",
+   "id": "22",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -218,7 +228,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "9dc09b53-7e2a-4fb6-9b28-a3ae3fd95bd0",
+   "id": "23",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -229,7 +239,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "41976524-fca8-4569-8b37-867d2214709c",
+   "id": "24",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -240,7 +250,7 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "c4239ebf-f16d-42ee-8f03-a38ecbc04cee",
+   "id": "25",
    "metadata": {},
    "outputs": [],
    "source": [
@@ -260,7 +270,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.6"
+   "version": "3.11.4"
   }
  },
  "nbformat": 4,
diff --git a/xradar/io/backends/iris.py b/xradar/io/backends/iris.py
index f5e78ad..4e82462 100644
--- a/xradar/io/backends/iris.py
+++ b/xradar/io/backends/iris.py
@@ -179,6 +179,9 @@ def decode_array(data, scale=1.0, offset=0, offset2=0, tofloat=False, mask=None)
         data = to_float(data)
     if mask is not None:
         data = np.ma.masked_equal(data, mask)
+    # numpy 2 changed casting rules
+    # so we need to cast to float beforehand
+    data = data.astype(np.float64)
     return (data + offset) / scale + offset2
 
 
@@ -3338,7 +3341,8 @@ class IrisRawFile(IrisRecordFile, IrisIngestHeader):
         cmp_val = self.read_from_record(1, "int16")[0]
         cmp_msb = np.sign(cmp_val) == -1
         if cmp_msb:
-            cmp_val = cmp_val + 32768
+            # prevent OverflowError in numpy 2
+            cmp_val = cmp_val + 32767 + 1
         if self._debug:
             print(
                 "--- Sub CMP Code:",
@@ -3959,9 +3963,7 @@ def _get_iris_group_names(filename):
 def _get_required_root_dataset(ls_ds, optional=True):
     """Extract Root Dataset."""
     # keep only defined mandatory and defined optional variables per default
-    data_var = set(
-        [x for xs in [sweep.variables.keys() for sweep in ls_ds] for x in xs]
-    )
+    data_var = {x for xs in [sweep.variables.keys() for sweep in ls_ds] for x in xs}
     remove_root = set(data_var) ^ set(required_root_vars)
     if optional:
         remove_root ^= set(optional_root_vars)
@@ -3972,9 +3974,7 @@ def _get_required_root_dataset(ls_ds, optional=True):
     }
     remove_root &= data_var
     root = [sweep.drop_vars(remove_root) for sweep in ls_ds]
-    root_vars = set(
-        [x for xs in [sweep.variables.keys() for sweep in root] for x in xs]
-    )
+    root_vars = {x for xs in [sweep.variables.keys() for sweep in root] for x in xs}
     # rename variables
     # todo: find a more easy method not iterating over all variables
     for k in root_vars:
@@ -3982,9 +3982,7 @@ def _get_required_root_dataset(ls_ds, optional=True):
         if rename:
             root = [sweep.rename_vars({k: rename}) for sweep in root]
 
-    root_vars = set(
-        [x for xs in [sweep.variables.keys() for sweep in root] for x in xs]
-    )
+    root_vars = {x for xs in [sweep.variables.keys() for sweep in root] for x in xs}
     ds_vars = [sweep[root_vars] for sweep in ls_ds]
 
     root = xr.concat(ds_vars, dim="sweep").reset_coords()
@@ -4010,7 +4008,7 @@ def _get_subgroup(ls_ds: list[xr.Dataset], subdict):
     Variables are fetched from the provided Dataset according to the subdict dictionary.
     """
     meta_vars = subdict
-    data_vars = set([x for xs in [ds.variables.keys() for ds in ls_ds] for x in xs])
+    data_vars = {x for xs in [ds.variables.keys() for ds in ls_ds] for x in xs}
     extract_vars = set(data_vars) & set(meta_vars)
     subgroup = xr.concat([ds[extract_vars] for ds in ls_ds], "sweep")
     for k in subgroup.data_vars:
diff --git a/xradar/io/backends/rainbow.py b/xradar/io/backends/rainbow.py
index 7e3cb99..2630e25 100644
--- a/xradar/io/backends/rainbow.py
+++ b/xradar/io/backends/rainbow.py
@@ -519,7 +519,7 @@ class RainbowFile(RainbowFileBase):
         if value is None:
             value = self.pargroup.get(name, default)
         if dtype is not None:
-            if dtype == bool:
+            if dtype is bool:
                 value = int(value)
             value = dtype(value)
         return value


Test patch:
diff --git a/examples/notebooks/conftest.py b/examples/notebooks/conftest.py
index c21755a..0e4369c 100644
--- a/examples/notebooks/conftest.py
+++ b/examples/notebooks/conftest.py
@@ -75,7 +75,7 @@ class NotebookItem(pytest.Item):
         return super().repr_failure(excinfo)
 
     def reportinfo(self):
-        return self.path, 0, "TestCase: %s" % self.name
+        return self.path, 0, f"TestCase: {self.name}"
 
 
 class NotebookException(Exception):
diff --git a/tests/io/test_io.py b/tests/io/test_io.py
index 7c151b9..6db703a 100644
--- a/tests/io/test_io.py
+++ b/tests/io/test_io.py
@@ -742,7 +742,7 @@ def test_odim_optional_how(odim_file2):
     ds = h5py.File(outfile)
 
     for i in range(1, 6):
-        ds_how = ds["dataset%s" % (i)]["how"].attrs
+        ds_how = ds[f"dataset{i}"]["how"].attrs
         assert "scan_index" in ds_how
         assert "scan_count" in ds_how
         assert "startazA" in ds_how
@@ -762,7 +762,7 @@ def test_odim_optional_how(odim_file2):
     ds = h5py.File(outfile)
 
     for i in range(1, 6):
-        ds_how = ds["dataset%s" % (i)]["how"].attrs
+        ds_how = ds[f"dataset{i}"]["how"].attrs
         assert "scan_index" not in ds_how
         assert "scan_count" not in ds_how
         assert "startazA" not in ds_how