We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ak.type does not understand `numpy.<type>` style dtypes
### Version of Awkward Array

2.0.0rc1

### Description and code to reproduce

numpy = 1.23.4

```python3
>>> import awkward as ak
>>> import numpy as np
>>> x = np.random.normal(size=100)
>>> ak.type(x)
```
results in:
```
Traceback (most recent call last):
  File "/Users/lgray/miniforge3/envs/coffea-dev/lib/python3.8/site-packages/awkward/operations/ak_type.py", line 99, in _impl
    out = ak.types.numpytype._dtype_to_primitive_dict[array.dtype.type]
KeyError: <class 'numpy.float64'>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/lgray/miniforge3/envs/coffea-dev/lib/python3.8/site-packages/awkward/operations/ak_type.py", line 60, in type
    return _impl(array)
  File "/Users/lgray/miniforge3/envs/coffea-dev/lib/python3.8/site-packages/awkward/operations/ak_type.py", line 101, in _impl
    raise ak._errors.wrap_error(
TypeError: while calling

    ak.type(
        array = numpy.ndarray([ 0.27824033 -1.483569   -0.61108357 ...
    )

Error details: numpy array type is unrecognized by awkward: <class 'numpy.float64'>
```

`np.float64` (or `np.<type>` in general) is a fairly common way for folks to denote typing, we should probably support it.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/awkward/operations/ak_type.py`
Content:
```
1 # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE
2 
3 import numbers
4 
5 import awkward as ak
6 
7 np = ak.nplikes.NumpyMetadata.instance()
8 
9 
10 def type(array):
11     """
12     The high-level type of an `array` (many types supported, including all
13     Awkward Arrays and Records) as #ak.types.Type objects.
14 
15     The high-level type ignores #layout differences like
16     #ak.contents.ListArray versus #ak.contents.ListOffsetArray, but
17     not differences like "regular-sized lists" (i.e.
18     #ak.contents.RegularArray) versus "variable-sized lists" (i.e.
19     #ak.contents.ListArray and similar).
20 
21     Types are rendered as [Datashape](https://datashape.readthedocs.io/)
22     strings, which makes the same distinctions.
23 
24     For example,
25 
26         ak.Array([[{"x": 1.1, "y": [1]}, {"x": 2.2, "y": [2, 2]}],
27                   [],
28                   [{"x": 3.3, "y": [3, 3, 3]}]])
29 
30     has type
31 
32         3 * var * {"x": float64, "y": var * int64}
33 
34     but
35 
36         ak.Array(np.arange(2*3*5).reshape(2, 3, 5))
37 
38     has type
39 
40         2 * 3 * 5 * int64
41 
42     Some cases, like heterogeneous data, require [extensions beyond the
43     Datashape specification](https://github.com/blaze/datashape/issues/237).
44     For example,
45 
46         ak.Array([1, "two", [3, 3, 3]])
47 
48     has type
49 
50         3 * union[int64, string, var * int64]
51 
52     but "union" is not a Datashape type-constructor. (Its syntax is
53     similar to existing type-constructors, so it's a plausible addition
54     to the language.)
55     """
56     with ak._errors.OperationErrorContext(
57         "ak.type",
58         dict(array=array),
59     ):
60         return _impl(array)
61 
62 
63 def _impl(array):
64     if array is None:
65         return ak.types.UnknownType()
66 
67     elif isinstance(
68         array,
69         tuple(x.type for x in ak.types.numpytype._dtype_to_primitive_dict),
70     ):
71         return ak.types.NumpyType(
72             ak.types.numpytype._dtype_to_primitive_dict[array.dtype]
73         )
74 
75     elif isinstance(array, (bool, np.bool_)):
76         return ak.types.NumpyType("bool")
77 
78     elif isinstance(array, numbers.Integral):
79         return ak.types.NumpyType("int64")
80 
81     elif isinstance(array, numbers.Real):
82         return ak.types.NumpyType("float64")
83 
84     elif isinstance(
85         array,
86         (
87             ak.highlevel.Array,
88             ak.highlevel.Record,
89             ak.highlevel.ArrayBuilder,
90         ),
91     ):
92         return array.type
93 
94     elif isinstance(array, np.ndarray):
95         if len(array.shape) == 0:
96             return _impl(array.reshape((1,))[0])
97         else:
98             try:
99                 out = ak.types.numpytype._dtype_to_primitive_dict[array.dtype.type]
100             except KeyError as err:
101                 raise ak._errors.wrap_error(
102                     TypeError(
103                         "numpy array type is unrecognized by awkward: %r"
104                         % array.dtype.type
105                     )
106                 ) from err
107             out = ak.types.NumpyType(out)
108             for x in array.shape[-1:0:-1]:
109                 out = ak.types.RegularType(out, x)
110             return ak.types.ArrayType(out, array.shape[0])
111 
112     elif isinstance(array, ak._ext.ArrayBuilder):
113         form = ak.forms.from_json(array.form())
114         return ak.types.ArrayType(form.type_from_behavior(None), len(array))
115 
116     elif isinstance(array, ak.record.Record):
117         return array.array.form.type
118 
119     elif isinstance(array, ak.contents.Content):
120         return array.form.type
121 
122     else:
123         raise ak._errors.wrap_error(TypeError(f"unrecognized array type: {array!r}"))
124
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/awkward/operations/ak_type.py b/src/awkward/operations/ak_type.py
--- a/src/awkward/operations/ak_type.py
+++ b/src/awkward/operations/ak_type.py
@@ -1,6 +1,8 @@
 # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE
 
+import builtins
 import numbers
+from datetime import datetime, timedelta
 
 import awkward as ak
 
@@ -64,15 +66,18 @@
     if array is None:
         return ak.types.UnknownType()
 
-    elif isinstance(
-        array,
-        tuple(x.type for x in ak.types.numpytype._dtype_to_primitive_dict),
+    elif isinstance(array, np.dtype):
+        return ak.types.NumpyType(ak.types.numpytype.dtype_to_primitive(array))
+
+    elif (
+        isinstance(array, np.generic)
+        or isinstance(array, builtins.type)
+        and issubclass(array, np.generic)
     ):
-        return ak.types.NumpyType(
-            ak.types.numpytype._dtype_to_primitive_dict[array.dtype]
-        )
+        primitive = ak.types.numpytype.dtype_to_primitive(np.dtype(array))
+        return ak.types.NumpyType(primitive)
 
-    elif isinstance(array, (bool, np.bool_)):
+    elif isinstance(array, bool):  # np.bool_ in np.generic (above)
         return ak.types.NumpyType("bool")
 
     elif isinstance(array, numbers.Integral):
@@ -81,6 +86,15 @@
     elif isinstance(array, numbers.Real):
         return ak.types.NumpyType("float64")
 
+    elif isinstance(array, numbers.Complex):
+        return ak.types.NumpyType("complex128")
+
+    elif isinstance(array, datetime):  # np.datetime64 in np.generic (above)
+        return ak.types.NumpyType("datetime64")
+
+    elif isinstance(array, timedelta):  # np.timedelta64 in np.generic (above)
+        return ak.types.NumpyType("timedelta")
+
     elif isinstance(
         array,
         (
@@ -95,16 +109,8 @@
         if len(array.shape) == 0:
             return _impl(array.reshape((1,))[0])
         else:
-            try:
-                out = ak.types.numpytype._dtype_to_primitive_dict[array.dtype.type]
-            except KeyError as err:
-                raise ak._errors.wrap_error(
-                    TypeError(
-                        "numpy array type is unrecognized by awkward: %r"
-                        % array.dtype.type
-                    )
-                ) from err
-            out = ak.types.NumpyType(out)
+            primitive = ak.types.numpytype.dtype_to_primitive(array.dtype)
+            out = ak.types.NumpyType(primitive)
             for x in array.shape[-1:0:-1]:
                 out = ak.types.RegularType(out, x)
             return ak.types.ArrayType(out, array.shape[0])

{"golden_diff": "diff --git a/src/awkward/operations/ak_type.py b/src/awkward/operations/ak_type.py\n--- a/src/awkward/operations/ak_type.py\n+++ b/src/awkward/operations/ak_type.py\n@@ -1,6 +1,8 @@\n # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE\n \n+import builtins\n import numbers\n+from datetime import datetime, timedelta\n \n import awkward as ak\n \n@@ -64,15 +66,18 @@\n     if array is None:\n         return ak.types.UnknownType()\n \n-    elif isinstance(\n-        array,\n-        tuple(x.type for x in ak.types.numpytype._dtype_to_primitive_dict),\n+    elif isinstance(array, np.dtype):\n+        return ak.types.NumpyType(ak.types.numpytype.dtype_to_primitive(array))\n+\n+    elif (\n+        isinstance(array, np.generic)\n+        or isinstance(array, builtins.type)\n+        and issubclass(array, np.generic)\n     ):\n-        return ak.types.NumpyType(\n-            ak.types.numpytype._dtype_to_primitive_dict[array.dtype]\n-        )\n+        primitive = ak.types.numpytype.dtype_to_primitive(np.dtype(array))\n+        return ak.types.NumpyType(primitive)\n \n-    elif isinstance(array, (bool, np.bool_)):\n+    elif isinstance(array, bool):  # np.bool_ in np.generic (above)\n         return ak.types.NumpyType(\"bool\")\n \n     elif isinstance(array, numbers.Integral):\n@@ -81,6 +86,15 @@\n     elif isinstance(array, numbers.Real):\n         return ak.types.NumpyType(\"float64\")\n \n+    elif isinstance(array, numbers.Complex):\n+        return ak.types.NumpyType(\"complex128\")\n+\n+    elif isinstance(array, datetime):  # np.datetime64 in np.generic (above)\n+        return ak.types.NumpyType(\"datetime64\")\n+\n+    elif isinstance(array, timedelta):  # np.timedelta64 in np.generic (above)\n+        return ak.types.NumpyType(\"timedelta\")\n+\n     elif isinstance(\n         array,\n         (\n@@ -95,16 +109,8 @@\n         if len(array.shape) == 0:\n             return _impl(array.reshape((1,))[0])\n         else:\n-            try:\n-                out = ak.types.numpytype._dtype_to_primitive_dict[array.dtype.type]\n-            except KeyError as err:\n-                raise ak._errors.wrap_error(\n-                    TypeError(\n-                        \"numpy array type is unrecognized by awkward: %r\"\n-                        % array.dtype.type\n-                    )\n-                ) from err\n-            out = ak.types.NumpyType(out)\n+            primitive = ak.types.numpytype.dtype_to_primitive(array.dtype)\n+            out = ak.types.NumpyType(primitive)\n             for x in array.shape[-1:0:-1]:\n                 out = ak.types.RegularType(out, x)\n             return ak.types.ArrayType(out, array.shape[0])\n", "issue": "ak.type does not understand `numpy.<type>` style dtypes\n### Version of Awkward Array\n\n2.0.0rc1\n\n### Description and code to reproduce\n\nnumpy = 1.23.4\r\n\r\n```python3\r\n>>> import awkward as ak\r\n>>> import numpy as np\r\n>>> x = np.random.normal(size=100)\r\n>>> ak.type(x)\r\n```\r\nresults in:\r\n```\r\nTraceback (most recent call last):\r\n  File \"/Users/lgray/miniforge3/envs/coffea-dev/lib/python3.8/site-packages/awkward/operations/ak_type.py\", line 99, in _impl\r\n    out = ak.types.numpytype._dtype_to_primitive_dict[array.dtype.type]\r\nKeyError: <class 'numpy.float64'>\r\n\r\nThe above exception was the direct cause of the following exception:\r\n\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/Users/lgray/miniforge3/envs/coffea-dev/lib/python3.8/site-packages/awkward/operations/ak_type.py\", line 60, in type\r\n    return _impl(array)\r\n  File \"/Users/lgray/miniforge3/envs/coffea-dev/lib/python3.8/site-packages/awkward/operations/ak_type.py\", line 101, in _impl\r\n    raise ak._errors.wrap_error(\r\nTypeError: while calling\r\n\r\n    ak.type(\r\n        array = numpy.ndarray([ 0.27824033 -1.483569   -0.61108357 ...\r\n    )\r\n\r\nError details: numpy array type is unrecognized by awkward: <class 'numpy.float64'>\r\n```\r\n\r\n`np.float64` (or `np.<type>` in general) is a fairly common way for folks to denote typing, we should probably support it.\n", "before_files": [{"content": "# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE\n\nimport numbers\n\nimport awkward as ak\n\nnp = ak.nplikes.NumpyMetadata.instance()\n\n\ndef type(array):\n    \"\"\"\n    The high-level type of an `array` (many types supported, including all\n    Awkward Arrays and Records) as #ak.types.Type objects.\n\n    The high-level type ignores #layout differences like\n    #ak.contents.ListArray versus #ak.contents.ListOffsetArray, but\n    not differences like \"regular-sized lists\" (i.e.\n    #ak.contents.RegularArray) versus \"variable-sized lists\" (i.e.\n    #ak.contents.ListArray and similar).\n\n    Types are rendered as [Datashape](https://datashape.readthedocs.io/)\n    strings, which makes the same distinctions.\n\n    For example,\n\n        ak.Array([[{\"x\": 1.1, \"y\": [1]}, {\"x\": 2.2, \"y\": [2, 2]}],\n                  [],\n                  [{\"x\": 3.3, \"y\": [3, 3, 3]}]])\n\n    has type\n\n        3 * var * {\"x\": float64, \"y\": var * int64}\n\n    but\n\n        ak.Array(np.arange(2*3*5).reshape(2, 3, 5))\n\n    has type\n\n        2 * 3 * 5 * int64\n\n    Some cases, like heterogeneous data, require [extensions beyond the\n    Datashape specification](https://github.com/blaze/datashape/issues/237).\n    For example,\n\n        ak.Array([1, \"two\", [3, 3, 3]])\n\n    has type\n\n        3 * union[int64, string, var * int64]\n\n    but \"union\" is not a Datashape type-constructor. (Its syntax is\n    similar to existing type-constructors, so it's a plausible addition\n    to the language.)\n    \"\"\"\n    with ak._errors.OperationErrorContext(\n        \"ak.type\",\n        dict(array=array),\n    ):\n        return _impl(array)\n\n\ndef _impl(array):\n    if array is None:\n        return ak.types.UnknownType()\n\n    elif isinstance(\n        array,\n        tuple(x.type for x in ak.types.numpytype._dtype_to_primitive_dict),\n    ):\n        return ak.types.NumpyType(\n            ak.types.numpytype._dtype_to_primitive_dict[array.dtype]\n        )\n\n    elif isinstance(array, (bool, np.bool_)):\n        return ak.types.NumpyType(\"bool\")\n\n    elif isinstance(array, numbers.Integral):\n        return ak.types.NumpyType(\"int64\")\n\n    elif isinstance(array, numbers.Real):\n        return ak.types.NumpyType(\"float64\")\n\n    elif isinstance(\n        array,\n        (\n            ak.highlevel.Array,\n            ak.highlevel.Record,\n            ak.highlevel.ArrayBuilder,\n        ),\n    ):\n        return array.type\n\n    elif isinstance(array, np.ndarray):\n        if len(array.shape) == 0:\n            return _impl(array.reshape((1,))[0])\n        else:\n            try:\n                out = ak.types.numpytype._dtype_to_primitive_dict[array.dtype.type]\n            except KeyError as err:\n                raise ak._errors.wrap_error(\n                    TypeError(\n                        \"numpy array type is unrecognized by awkward: %r\"\n                        % array.dtype.type\n                    )\n                ) from err\n            out = ak.types.NumpyType(out)\n            for x in array.shape[-1:0:-1]:\n                out = ak.types.RegularType(out, x)\n            return ak.types.ArrayType(out, array.shape[0])\n\n    elif isinstance(array, ak._ext.ArrayBuilder):\n        form = ak.forms.from_json(array.form())\n        return ak.types.ArrayType(form.type_from_behavior(None), len(array))\n\n    elif isinstance(array, ak.record.Record):\n        return array.array.form.type\n\n    elif isinstance(array, ak.contents.Content):\n        return array.form.type\n\n    else:\n        raise ak._errors.wrap_error(TypeError(f\"unrecognized array type: {array!r}\"))\n", "path": "src/awkward/operations/ak_type.py"}], "after_files": [{"content": "# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE\n\nimport builtins\nimport numbers\nfrom datetime import datetime, timedelta\n\nimport awkward as ak\n\nnp = ak.nplikes.NumpyMetadata.instance()\n\n\ndef type(array):\n    \"\"\"\n    The high-level type of an `array` (many types supported, including all\n    Awkward Arrays and Records) as #ak.types.Type objects.\n\n    The high-level type ignores #layout differences like\n    #ak.contents.ListArray versus #ak.contents.ListOffsetArray, but\n    not differences like \"regular-sized lists\" (i.e.\n    #ak.contents.RegularArray) versus \"variable-sized lists\" (i.e.\n    #ak.contents.ListArray and similar).\n\n    Types are rendered as [Datashape](https://datashape.readthedocs.io/)\n    strings, which makes the same distinctions.\n\n    For example,\n\n        ak.Array([[{\"x\": 1.1, \"y\": [1]}, {\"x\": 2.2, \"y\": [2, 2]}],\n                  [],\n                  [{\"x\": 3.3, \"y\": [3, 3, 3]}]])\n\n    has type\n\n        3 * var * {\"x\": float64, \"y\": var * int64}\n\n    but\n\n        ak.Array(np.arange(2*3*5).reshape(2, 3, 5))\n\n    has type\n\n        2 * 3 * 5 * int64\n\n    Some cases, like heterogeneous data, require [extensions beyond the\n    Datashape specification](https://github.com/blaze/datashape/issues/237).\n    For example,\n\n        ak.Array([1, \"two\", [3, 3, 3]])\n\n    has type\n\n        3 * union[int64, string, var * int64]\n\n    but \"union\" is not a Datashape type-constructor. (Its syntax is\n    similar to existing type-constructors, so it's a plausible addition\n    to the language.)\n    \"\"\"\n    with ak._errors.OperationErrorContext(\n        \"ak.type\",\n        dict(array=array),\n    ):\n        return _impl(array)\n\n\ndef _impl(array):\n    if array is None:\n        return ak.types.UnknownType()\n\n    elif isinstance(array, np.dtype):\n        return ak.types.NumpyType(ak.types.numpytype.dtype_to_primitive(array))\n\n    elif (\n        isinstance(array, np.generic)\n        or isinstance(array, builtins.type)\n        and issubclass(array, np.generic)\n    ):\n        primitive = ak.types.numpytype.dtype_to_primitive(np.dtype(array))\n        return ak.types.NumpyType(primitive)\n\n    elif isinstance(array, bool):  # np.bool_ in np.generic (above)\n        return ak.types.NumpyType(\"bool\")\n\n    elif isinstance(array, numbers.Integral):\n        return ak.types.NumpyType(\"int64\")\n\n    elif isinstance(array, numbers.Real):\n        return ak.types.NumpyType(\"float64\")\n\n    elif isinstance(array, numbers.Complex):\n        return ak.types.NumpyType(\"complex128\")\n\n    elif isinstance(array, datetime):  # np.datetime64 in np.generic (above)\n        return ak.types.NumpyType(\"datetime64\")\n\n    elif isinstance(array, timedelta):  # np.timedelta64 in np.generic (above)\n        return ak.types.NumpyType(\"timedelta\")\n\n    elif isinstance(\n        array,\n        (\n            ak.highlevel.Array,\n            ak.highlevel.Record,\n            ak.highlevel.ArrayBuilder,\n        ),\n    ):\n        return array.type\n\n    elif isinstance(array, np.ndarray):\n        if len(array.shape) == 0:\n            return _impl(array.reshape((1,))[0])\n        else:\n            primitive = ak.types.numpytype.dtype_to_primitive(array.dtype)\n            out = ak.types.NumpyType(primitive)\n            for x in array.shape[-1:0:-1]:\n                out = ak.types.RegularType(out, x)\n            return ak.types.ArrayType(out, array.shape[0])\n\n    elif isinstance(array, ak._ext.ArrayBuilder):\n        form = ak.forms.from_json(array.form())\n        return ak.types.ArrayType(form.type_from_behavior(None), len(array))\n\n    elif isinstance(array, ak.record.Record):\n        return array.array.form.type\n\n    elif isinstance(array, ak.contents.Content):\n        return array.form.type\n\n    else:\n        raise ak._errors.wrap_error(TypeError(f\"unrecognized array type: {array!r}\"))\n", "path": "src/awkward/operations/ak_type.py"}]}