prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Detection of Jax Arrays Breaks on Jax=0.4.*
  The detection for jax arrays here https://github.com/aimhubio/aim/blob/285a09fefbf25d418e00bc305e9a1357d6343d3c/aim/sdk/num_utils.py#L66 is broken in Jax 0.4.* since `DeviceArray` was renamed to `Array`. The simple fix to support the prior/current version would be to check for either `DeviceArray` or `Array`
  
  </issue>
  <code>
  [start of aim/sdk/num_utils.py]
  1 def get_inst_type_str(inst):
  2     """
  3     Get instance type and class type full names
  4     """
  5     obj_name = obj_module = obj_cls_name = obj_cls_module = ''
  6 
  7     if hasattr(inst, '__name__'):
  8         obj_name = inst.__name__
  9     if hasattr(inst, '__module__'):
  10         obj_module = inst.__module__
  11     if hasattr(inst, '__class__'):
  12         if hasattr(inst.__class__, '__name__'):
  13             obj_cls_name = inst.__class__.__name__
  14         if hasattr(inst.__class__, '__module__'):
  15             obj_cls_module = inst.__class__.__module__
  16 
  17     obj_full = '{}.{}'.format(obj_name, obj_module)
  18     obj_cls_full = '{}.{}'.format(obj_cls_name, obj_cls_module)
  19 
  20     return obj_full, obj_cls_full
  21 
  22 
  23 def get_inst_base_types(inst):
  24     """
  25     Get instance and it's base classes types
  26     """
  27     bases_types = []
  28     for b in inst.__class__.__bases__:
  29         b_type, b_cls_type = get_inst_type_str(b)
  30         bases_types.append(b_type)
  31         bases_types.append(b_cls_type)
  32     return bases_types
  33 
  34 
  35 def inst_has_typename(inst, types):
  36     """
  37     Return `True` if the instance is created from class
  38     which has base that matches passed `types`
  39     """
  40     inst_type, inst_cls_type = get_inst_type_str(inst)
  41     inst_types = [inst_type, inst_cls_type] + get_inst_base_types(inst)
  42 
  43     for i in inst_types:
  44         found = True
  45         for t in types:
  46             if i.find(t) == -1:
  47                 found = False
  48                 break
  49         if found:
  50             return True
  51 
  52     return False
  53 
  54 
  55 def is_pytorch_tensor(inst):
  56     """
  57     Check whether `inst` is instance of pytorch tensor
  58     """
  59     return inst_has_typename(inst, ['torch', 'Tensor'])
  60 
  61 
  62 def is_tf_tensor(inst):
  63     return inst_has_typename(inst, ['tensorflow', 'Tensor'])
  64 
  65 
  66 def is_jax_device_array(inst):
  67     """
  68     Check whether `inst` is instance of jax device array
  69     """
  70     return inst_has_typename(inst, ['jaxlib', 'xla_extension', 'DeviceArray'])
  71 
  72 
  73 def is_numpy_array(inst):
  74     """
  75     Check whether `inst` is instance of numpy array
  76     """
  77     return inst_has_typename(inst, ['numpy', 'ndarray'])
  78 
  79 
  80 def is_numpy_number(inst):
  81     """
  82     Check whether `inst` is numpy number
  83     """
  84 
  85     return inst_has_typename(inst, ['numpy'])
  86 
  87 
  88 def is_py_number(value):
  89     return isinstance(value, (int, float))
  90 
  91 
  92 def is_number(value):
  93     """
  94     Checks if the given value is a number
  95     """
  96     if is_py_number(value):
  97         return True
  98 
  99     if is_numpy_array(value):
  100         return True
  101 
  102     if is_numpy_number(value):
  103         return True
  104 
  105     if is_jax_device_array(value):
  106         return True
  107 
  108     if is_pytorch_tensor(value):
  109         return True
  110 
  111     if is_tf_tensor(value):
  112         return True
  113 
  114     return False
  115 
  116 
  117 def convert_to_py_number(value) -> object:
  118     """
  119     Converts numpy objects or tensors to python number types
  120     """
  121     if isinstance(value, int):
  122         return int(value)
  123 
  124     if isinstance(value, float):
  125         return float(value)
  126 
  127     if is_numpy_array(value):
  128         return value.item()
  129 
  130     if is_numpy_number(value):
  131         return value.item()
  132 
  133     if is_jax_device_array(value):
  134         return value.item()
  135 
  136     if is_pytorch_tensor(value):
  137         return value.item()
  138 
  139     if is_tf_tensor(value):
  140         return value.numpy().item()
  141 
  142     raise ValueError('not a number')
  143
  [end of aim/sdk/num_utils.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/aim/sdk/num_utils.py b/aim/sdk/num_utils.py
  --- a/aim/sdk/num_utils.py
  +++ b/aim/sdk/num_utils.py
  @@ -67,7 +67,11 @@
       """
       Check whether `inst` is instance of jax device array
       """
  -    return inst_has_typename(inst, ['jaxlib', 'xla_extension', 'DeviceArray'])
  +    if inst_has_typename(inst, ['jaxlib', 'xla_extension', 'Array']):
  +        return True
  +    if inst_has_typename(inst, ['jaxlib', 'xla_extension', 'DeviceArray']):
  +        return True
  +    return False
   
   
   def is_numpy_array(inst):
  
verification_info: {"golden_diff": "diff --git a/aim/sdk/num_utils.py b/aim/sdk/num_utils.py\n--- a/aim/sdk/num_utils.py\n+++ b/aim/sdk/num_utils.py\n@@ -67,7 +67,11 @@\n     \"\"\"\n     Check whether `inst` is instance of jax device array\n     \"\"\"\n-    return inst_has_typename(inst, ['jaxlib', 'xla_extension', 'DeviceArray'])\n+    if inst_has_typename(inst, ['jaxlib', 'xla_extension', 'Array']):\n+        return True\n+    if inst_has_typename(inst, ['jaxlib', 'xla_extension', 'DeviceArray']):\n+        return True\n+    return False\n \n \n def is_numpy_array(inst):\n", "issue": "Detection of Jax Arrays Breaks on Jax=0.4.*\nThe detection for jax arrays here https://github.com/aimhubio/aim/blob/285a09fefbf25d418e00bc305e9a1357d6343d3c/aim/sdk/num_utils.py#L66 is broken in Jax 0.4.* since `DeviceArray` was renamed to `Array`. The simple fix to support the prior/current version would be to check for either `DeviceArray` or `Array`\n", "before_files": [{"content": "def get_inst_type_str(inst):\n    \"\"\"\n    Get instance type and class type full names\n    \"\"\"\n    obj_name = obj_module = obj_cls_name = obj_cls_module = ''\n\n    if hasattr(inst, '__name__'):\n        obj_name = inst.__name__\n    if hasattr(inst, '__module__'):\n        obj_module = inst.__module__\n    if hasattr(inst, '__class__'):\n        if hasattr(inst.__class__, '__name__'):\n            obj_cls_name = inst.__class__.__name__\n        if hasattr(inst.__class__, '__module__'):\n            obj_cls_module = inst.__class__.__module__\n\n    obj_full = '{}.{}'.format(obj_name, obj_module)\n    obj_cls_full = '{}.{}'.format(obj_cls_name, obj_cls_module)\n\n    return obj_full, obj_cls_full\n\n\ndef get_inst_base_types(inst):\n    \"\"\"\n    Get instance and it's base classes types\n    \"\"\"\n    bases_types = []\n    for b in inst.__class__.__bases__:\n        b_type, b_cls_type = get_inst_type_str(b)\n        bases_types.append(b_type)\n        bases_types.append(b_cls_type)\n    return bases_types\n\n\ndef inst_has_typename(inst, types):\n    \"\"\"\n    Return `True` if the instance is created from class\n    which has base that matches passed `types`\n    \"\"\"\n    inst_type, inst_cls_type = get_inst_type_str(inst)\n    inst_types = [inst_type, inst_cls_type] + get_inst_base_types(inst)\n\n    for i in inst_types:\n        found = True\n        for t in types:\n            if i.find(t) == -1:\n                found = False\n                break\n        if found:\n            return True\n\n    return False\n\n\ndef is_pytorch_tensor(inst):\n    \"\"\"\n    Check whether `inst` is instance of pytorch tensor\n    \"\"\"\n    return inst_has_typename(inst, ['torch', 'Tensor'])\n\n\ndef is_tf_tensor(inst):\n    return inst_has_typename(inst, ['tensorflow', 'Tensor'])\n\n\ndef is_jax_device_array(inst):\n    \"\"\"\n    Check whether `inst` is instance of jax device array\n    \"\"\"\n    return inst_has_typename(inst, ['jaxlib', 'xla_extension', 'DeviceArray'])\n\n\ndef is_numpy_array(inst):\n    \"\"\"\n    Check whether `inst` is instance of numpy array\n    \"\"\"\n    return inst_has_typename(inst, ['numpy', 'ndarray'])\n\n\ndef is_numpy_number(inst):\n    \"\"\"\n    Check whether `inst` is numpy number\n    \"\"\"\n\n    return inst_has_typename(inst, ['numpy'])\n\n\ndef is_py_number(value):\n    return isinstance(value, (int, float))\n\n\ndef is_number(value):\n    \"\"\"\n    Checks if the given value is a number\n    \"\"\"\n    if is_py_number(value):\n        return True\n\n    if is_numpy_array(value):\n        return True\n\n    if is_numpy_number(value):\n        return True\n\n    if is_jax_device_array(value):\n        return True\n\n    if is_pytorch_tensor(value):\n        return True\n\n    if is_tf_tensor(value):\n        return True\n\n    return False\n\n\ndef convert_to_py_number(value) -> object:\n    \"\"\"\n    Converts numpy objects or tensors to python number types\n    \"\"\"\n    if isinstance(value, int):\n        return int(value)\n\n    if isinstance(value, float):\n        return float(value)\n\n    if is_numpy_array(value):\n        return value.item()\n\n    if is_numpy_number(value):\n        return value.item()\n\n    if is_jax_device_array(value):\n        return value.item()\n\n    if is_pytorch_tensor(value):\n        return value.item()\n\n    if is_tf_tensor(value):\n        return value.numpy().item()\n\n    raise ValueError('not a number')\n", "path": "aim/sdk/num_utils.py"}]}