prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  `normalize_dtype` excludes big endian types
  ## 🐛 Bug
  ```py
  In [457]: from napari.utils._dtype import get_dtype_limits
  
  In [458]: get_dtype_limits(np.dtype('<u2'))
  Out[458]: (0, 65535)
  
  In [459]: get_dtype_limits(np.dtype('>u2'))
  ---------------------------------------------------------------------------
  TypeError                                 Traceback (most recent call last)
  <ipython-input-459-d109d903c3cf> in <module>
  ----> 1 get_dtype_limits(np.dtype('>u2'))
  
  ~/Dropbox (HMS)/Python/forks/napari/napari/utils/_dtype.py in get_dtype_limits(dtype_spec)
      103         info = np.finfo(dtype)
      104     else:
  --> 105         raise TypeError(f'Unrecognized or non-numeric dtype: {dtype_spec}')
      106     return info.min, info.max
  
  TypeError: Unrecognized or non-numeric dtype: >u2
  
  In [460]: np.iinfo('>u2')
  Out[460]: iinfo(min=0, max=65535, dtype=>u2)
  ```
  
  </issue>
  <code>
  [start of napari/utils/_dtype.py]
  1 from typing import Tuple, Union
  2 
  3 import numpy as np
  4 
  5 _np_uints = {
  6     8: np.uint8,
  7     16: np.uint16,
  8     32: np.uint32,
  9     64: np.uint64,
  10 }
  11 
  12 _np_ints = {
  13     8: np.int8,
  14     16: np.int16,
  15     32: np.int32,
  16     64: np.int64,
  17 }
  18 
  19 _np_floats = {
  20     32: np.float32,
  21     64: np.float64,
  22 }
  23 
  24 _np_complex = {
  25     64: np.complex64,
  26     128: np.complex128,
  27 }
  28 
  29 _np_kinds = {
  30     'uint': _np_uints,
  31     'int': _np_ints,
  32     'float': _np_floats,
  33     'complex': _np_complex,
  34 }
  35 
  36 
  37 def _normalize_str_by_bit_depth(dtype_str, kind):
  38     if not any(str.isdigit(c) for c in dtype_str):  # Python 'int' or 'float'
  39         return np.dtype(kind).type
  40     bit_dict = _np_kinds[kind]
  41     if '128' in dtype_str:
  42         return bit_dict[128]
  43     if '8' in dtype_str:
  44         return bit_dict[8]
  45     if '16' in dtype_str:
  46         return bit_dict[16]
  47     if '32' in dtype_str:
  48         return bit_dict[32]
  49     if '64' in dtype_str:
  50         return bit_dict[64]
  51 
  52 
  53 def normalize_dtype(dtype_spec):
  54     """Return a proper NumPy type given ~any duck array dtype.
  55 
  56     Parameters
  57     ----------
  58     dtype_spec : numpy dtype, numpy type, torch dtype, tensorstore dtype, etc
  59         A type that can be interpreted as a NumPy numeric data type, e.g.
  60         'uint32', np.uint8, torch.float32, etc.
  61 
  62     Returns
  63     -------
  64     dtype : numpy.dtype
  65         The corresponding dtype.
  66 
  67     Notes
  68     -----
  69     half-precision floats are not supported.
  70     """
  71     dtype_str = str(dtype_spec)
  72     if 'uint' in dtype_str:
  73         return _normalize_str_by_bit_depth(dtype_str, 'uint')
  74     if 'int' in dtype_str:
  75         return _normalize_str_by_bit_depth(dtype_str, 'int')
  76     if 'float' in dtype_str:
  77         return _normalize_str_by_bit_depth(dtype_str, 'float')
  78     if 'complex' in dtype_str:
  79         return _normalize_str_by_bit_depth(dtype_str, 'complex')
  80     if 'bool' in dtype_str:
  81         return np.bool_
  82 
  83 
  84 def get_dtype_limits(dtype_spec) -> Tuple[float, float]:
  85     """Return machine limits for numeric types.
  86 
  87     Parameters
  88     ----------
  89     dtype_spec : numpy dtype, numpy type, torch dtype, tensorstore dtype, etc
  90         A type that can be interpreted as a NumPy numeric data type, e.g.
  91         'uint32', np.uint8, torch.float32, etc.
  92 
  93     Returns
  94     -------
  95     limits : tuple
  96         The smallest/largest numbers expressible by the type.
  97     """
  98     dtype = normalize_dtype(dtype_spec)
  99     info: Union[np.iinfo, np.finfo]
  100     if np.issubdtype(dtype, np.integer):
  101         info = np.iinfo(dtype)
  102     elif dtype and np.issubdtype(dtype, np.floating):
  103         info = np.finfo(dtype)
  104     else:
  105         raise TypeError(f'Unrecognized or non-numeric dtype: {dtype_spec}')
  106     return info.min, info.max
  107
  [end of napari/utils/_dtype.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/napari/utils/_dtype.py b/napari/utils/_dtype.py
  --- a/napari/utils/_dtype.py
  +++ b/napari/utils/_dtype.py
  @@ -79,6 +79,11 @@
           return _normalize_str_by_bit_depth(dtype_str, 'complex')
       if 'bool' in dtype_str:
           return np.bool_
  +    # If we don't find one of the named dtypes, return the dtype_spec
  +    # unchanged. This allows NumPy big endian types to work. See
  +    # https://github.com/napari/napari/issues/3421
  +    else:
  +        return dtype_spec
   
   
   def get_dtype_limits(dtype_spec) -> Tuple[float, float]:
  
verification_info: {"golden_diff": "diff --git a/napari/utils/_dtype.py b/napari/utils/_dtype.py\n--- a/napari/utils/_dtype.py\n+++ b/napari/utils/_dtype.py\n@@ -79,6 +79,11 @@\n         return _normalize_str_by_bit_depth(dtype_str, 'complex')\n     if 'bool' in dtype_str:\n         return np.bool_\n+    # If we don't find one of the named dtypes, return the dtype_spec\n+    # unchanged. This allows NumPy big endian types to work. See\n+    # https://github.com/napari/napari/issues/3421\n+    else:\n+        return dtype_spec\n \n \n def get_dtype_limits(dtype_spec) -> Tuple[float, float]:\n", "issue": "`normalize_dtype` excludes big endian types\n## \ud83d\udc1b Bug\r\n```py\r\nIn [457]: from napari.utils._dtype import get_dtype_limits\r\n\r\nIn [458]: get_dtype_limits(np.dtype('<u2'))\r\nOut[458]: (0, 65535)\r\n\r\nIn [459]: get_dtype_limits(np.dtype('>u2'))\r\n---------------------------------------------------------------------------\r\nTypeError                                 Traceback (most recent call last)\r\n<ipython-input-459-d109d903c3cf> in <module>\r\n----> 1 get_dtype_limits(np.dtype('>u2'))\r\n\r\n~/Dropbox (HMS)/Python/forks/napari/napari/utils/_dtype.py in get_dtype_limits(dtype_spec)\r\n    103         info = np.finfo(dtype)\r\n    104     else:\r\n--> 105         raise TypeError(f'Unrecognized or non-numeric dtype: {dtype_spec}')\r\n    106     return info.min, info.max\r\n\r\nTypeError: Unrecognized or non-numeric dtype: >u2\r\n\r\nIn [460]: np.iinfo('>u2')\r\nOut[460]: iinfo(min=0, max=65535, dtype=>u2)\r\n```\n", "before_files": [{"content": "from typing import Tuple, Union\n\nimport numpy as np\n\n_np_uints = {\n    8: np.uint8,\n    16: np.uint16,\n    32: np.uint32,\n    64: np.uint64,\n}\n\n_np_ints = {\n    8: np.int8,\n    16: np.int16,\n    32: np.int32,\n    64: np.int64,\n}\n\n_np_floats = {\n    32: np.float32,\n    64: np.float64,\n}\n\n_np_complex = {\n    64: np.complex64,\n    128: np.complex128,\n}\n\n_np_kinds = {\n    'uint': _np_uints,\n    'int': _np_ints,\n    'float': _np_floats,\n    'complex': _np_complex,\n}\n\n\ndef _normalize_str_by_bit_depth(dtype_str, kind):\n    if not any(str.isdigit(c) for c in dtype_str):  # Python 'int' or 'float'\n        return np.dtype(kind).type\n    bit_dict = _np_kinds[kind]\n    if '128' in dtype_str:\n        return bit_dict[128]\n    if '8' in dtype_str:\n        return bit_dict[8]\n    if '16' in dtype_str:\n        return bit_dict[16]\n    if '32' in dtype_str:\n        return bit_dict[32]\n    if '64' in dtype_str:\n        return bit_dict[64]\n\n\ndef normalize_dtype(dtype_spec):\n    \"\"\"Return a proper NumPy type given ~any duck array dtype.\n\n    Parameters\n    ----------\n    dtype_spec : numpy dtype, numpy type, torch dtype, tensorstore dtype, etc\n        A type that can be interpreted as a NumPy numeric data type, e.g.\n        'uint32', np.uint8, torch.float32, etc.\n\n    Returns\n    -------\n    dtype : numpy.dtype\n        The corresponding dtype.\n\n    Notes\n    -----\n    half-precision floats are not supported.\n    \"\"\"\n    dtype_str = str(dtype_spec)\n    if 'uint' in dtype_str:\n        return _normalize_str_by_bit_depth(dtype_str, 'uint')\n    if 'int' in dtype_str:\n        return _normalize_str_by_bit_depth(dtype_str, 'int')\n    if 'float' in dtype_str:\n        return _normalize_str_by_bit_depth(dtype_str, 'float')\n    if 'complex' in dtype_str:\n        return _normalize_str_by_bit_depth(dtype_str, 'complex')\n    if 'bool' in dtype_str:\n        return np.bool_\n\n\ndef get_dtype_limits(dtype_spec) -> Tuple[float, float]:\n    \"\"\"Return machine limits for numeric types.\n\n    Parameters\n    ----------\n    dtype_spec : numpy dtype, numpy type, torch dtype, tensorstore dtype, etc\n        A type that can be interpreted as a NumPy numeric data type, e.g.\n        'uint32', np.uint8, torch.float32, etc.\n\n    Returns\n    -------\n    limits : tuple\n        The smallest/largest numbers expressible by the type.\n    \"\"\"\n    dtype = normalize_dtype(dtype_spec)\n    info: Union[np.iinfo, np.finfo]\n    if np.issubdtype(dtype, np.integer):\n        info = np.iinfo(dtype)\n    elif dtype and np.issubdtype(dtype, np.floating):\n        info = np.finfo(dtype)\n    else:\n        raise TypeError(f'Unrecognized or non-numeric dtype: {dtype_spec}')\n    return info.min, info.max\n", "path": "napari/utils/_dtype.py"}]}