From 1e5ee839342974f59a9c7eeafe8b4a3822911d05 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 20:38:38 -0700
Subject: [PATCH 01/33] Add namespace inspection utilities

---
 spec/draft/API_specification/inspection.rst |  22 +++
 src/array_api_stubs/_draft/__init__.py      |   1 +
 src/array_api_stubs/_draft/_types.py        |  33 +++++
 src/array_api_stubs/_draft/inspection.py    | 141 ++++++++++++++++++++
 4 files changed, 197 insertions(+)
 create mode 100644 spec/draft/API_specification/inspection.rst
 create mode 100644 src/array_api_stubs/_draft/inspection.py

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
new file mode 100644
index 000000000..ceb01fd94
--- /dev/null
+++ b/spec/draft/API_specification/inspection.rst
@@ -0,0 +1,22 @@
+Inspection
+==========
+
+    Array API specification for namespace inspection utilities.
+
+A conforming implementation of the array API standard must provide and support the following functions.
+
+
+Objects in API
+--------------
+
+.. currentmodule:: array_api
+
+..
+  NOTE: please keep the functions in alphabetical order
+
+.. autosummary::
+   :toctree: generated
+   :template: attribute.rst
+   :nosignatures:
+
+   __array_namespace_info__
diff --git a/src/array_api_stubs/_draft/__init__.py b/src/array_api_stubs/_draft/__init__.py
index 12b6d9fbb..5280ce7f2 100644
--- a/src/array_api_stubs/_draft/__init__.py
+++ b/src/array_api_stubs/_draft/__init__.py
@@ -7,6 +7,7 @@
 from . import data_types as dtype
 from .elementwise_functions import *
 from .indexing_functions import *
+from .inspection import *
 from .linear_algebra_functions import *
 from .manipulation_functions import *
 from .searching_functions import *
diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index 2a73dda24..433f762d1 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -35,6 +35,7 @@
     Optional,
     Sequence,
     Tuple,
+    TypedDict,
     TypeVar,
     Union,
     Protocol,
@@ -51,6 +52,38 @@
 # to keep pyflakes happy. https://github.com/python/typeshed/issues/3556
 ellipsis = TypeVar("ellipsis")
 
+DefaultDataTypes = TypedDict(
+    "DefaultDataTypes",
+    {
+        "real floating": dtype,
+        "complex floating": dtype,
+        "integral": dtype,
+        "indexing": dtype,
+    },
+)
+DataTypes = TypedDict(
+    "DataTypes",
+    {
+        "bool": dtype,
+        "float32": dtype,
+        "float64": dtype,
+        "complex64": dtype,
+        "complex128": dtype,
+        "int8": dtype,
+        "int16": dtype,
+        "int32": dtype,
+        "int64": dtype,
+        "uint8": dtype,
+        "uint16": dtype,
+        "uint32": dtype,
+        "uint64": dtype,
+    },
+    total=False,
+)
+Capabilities = TypedDict(
+    "Capabilities", {"boolean_indexing": bool, "data_dependent_shapes": bool}
+)
+
 
 @dataclass
 class finfo_object:
diff --git a/src/array_api_stubs/_draft/inspection.py b/src/array_api_stubs/_draft/inspection.py
new file mode 100644
index 000000000..3a19e0e6f
--- /dev/null
+++ b/src/array_api_stubs/_draft/inspection.py
@@ -0,0 +1,141 @@
+__all__ = [
+    "__array_namespace_info__",
+]
+
+from __future__ import annotations
+
+from ._types import (
+    Optional,
+    device,
+    dtype,
+    DefaultDataTypes,
+    DataTypes,
+    Capabilities,
+)
+
+
+def __array_namespace_info__() -> Info:
+    """
+    Returns a namespace with Array API namespace inspection utilities.
+
+    Returns
+    -------
+    out: Info
+        Namespace with Array API namespace inspection utilities.
+    """
+
+
+class Info:
+    def __init__(self: Info) -> None:
+        """Initialize the attributes for the inspection API class."""
+
+    @property
+    def capabilities(self: Info) -> Capabilities:
+        """
+        Dictionary of array library capabilities.
+
+        The dictionary should contain the following keys:
+
+        -   **boolean_indexing**: boolean indicating whether an array library supports boolean indexing.
+        -   **data_dependent_shapes**: boolean indicating whether an array library supports data-dependent output shapes.
+
+        Returns
+        -------
+        out: Capabilities
+            a dictionary of array library capabilities.
+        """
+
+    def default_device(self: Info) -> device:
+        """
+        Returns an object for the default device.
+
+        Returns
+        -------
+        out: device
+            an object corresponding to the default device.
+        """
+
+    def default_dtypes(
+        self: Info,
+        /,
+        *,
+        device: Optional[device] = None,
+    ) -> DefaultDataTypes:
+        """
+        Returns a dictionary containing default data types.
+
+        The dictionary should have the following keys:
+
+        -   **real floating**: default real floating-point data type.
+        -   **complex floating**: default complex floating-point data type.
+        -   **integral**: default integral data type.
+        -   **indexing**: default index data type.
+
+        Parameters
+        ----------
+        device: Optional[device]
+            device for which to return default data types. If ``device`` is ``None``, the returned data types must be the default data types for the current device. If ``device`` is not ``None``, the returned data types must be default data types specific to the specified device. Default: ``None``.
+
+            .. note::
+               Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the default data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the default data types for the default device.
+
+        Returns
+        -------
+        out: DefaultDataTypes
+            a dictionary containing the default data type for respective data type kinds.
+        """
+
+    def dtypes(
+        self: Info,
+        /,
+        *,
+        device: Optional[device] = None,
+        kind: Optional[Union[str, Tuple[str, ...]]] = None,
+    ) -> DataTypes:
+        """
+        Returns a dictionary of supported *Array API* data types.
+
+        .. note::
+           While specification-conforming array libraries may support additional data types which are not present in this specification, data types which are not present in this specification should not be included in the returned dictionary.
+
+        Parameters
+        ----------
+        kind: Optional[Union[str, Tuple[str, ...]]]
+            data type kind.
+
+            -   If ``kind`` is ``None``, the function must return a dictionary containing all supported Array API data types.
+
+            -   If ``kind`` is a string, the function must return a dictionary containing the data types belonging to the specified data type kind. The following data type kinds must be supported:
+
+                -   ``'bool'``: boolean data types (e.g., ``bool``).
+                -   ``'signed integer'``: signed integer data types (e.g., ``int8``, ``int16``, ``int32``, ``int64``).
+                -   ``'unsigned integer'``: unsigned integer data types (e.g., ``uint8``, ``uint16``, ``uint32``, ``uint64``).
+                -   ``'integral'``: integer data types. Shorthand for ``('signed integer', 'unsigned integer')``.
+                -   ``'real floating'``: real-valued floating-point data types (e.g., ``float32``, ``float64``).
+                -   ``'complex floating'``: complex floating-point data types (e.g., ``complex64``, ``complex128``).
+                -   ``'numeric'``: numeric data types. Shorthand for ``('integral', 'real floating', 'complex floating')``.
+
+            -   If ``kind`` is a tuple, the tuple specifies a union of data type kinds, and the function must return a dictionary containing the data types belonging to at least one of the specified data type kinds.
+
+            Default: ``None``.
+        device: Optional[device]
+            device for which to return supported data types. If ``device`` is ``None``, the returned data types must be the supported data types for the current device; otherwise, the returned data types must be supported data types specific to the specified device. Default: ``None``.
+
+            .. note::
+               Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the supported data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the supported data types for the default device.
+
+        Returns
+        -------
+        out: DataTypes
+            a dictionary containing supported data types.
+        """
+
+    def device(self: Info) -> List[device]:
+        """
+        Returns a list of supported devices.
+
+        Returns
+        -------
+        out: List[device]
+            a list of supported devices.
+        """

From 9494a13b35ed2ea116c92c3b97c88d80b76a2fe6 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 20:46:16 -0700
Subject: [PATCH 02/33] Fix build error

---
 src/array_api_stubs/_draft/inspection.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/array_api_stubs/_draft/inspection.py b/src/array_api_stubs/_draft/inspection.py
index 3a19e0e6f..06bad1f1f 100644
--- a/src/array_api_stubs/_draft/inspection.py
+++ b/src/array_api_stubs/_draft/inspection.py
@@ -1,9 +1,9 @@
+from __future__ import annotations
+
 __all__ = [
     "__array_namespace_info__",
 ]
 
-from __future__ import annotations
-
 from ._types import (
     Optional,
     device,

From f9436b760745bc06d9521d6a24b4f9e683e6ba53 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 20:55:17 -0700
Subject: [PATCH 03/33] Fix missing item in toctree

---
 spec/draft/API_specification/index.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/spec/draft/API_specification/index.rst b/spec/draft/API_specification/index.rst
index 603131ab9..ffc3d3775 100644
--- a/spec/draft/API_specification/index.rst
+++ b/spec/draft/API_specification/index.rst
@@ -29,6 +29,7 @@ A conforming implementation of the array API standard must provide and support t
    function_and_method_signatures
    indexing
    indexing_functions
+   inspection
    linear_algebra_functions
    manipulation_functions
    searching_functions

From fb694055e1a084d3d0d0afe9000511d5a5815285 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 21:09:14 -0700
Subject: [PATCH 04/33] Rename class

---
 src/array_api_stubs/_draft/inspection.py | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/src/array_api_stubs/_draft/inspection.py b/src/array_api_stubs/_draft/inspection.py
index 06bad1f1f..f8b83fe06 100644
--- a/src/array_api_stubs/_draft/inspection.py
+++ b/src/array_api_stubs/_draft/inspection.py
@@ -1,8 +1,6 @@
 from __future__ import annotations
 
-__all__ = [
-    "__array_namespace_info__",
-]
+__all__ = ["__array_namespace_info__", "Inspection"]
 
 from ._types import (
     Optional,
@@ -14,23 +12,23 @@
 )
 
 
-def __array_namespace_info__() -> Info:
+def __array_namespace_info__() -> Inspection:
     """
     Returns a namespace with Array API namespace inspection utilities.
 
     Returns
     -------
-    out: Info
+    out: Inspection
         Namespace with Array API namespace inspection utilities.
     """
 
 
-class Info:
-    def __init__(self: Info) -> None:
+class Inspection:
+    def __init__(self: Inspection) -> None:
         """Initialize the attributes for the inspection API class."""
 
     @property
-    def capabilities(self: Info) -> Capabilities:
+    def capabilities(self: Inspection) -> Capabilities:
         """
         Dictionary of array library capabilities.
 
@@ -45,7 +43,7 @@ def capabilities(self: Info) -> Capabilities:
             a dictionary of array library capabilities.
         """
 
-    def default_device(self: Info) -> device:
+    def default_device(self: Inspection) -> device:
         """
         Returns an object for the default device.
 
@@ -56,7 +54,7 @@ def default_device(self: Info) -> device:
         """
 
     def default_dtypes(
-        self: Info,
+        self: Inspection,
         /,
         *,
         device: Optional[device] = None,
@@ -86,7 +84,7 @@ def default_dtypes(
         """
 
     def dtypes(
-        self: Info,
+        self: Inspection,
         /,
         *,
         device: Optional[device] = None,
@@ -130,7 +128,7 @@ def dtypes(
             a dictionary containing supported data types.
         """
 
-    def device(self: Info) -> List[device]:
+    def device(self: Inspection) -> List[device]:
         """
         Returns a list of supported devices.
 

From bf6eca59b7f8ae06acfa4c2ba041f7f78f73dd1d Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 21:12:23 -0700
Subject: [PATCH 05/33] Update toctree

---
 spec/draft/API_specification/inspection.rst |  1 +
 src/array_api_stubs/_draft/inspection.py    | 20 ++++++++++----------
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index ceb01fd94..0c6b655fe 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -20,3 +20,4 @@ Objects in API
    :nosignatures:
 
    __array_namespace_info__
+   info
diff --git a/src/array_api_stubs/_draft/inspection.py b/src/array_api_stubs/_draft/inspection.py
index f8b83fe06..21d3be347 100644
--- a/src/array_api_stubs/_draft/inspection.py
+++ b/src/array_api_stubs/_draft/inspection.py
@@ -1,6 +1,6 @@
 from __future__ import annotations
 
-__all__ = ["__array_namespace_info__", "Inspection"]
+__all__ = ["__array_namespace_info__", "Info"]
 
 from ._types import (
     Optional,
@@ -12,23 +12,23 @@
 )
 
 
-def __array_namespace_info__() -> Inspection:
+def __array_namespace_info__() -> Info:
     """
     Returns a namespace with Array API namespace inspection utilities.
 
     Returns
     -------
-    out: Inspection
+    out: Info
         Namespace with Array API namespace inspection utilities.
     """
 
 
-class Inspection:
-    def __init__(self: Inspection) -> None:
+class Info:
+    def __init__(self: Info) -> None:
         """Initialize the attributes for the inspection API class."""
 
     @property
-    def capabilities(self: Inspection) -> Capabilities:
+    def capabilities(self: Info) -> Capabilities:
         """
         Dictionary of array library capabilities.
 
@@ -43,7 +43,7 @@ def capabilities(self: Inspection) -> Capabilities:
             a dictionary of array library capabilities.
         """
 
-    def default_device(self: Inspection) -> device:
+    def default_device(self: Info) -> device:
         """
         Returns an object for the default device.
 
@@ -54,7 +54,7 @@ def default_device(self: Inspection) -> device:
         """
 
     def default_dtypes(
-        self: Inspection,
+        self: Info,
         /,
         *,
         device: Optional[device] = None,
@@ -84,7 +84,7 @@ def default_dtypes(
         """
 
     def dtypes(
-        self: Inspection,
+        self: Info,
         /,
         *,
         device: Optional[device] = None,
@@ -128,7 +128,7 @@ def dtypes(
             a dictionary containing supported data types.
         """
 
-    def device(self: Inspection) -> List[device]:
+    def device(self: Info) -> List[device]:
         """
         Returns a list of supported devices.
 

From 58e51526359101d823ae9276888cc6c83df50ce7 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 21:48:27 -0700
Subject: [PATCH 06/33] Fix item name

---
 spec/draft/API_specification/inspection.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index 0c6b655fe..1ca8e040d 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -20,4 +20,4 @@ Objects in API
    :nosignatures:
 
    __array_namespace_info__
-   info
+   Info

From ff0a5b093f4da1ccee010e174512e50df3822bb6 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 19 Sep 2023 21:49:54 -0700
Subject: [PATCH 07/33] Update copy

---
 spec/draft/API_specification/inspection.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index 1ca8e040d..a3ca9edfc 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -3,7 +3,7 @@ Inspection
 
     Array API specification for namespace inspection utilities.
 
-A conforming implementation of the array API standard must provide and support the following functions.
+A conforming implementation of the array API standard must provide and support the following functions and objects.
 
 
 Objects in API

From a7fffab25a1041407e9c6b9ad57d59acf46459af Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 20 Sep 2023 00:19:28 -0700
Subject: [PATCH 08/33] Rename file and fix rendering issues

---
 spec/draft/API_specification/inspection.rst |  25 +++-
 src/array_api_stubs/_draft/__init__.py      |   2 +-
 src/array_api_stubs/_draft/_types.py        |  26 ++++
 src/array_api_stubs/_draft/info.py          | 143 ++++++++++++++++++++
 src/array_api_stubs/_draft/inspection.py    | 139 -------------------
 5 files changed, 190 insertions(+), 145 deletions(-)
 create mode 100644 src/array_api_stubs/_draft/info.py
 delete mode 100644 src/array_api_stubs/_draft/inspection.py

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index a3ca9edfc..b16bbe7b2 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -3,21 +3,36 @@ Inspection
 
     Array API specification for namespace inspection utilities.
 
-A conforming implementation of the array API standard must provide and support the following functions and objects.
+A conforming implementation of the array API standard must provide and support the following functions and associated inspection APIs.
 
 
 Objects in API
 --------------
 
-.. currentmodule:: array_api
+.. currentmodule:: array_api.info
 
 ..
   NOTE: please keep the functions in alphabetical order
 
 .. autosummary::
    :toctree: generated
-   :template: attribute.rst
-   :nosignatures:
+   :template: method.rst
 
    __array_namespace_info__
-   Info
+
+
+Inspection APIs
+---------------
+..
+  NOTE: please keep the methods in alphabetical order
+
+
+.. autosummary::
+   :toctree: generated
+   :template: method.rst
+
+   capabilities
+   default_device
+   default_dtypes
+   devices
+   dtypes
diff --git a/src/array_api_stubs/_draft/__init__.py b/src/array_api_stubs/_draft/__init__.py
index 5280ce7f2..8415f2765 100644
--- a/src/array_api_stubs/_draft/__init__.py
+++ b/src/array_api_stubs/_draft/__init__.py
@@ -7,7 +7,6 @@
 from . import data_types as dtype
 from .elementwise_functions import *
 from .indexing_functions import *
-from .inspection import *
 from .linear_algebra_functions import *
 from .manipulation_functions import *
 from .searching_functions import *
@@ -17,6 +16,7 @@
 from .utility_functions import *
 from . import linalg
 from . import fft
+from . import info
 
 
 __array_api_version__: str = "YYYY.MM"
diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index 433f762d1..f54405e1d 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -25,6 +25,10 @@
     "finfo_object",
     "iinfo_object",
     "Enum",
+    "DefaultDataTypes",
+    "DataTypes",
+    "Capabilities",
+    "Info",
 ]
 
 from dataclasses import dataclass
@@ -85,6 +89,28 @@
 )
 
 
+@dataclass
+class Info:
+    """Namespace returned by `__array_namespace_info__`."""
+
+    def capabilities() -> Capabilities:
+        ...
+
+    def default_device() -> device:
+        ...
+
+    def default_dtypes(*, device: Optional[device]) -> DefaultDataTypes:
+        ...
+
+    def devices() -> List[device]:
+        ...
+
+    def dtypes(
+        *, device: Optional[device], kind: Optional[Union[str, Tuple[str, ...]]]
+    ) -> DataTypes:
+        ...
+
+
 @dataclass
 class finfo_object:
     """Dataclass returned by `finfo`."""
diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
new file mode 100644
index 000000000..876192ff8
--- /dev/null
+++ b/src/array_api_stubs/_draft/info.py
@@ -0,0 +1,143 @@
+__all__ = [
+    "__array_namespace_info__",
+    "capabilities",
+    "default_device",
+    "default_dtypes",
+    "devices",
+    "dtypes",
+]
+
+from ._types import (
+    Optional,
+    Union,
+    Tuple,
+    List,
+    device,
+    dtype,
+    DefaultDataTypes,
+    DataTypes,
+    Capabilities,
+    Info,
+)
+
+
+def __array_namespace_info__() -> Info:
+    """
+    Returns a namespace with Array API namespace inspection utilities.
+
+    Returns
+    -------
+    out: Info
+        Namespace with Array API namespace inspection utilities.
+    """
+
+
+def capabilities() -> Capabilities:
+    """
+    Returns a dictionary of array library capabilities.
+
+    The dictionary should contain the following keys:
+
+    -   **boolean_indexing**: boolean indicating whether an array library supports boolean indexing.
+    -   **data_dependent_shapes**: boolean indicating whether an array library supports data-dependent output shapes.
+
+    Returns
+    -------
+    out: Capabilities
+        a dictionary of array library capabilities.
+    """
+
+
+def default_device() -> device:
+    """
+    Returns an object for the default device.
+
+    Returns
+    -------
+    out: device
+        an object corresponding to the default device.
+    """
+
+
+def default_dtypes(
+    *,
+    device: Optional[device] = None,
+) -> DefaultDataTypes:
+    """
+    Returns a dictionary containing default data types.
+
+    The dictionary should have the following keys:
+
+    -   **real floating**: default real floating-point data type.
+    -   **complex floating**: default complex floating-point data type.
+    -   **integral**: default integral data type.
+    -   **indexing**: default index data type.
+
+    Parameters
+    ----------
+    device: Optional[device]
+        device for which to return default data types. If ``device`` is ``None``, the returned data types must be the default data types for the current device. If ``device`` is not ``None``, the returned data types must be default data types specific to the specified device. Default: ``None``.
+
+        .. note::
+           Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the default data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the default data types for the default device.
+
+    Returns
+    -------
+    out: DefaultDataTypes
+        a dictionary containing the default data type for respective data type kinds.
+    """
+
+
+def dtypes(
+    *,
+    device: Optional[device] = None,
+    kind: Optional[Union[str, Tuple[str, ...]]] = None,
+) -> DataTypes:
+    """
+    Returns a dictionary of supported *Array API* data types.
+
+    .. note::
+       While specification-conforming array libraries may support additional data types which are not present in this specification, data types which are not present in this specification should not be included in the returned dictionary.
+
+    Parameters
+    ----------
+    kind: Optional[Union[str, Tuple[str, ...]]]
+        data type kind.
+
+        -   If ``kind`` is ``None``, the function must return a dictionary containing all supported Array API data types.
+
+        -   If ``kind`` is a string, the function must return a dictionary containing the data types belonging to the specified data type kind. The following data type kinds must be supported:
+
+            -   ``'bool'``: boolean data types (e.g., ``bool``).
+            -   ``'signed integer'``: signed integer data types (e.g., ``int8``, ``int16``, ``int32``, ``int64``).
+            -   ``'unsigned integer'``: unsigned integer data types (e.g., ``uint8``, ``uint16``, ``uint32``, ``uint64``).
+            -   ``'integral'``: integer data types. Shorthand for ``('signed integer', 'unsigned integer')``.
+            -   ``'real floating'``: real-valued floating-point data types (e.g., ``float32``, ``float64``).
+            -   ``'complex floating'``: complex floating-point data types (e.g., ``complex64``, ``complex128``).
+            -   ``'numeric'``: numeric data types. Shorthand for ``('integral', 'real floating', 'complex floating')``.
+
+        -   If ``kind`` is a tuple, the tuple specifies a union of data type kinds, and the function must return a dictionary containing the data types belonging to at least one of the specified data type kinds.
+
+        Default: ``None``.
+    device: Optional[device]
+        device for which to return supported data types. If ``device`` is ``None``, the returned data types must be the supported data types for the current device; otherwise, the returned data types must be supported data types specific to the specified device. Default: ``None``.
+
+        .. note::
+           Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the supported data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the supported data types for the default device.
+
+    Returns
+    -------
+    out: DataTypes
+        a dictionary containing supported data types.
+    """
+
+
+def devices() -> List[device]:
+    """
+    Returns a list of supported devices.
+
+    Returns
+    -------
+    out: List[device]
+        a list of supported devices.
+    """
diff --git a/src/array_api_stubs/_draft/inspection.py b/src/array_api_stubs/_draft/inspection.py
deleted file mode 100644
index 21d3be347..000000000
--- a/src/array_api_stubs/_draft/inspection.py
+++ /dev/null
@@ -1,139 +0,0 @@
-from __future__ import annotations
-
-__all__ = ["__array_namespace_info__", "Info"]
-
-from ._types import (
-    Optional,
-    device,
-    dtype,
-    DefaultDataTypes,
-    DataTypes,
-    Capabilities,
-)
-
-
-def __array_namespace_info__() -> Info:
-    """
-    Returns a namespace with Array API namespace inspection utilities.
-
-    Returns
-    -------
-    out: Info
-        Namespace with Array API namespace inspection utilities.
-    """
-
-
-class Info:
-    def __init__(self: Info) -> None:
-        """Initialize the attributes for the inspection API class."""
-
-    @property
-    def capabilities(self: Info) -> Capabilities:
-        """
-        Dictionary of array library capabilities.
-
-        The dictionary should contain the following keys:
-
-        -   **boolean_indexing**: boolean indicating whether an array library supports boolean indexing.
-        -   **data_dependent_shapes**: boolean indicating whether an array library supports data-dependent output shapes.
-
-        Returns
-        -------
-        out: Capabilities
-            a dictionary of array library capabilities.
-        """
-
-    def default_device(self: Info) -> device:
-        """
-        Returns an object for the default device.
-
-        Returns
-        -------
-        out: device
-            an object corresponding to the default device.
-        """
-
-    def default_dtypes(
-        self: Info,
-        /,
-        *,
-        device: Optional[device] = None,
-    ) -> DefaultDataTypes:
-        """
-        Returns a dictionary containing default data types.
-
-        The dictionary should have the following keys:
-
-        -   **real floating**: default real floating-point data type.
-        -   **complex floating**: default complex floating-point data type.
-        -   **integral**: default integral data type.
-        -   **indexing**: default index data type.
-
-        Parameters
-        ----------
-        device: Optional[device]
-            device for which to return default data types. If ``device`` is ``None``, the returned data types must be the default data types for the current device. If ``device`` is not ``None``, the returned data types must be default data types specific to the specified device. Default: ``None``.
-
-            .. note::
-               Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the default data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the default data types for the default device.
-
-        Returns
-        -------
-        out: DefaultDataTypes
-            a dictionary containing the default data type for respective data type kinds.
-        """
-
-    def dtypes(
-        self: Info,
-        /,
-        *,
-        device: Optional[device] = None,
-        kind: Optional[Union[str, Tuple[str, ...]]] = None,
-    ) -> DataTypes:
-        """
-        Returns a dictionary of supported *Array API* data types.
-
-        .. note::
-           While specification-conforming array libraries may support additional data types which are not present in this specification, data types which are not present in this specification should not be included in the returned dictionary.
-
-        Parameters
-        ----------
-        kind: Optional[Union[str, Tuple[str, ...]]]
-            data type kind.
-
-            -   If ``kind`` is ``None``, the function must return a dictionary containing all supported Array API data types.
-
-            -   If ``kind`` is a string, the function must return a dictionary containing the data types belonging to the specified data type kind. The following data type kinds must be supported:
-
-                -   ``'bool'``: boolean data types (e.g., ``bool``).
-                -   ``'signed integer'``: signed integer data types (e.g., ``int8``, ``int16``, ``int32``, ``int64``).
-                -   ``'unsigned integer'``: unsigned integer data types (e.g., ``uint8``, ``uint16``, ``uint32``, ``uint64``).
-                -   ``'integral'``: integer data types. Shorthand for ``('signed integer', 'unsigned integer')``.
-                -   ``'real floating'``: real-valued floating-point data types (e.g., ``float32``, ``float64``).
-                -   ``'complex floating'``: complex floating-point data types (e.g., ``complex64``, ``complex128``).
-                -   ``'numeric'``: numeric data types. Shorthand for ``('integral', 'real floating', 'complex floating')``.
-
-            -   If ``kind`` is a tuple, the tuple specifies a union of data type kinds, and the function must return a dictionary containing the data types belonging to at least one of the specified data type kinds.
-
-            Default: ``None``.
-        device: Optional[device]
-            device for which to return supported data types. If ``device`` is ``None``, the returned data types must be the supported data types for the current device; otherwise, the returned data types must be supported data types specific to the specified device. Default: ``None``.
-
-            .. note::
-               Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the supported data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the supported data types for the default device.
-
-        Returns
-        -------
-        out: DataTypes
-            a dictionary containing supported data types.
-        """
-
-    def device(self: Info) -> List[device]:
-        """
-        Returns a list of supported devices.
-
-        Returns
-        -------
-        out: List[device]
-            a list of supported devices.
-        """

From 4e968f701aa23b9ac677897e21cad67eeaf4b05f Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 20 Sep 2023 00:20:45 -0700
Subject: [PATCH 09/33] Add annotations

---
 src/array_api_stubs/_draft/_types.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index f54405e1d..298d8dab9 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -93,18 +93,23 @@
 class Info:
     """Namespace returned by `__array_namespace_info__`."""
 
+    @staticmethod
     def capabilities() -> Capabilities:
         ...
 
+    @staticmethod
     def default_device() -> device:
         ...
 
+    @staticmethod
     def default_dtypes(*, device: Optional[device]) -> DefaultDataTypes:
         ...
 
+    @staticmethod
     def devices() -> List[device]:
         ...
 
+    @staticmethod
     def dtypes(
         *, device: Optional[device], kind: Optional[Union[str, Tuple[str, ...]]]
     ) -> DataTypes:

From 553d3890d26892256cb19eba86cd6555ce4f78d6 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 20 Sep 2023 00:25:15 -0700
Subject: [PATCH 10/33] Update description

---
 src/_array_api_conf.py             | 4 ++++
 src/array_api_stubs/_draft/info.py | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/_array_api_conf.py b/src/_array_api_conf.py
index d3a136eaa..5f0e2d376 100644
--- a/src/_array_api_conf.py
+++ b/src/_array_api_conf.py
@@ -70,6 +70,10 @@
     ("py:class", ".*PyCapsule"),
     ("py:class", ".*finfo_object"),
     ("py:class", ".*iinfo_object"),
+    ("py:class", ".*Info"),
+    ("py:class", ".*Capabilities"),
+    ("py:class", ".*DefaultDataTypes"),
+    ("py:class", ".*DataTypes"),
 ]
 # In array_object.py we have to use aliased names for some types because they
 # would otherwise refer back to method objects of array
diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 876192ff8..95d386708 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -50,7 +50,7 @@ def capabilities() -> Capabilities:
 
 def default_device() -> device:
     """
-    Returns an object for the default device.
+    Returns the default device.
 
     Returns
     -------

From e927b3535fb9ee91f50fcbaf02945aae495308df Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 20 Sep 2023 00:26:12 -0700
Subject: [PATCH 11/33] Update description

---
 src/array_api_stubs/_draft/info.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 95d386708..7d6d93710 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -76,7 +76,7 @@ def default_dtypes(
     Parameters
     ----------
     device: Optional[device]
-        device for which to return default data types. If ``device`` is ``None``, the returned data types must be the default data types for the current device. If ``device`` is not ``None``, the returned data types must be default data types specific to the specified device. Default: ``None``.
+        device for which to return default data types. If ``device`` is ``None``, the returned data types must be the default data types for the current device; otherwise, the returned data types must be default data types specific to the specified device. Default: ``None``.
 
         .. note::
            Some array libraries have the concept of a device context manager, allowing library consumers to manage the current device context. When ``device`` is ``None``, libraries supporting a device context should return the default data types for the current device. For libraries without a context manager or supporting only a single device, those libraries should return the default data types for the default device.

From aa012a8958623ae427e15232a9f35aa9dfcb35f6 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 20 Sep 2023 22:30:54 -0700
Subject: [PATCH 12/33] Add note regarding aliasing

---
 src/array_api_stubs/_draft/info.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 7d6d93710..b81321efe 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -99,6 +99,9 @@ def dtypes(
     .. note::
        While specification-conforming array libraries may support additional data types which are not present in this specification, data types which are not present in this specification should not be included in the returned dictionary.
 
+    .. note::
+       Specification-conforming array libraries must only return supported data types having expected properties as described in :ref:`data-types`. For example, if a library decides to alias ``float32`` as ``float64``, that library must not include ``float64`` in the dictionary of supported data types.
+
     Parameters
     ----------
     kind: Optional[Union[str, Tuple[str, ...]]]

From 43a8accf1157c9d3808d03d24b7d1a1b21c826ed Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 20 Sep 2023 22:34:15 -0700
Subject: [PATCH 13/33] Add note regarding use of canonical names

---
 src/array_api_stubs/_draft/info.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index b81321efe..6e7ff1f20 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -132,6 +132,9 @@ def dtypes(
     -------
     out: DataTypes
         a dictionary containing supported data types.
+
+        .. note::
+           Dictionary keys must only consist of canonical names as defined in :ref:`data-types`.
     """
 
 

From bcec0d3509ae62dbf501d2404539df893a8a7825 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 11 Jan 2024 01:51:22 -0800
Subject: [PATCH 14/33] Refactor to use `Protocol`

---
 src/array_api_stubs/_draft/_types.py | 113 +++++++++++++--------------
 1 file changed, 54 insertions(+), 59 deletions(-)

diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index 298d8dab9..5466d3820 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -56,65 +56,6 @@
 # to keep pyflakes happy. https://github.com/python/typeshed/issues/3556
 ellipsis = TypeVar("ellipsis")
 
-DefaultDataTypes = TypedDict(
-    "DefaultDataTypes",
-    {
-        "real floating": dtype,
-        "complex floating": dtype,
-        "integral": dtype,
-        "indexing": dtype,
-    },
-)
-DataTypes = TypedDict(
-    "DataTypes",
-    {
-        "bool": dtype,
-        "float32": dtype,
-        "float64": dtype,
-        "complex64": dtype,
-        "complex128": dtype,
-        "int8": dtype,
-        "int16": dtype,
-        "int32": dtype,
-        "int64": dtype,
-        "uint8": dtype,
-        "uint16": dtype,
-        "uint32": dtype,
-        "uint64": dtype,
-    },
-    total=False,
-)
-Capabilities = TypedDict(
-    "Capabilities", {"boolean_indexing": bool, "data_dependent_shapes": bool}
-)
-
-
-@dataclass
-class Info:
-    """Namespace returned by `__array_namespace_info__`."""
-
-    @staticmethod
-    def capabilities() -> Capabilities:
-        ...
-
-    @staticmethod
-    def default_device() -> device:
-        ...
-
-    @staticmethod
-    def default_dtypes(*, device: Optional[device]) -> DefaultDataTypes:
-        ...
-
-    @staticmethod
-    def devices() -> List[device]:
-        ...
-
-    @staticmethod
-    def dtypes(
-        *, device: Optional[device], kind: Optional[Union[str, Tuple[str, ...]]]
-    ) -> DataTypes:
-        ...
-
 
 @dataclass
 class finfo_object:
@@ -147,3 +88,57 @@ def __getitem__(self, key: int, /) -> Union[_T_co, NestedSequence[_T_co]]:
 
     def __len__(self, /) -> int:
         ...
+
+
+class Info(Protocol):
+    """Namespace returned by `__array_namespace_info__`."""
+
+    def capabilities() -> Capabilities:
+        ...
+
+    def default_device() -> device:
+        ...
+
+    def default_dtypes(*, device: Optional[device]) -> DefaultDataTypes:
+        ...
+
+    def devices() -> List[device]:
+        ...
+
+    def dtypes(
+        *, device: Optional[device], kind: Optional[Union[str, Tuple[str, ...]]]
+    ) -> DataTypes:
+        ...
+
+
+DefaultDataTypes = TypedDict(
+    "DefaultDataTypes",
+    {
+        "real floating": dtype,
+        "complex floating": dtype,
+        "integral": dtype,
+        "indexing": dtype,
+    },
+)
+DataTypes = TypedDict(
+    "DataTypes",
+    {
+        "bool": dtype,
+        "float32": dtype,
+        "float64": dtype,
+        "complex64": dtype,
+        "complex128": dtype,
+        "int8": dtype,
+        "int16": dtype,
+        "int32": dtype,
+        "int64": dtype,
+        "uint8": dtype,
+        "uint16": dtype,
+        "uint32": dtype,
+        "uint64": dtype,
+    },
+    total=False,
+)
+Capabilities = TypedDict(
+    "Capabilities", {"boolean_indexing": bool, "data_dependent_shapes": bool}
+)

From 0ed4686ccbbd9eb1fe85fa73953b2bd7205b8646 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 11 Jan 2024 01:55:52 -0800
Subject: [PATCH 15/33] Add `self`

---
 src/array_api_stubs/_draft/_types.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index 5466d3820..6dd259ab1 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -93,20 +93,20 @@ def __len__(self, /) -> int:
 class Info(Protocol):
     """Namespace returned by `__array_namespace_info__`."""
 
-    def capabilities() -> Capabilities:
+    def capabilities(self) -> Capabilities:
         ...
 
-    def default_device() -> device:
+    def default_device(self) -> device:
         ...
 
-    def default_dtypes(*, device: Optional[device]) -> DefaultDataTypes:
+    def default_dtypes(self, *, device: Optional[device]) -> DefaultDataTypes:
         ...
 
-    def devices() -> List[device]:
+    def devices(self) -> List[device]:
         ...
 
     def dtypes(
-        *, device: Optional[device], kind: Optional[Union[str, Tuple[str, ...]]]
+        self, *, device: Optional[device], kind: Optional[Union[str, Tuple[str, ...]]]
     ) -> DataTypes:
         ...
 

From 8207bbe4a841742c7e27259e68f6f66a25fa27d7 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 00:00:48 -0800
Subject: [PATCH 16/33] Replaces underscores with spaces

---
 src/array_api_stubs/_draft/_types.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index 6dd259ab1..47c1bf3c2 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -140,5 +140,5 @@ def dtypes(
     total=False,
 )
 Capabilities = TypedDict(
-    "Capabilities", {"boolean_indexing": bool, "data_dependent_shapes": bool}
+    "Capabilities", {"boolean indexing": bool, "data dependent shapes": bool}
 )

From 93c85ad4208791bc23885386362d892cdd09ba5b Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 00:02:19 -0800
Subject: [PATCH 17/33] Replace underscores with spaces to ensure consistent
 conventions

---
 src/array_api_stubs/_draft/info.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 6e7ff1f20..56cb6b05c 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -38,8 +38,8 @@ def capabilities() -> Capabilities:
 
     The dictionary should contain the following keys:
 
-    -   **boolean_indexing**: boolean indicating whether an array library supports boolean indexing.
-    -   **data_dependent_shapes**: boolean indicating whether an array library supports data-dependent output shapes.
+    -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing.
+    -   **data dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes.
 
     Returns
     -------

From e89882e48d6f53a395178852640e46852bfda037 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 00:44:12 -0800
Subject: [PATCH 18/33] Document returned object

---
 src/array_api_stubs/_draft/info.py | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 56cb6b05c..d2d3b5dbe 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -28,7 +28,20 @@ def __array_namespace_info__() -> Info:
     Returns
     -------
     out: Info
-        Namespace with Array API namespace inspection utilities.
+        An object containing Array API namespace inspection utilities.
+
+    Notes
+    -----
+
+    The returned object may be either a namespace or a class, so long as an Array API user can access inspection utilities as follows:
+
+    ::
+       info = xp.__array_namespace_info__()
+       info.capabilities()
+       info.devices()
+       info.dtypes()
+       info.default_dtypes()
+       # ...
     """
 
 

From d481eb449781c9fd69372aa74c10d3339535d200 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 00:52:23 -0800
Subject: [PATCH 19/33] Add introspection API preamble to clarify API
 relationship

---
 spec/draft/API_specification/inspection.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index b16bbe7b2..6480550a6 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -23,6 +23,9 @@ Objects in API
 
 Inspection APIs
 ---------------
+
+For the object (either a namespace or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
+
 ..
   NOTE: please keep the methods in alphabetical order
 

From 42ad3e38d401ea06dfc1456772176447dcf20358 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 01:33:14 -0800
Subject: [PATCH 20/33] Update copy

---
 spec/draft/API_specification/inspection.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index 6480550a6..26906e682 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -24,7 +24,7 @@ Objects in API
 Inspection APIs
 ---------------
 
-For the object (either a namespace or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
+For the namespace (or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
 
 ..
   NOTE: please keep the methods in alphabetical order

From 4d3b575f86f2ae1ed1cf5df4fbabbaf3ce92b4fd Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 01:35:27 -0800
Subject: [PATCH 21/33] Update indentation

---
 src/array_api_stubs/_draft/info.py | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index d2d3b5dbe..668b8b611 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -36,12 +36,13 @@ def __array_namespace_info__() -> Info:
     The returned object may be either a namespace or a class, so long as an Array API user can access inspection utilities as follows:
 
     ::
-       info = xp.__array_namespace_info__()
-       info.capabilities()
-       info.devices()
-       info.dtypes()
-       info.default_dtypes()
-       # ...
+
+      info = xp.__array_namespace_info__()
+      info.capabilities()
+      info.devices()
+      info.dtypes()
+      info.default_dtypes()
+      # ...
     """
 
 

From d32ec1f8c0d3cc8d5079c57e3dcd636b3b3a985f Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 01:39:45 -0800
Subject: [PATCH 22/33] Remove empty line

---
 spec/draft/API_specification/inspection.rst | 1 -
 1 file changed, 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index 26906e682..487f878f4 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -29,7 +29,6 @@ For the namespace (or class) returned by ``__array_namespace__info__``, a confor
 ..
   NOTE: please keep the methods in alphabetical order
 
-
 .. autosummary::
    :toctree: generated
    :template: method.rst

From 332b7d23537a6c2dd8aa17158807e38923fb488c Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 01:40:03 -0800
Subject: [PATCH 23/33] Update comment

---
 spec/draft/API_specification/inspection.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index 487f878f4..e584c0c74 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -27,7 +27,7 @@ Inspection APIs
 For the namespace (or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
 
 ..
-  NOTE: please keep the methods in alphabetical order
+  NOTE: please keep the functions in alphabetical order
 
 .. autosummary::
    :toctree: generated

From 908600aa69176dde06794a20917e19a98f1d7f49 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 01:46:31 -0800
Subject: [PATCH 24/33] Update copy

---
 spec/draft/API_specification/inspection.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index e584c0c74..b971cb501 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -24,7 +24,7 @@ Objects in API
 Inspection APIs
 ---------------
 
-For the namespace (or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
+In the namespace (or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
 
 ..
   NOTE: please keep the functions in alphabetical order

From ad1c84474cbbec26a99f9781035b9504ea685170 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 02:01:39 -0800
Subject: [PATCH 25/33] Add hyphen to match prose in specification

---
 src/array_api_stubs/_draft/_types.py | 2 +-
 src/array_api_stubs/_draft/info.py   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/array_api_stubs/_draft/_types.py b/src/array_api_stubs/_draft/_types.py
index 47c1bf3c2..7c3d903d7 100644
--- a/src/array_api_stubs/_draft/_types.py
+++ b/src/array_api_stubs/_draft/_types.py
@@ -140,5 +140,5 @@ def dtypes(
     total=False,
 )
 Capabilities = TypedDict(
-    "Capabilities", {"boolean indexing": bool, "data dependent shapes": bool}
+    "Capabilities", {"boolean indexing": bool, "data-dependent shapes": bool}
 )
diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 668b8b611..633f14df7 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -53,7 +53,7 @@ def capabilities() -> Capabilities:
     The dictionary should contain the following keys:
 
     -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing.
-    -   **data dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes.
+    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes.
 
     Returns
     -------

From feb92fd6899b8f9a502d7eccc7426b88fc19d111 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Thu, 25 Jan 2024 04:49:20 -0800
Subject: [PATCH 26/33] Update copy

---
 src/array_api_stubs/_draft/info.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 633f14df7..117034f26 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -154,7 +154,7 @@ def dtypes(
 
 def devices() -> List[device]:
     """
-    Returns a list of supported devices.
+    Returns a list of supported devices which are available at runtime.
 
     Returns
     -------

From 98a3b9002dac020bdeb05e255a2226f52741d6a3 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 7 Feb 2024 20:23:15 -0800
Subject: [PATCH 27/33] Add note

---
 src/array_api_stubs/_draft/info.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 117034f26..36671be68 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -85,7 +85,7 @@ def default_dtypes(
     -   **real floating**: default real floating-point data type.
     -   **complex floating**: default complex floating-point data type.
     -   **integral**: default integral data type.
-    -   **indexing**: default index data type.
+    -   **indexing**: default array index data type.
 
     Parameters
     ----------
@@ -160,4 +160,9 @@ def devices() -> List[device]:
     -------
     out: List[device]
         a list of supported devices.
+
+    Notes
+    -----
+
+    Each device object (see :ref:`device-support`) in the list of returned devices must be an object which can be provided as a valid keyword-argument to array creation functions.
     """

From f27b0d87036edaf0936994a0862306926a6c944f Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Wed, 7 Feb 2024 20:27:32 -0800
Subject: [PATCH 28/33] Update copy

---
 spec/draft/design_topics/device_support.rst | 29 +++++++++++----------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/spec/draft/design_topics/device_support.rst b/spec/draft/design_topics/device_support.rst
index 29f0789bb..593b0b9fa 100644
--- a/spec/draft/design_topics/device_support.rst
+++ b/spec/draft/design_topics/device_support.rst
@@ -39,7 +39,7 @@ into library code which may have to do the following:
 Syntax for device assignment
 ----------------------------
 
-The array API will offer the following syntax for device assignment and
+The array API provides the following syntax for device assignment and
 cross-device data transfer:
 
 1. A ``.device`` property on the array object, which returns a ``Device`` object
@@ -52,19 +52,20 @@ cross-device data transfer:
 3. A ``.to_device`` method on the array object to copy an array to a different device.
 
 .. note::
-   In the current API standard, the only way to obtain a ``Device`` object is from the
-   ``.device`` property on the array object. The standard does **not** include a universal
-   ``Device`` object recognized by all compliant libraries. Accordingly, the standard does
-   not provide a means of instantiating a ``Device`` object to point to a specific physical or
-   logical device.
-
-   The choice to not include a standardized ``Device`` object may be revisited in a future revision of this standard.
-
-   For array libraries which concern themselves with multi-device support, including CPU and GPU,
-   they are free to expose a library-specific device object (e.g., for creating an
-   array on a particular device). While a library-specific device object can be used as input to
-   ``to_device``, beware that this will mean non-portability as code will be specific to
-   that library.
+   The current API standard does **not** include a universal ``Device`` object
+   recognized by all compliant libraries. Accordingly, the standard does not
+   provide a means of instantiating a ``Device`` object to point to a specific
+   physical or logical device.
+
+   The choice to not include a standardized ``Device`` object may be revisited
+   in a future revision of this standard.
+
+   For array libraries which concern themselves with multi-device support,
+   including CPU and GPU, they are free to expose a library-specific device
+   object (e.g., for creating an array on a particular device). While a
+   library-specific device object can be used as input to ``to_device``, beware
+   that this will mean non-portability as code will be specific to that
+   library.
 
 Semantics
 ---------

From ad79bb0c6b34d19901f7f3d99237676152b37052 Mon Sep 17 00:00:00 2001
From: Athan <kgryte@gmail.com>
Date: Thu, 8 Feb 2024 09:51:13 -0800
Subject: [PATCH 29/33] Fix typo

---
 spec/draft/API_specification/inspection.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/draft/API_specification/inspection.rst b/spec/draft/API_specification/inspection.rst
index b971cb501..04691e712 100644
--- a/spec/draft/API_specification/inspection.rst
+++ b/spec/draft/API_specification/inspection.rst
@@ -24,7 +24,7 @@ Objects in API
 Inspection APIs
 ---------------
 
-In the namespace (or class) returned by ``__array_namespace__info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
+In the namespace (or class) returned by ``__array_namespace_info__``, a conforming implementation of the array API standard must provide and support the following functions (or methods) for programmatically querying data type and device support, capabilities, and other specification-defined implementation-specific behavior, as documented in the functions described below.
 
 ..
   NOTE: please keep the functions in alphabetical order

From 3210b5adbc3fc9ca85b15f39690247858994ff22 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 13 Feb 2024 02:08:42 -0800
Subject: [PATCH 30/33] docs: update capabilities guidance and replace `should`
 with `must`

---
 src/array_api_stubs/_draft/info.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index 36671be68..a2a933e21 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -50,10 +50,10 @@ def capabilities() -> Capabilities:
     """
     Returns a dictionary of array library capabilities.
 
-    The dictionary should contain the following keys:
+    The dictionary must contain the following keys:
 
-    -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing.
-    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes.
+    -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing. If a conforming implementation fully supports boolean indexing in compliance with this specification (see :ref:`indexing`), the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
+    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
 
     Returns
     -------
@@ -80,13 +80,15 @@ def default_dtypes(
     """
     Returns a dictionary containing default data types.
 
-    The dictionary should have the following keys:
+    The dictionary must have the following keys:
 
     -   **real floating**: default real floating-point data type.
     -   **complex floating**: default complex floating-point data type.
     -   **integral**: default integral data type.
     -   **indexing**: default array index data type.
 
+    Dictionary values must be the corresponding data type object.
+
     Parameters
     ----------
     device: Optional[device]

From 5d13d4103f37bb858d9d4551cb27128bbb9e1700 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 13 Feb 2024 02:12:03 -0800
Subject: [PATCH 31/33] docs: add clause

---
 src/array_api_stubs/_draft/info.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index a2a933e21..c85d244df 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -53,7 +53,7 @@ def capabilities() -> Capabilities:
     The dictionary must contain the following keys:
 
     -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing. If a conforming implementation fully supports boolean indexing in compliance with this specification (see :ref:`indexing`), the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
-    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
+    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, as explicitly demarcated throughout the specification, the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
 
     Returns
     -------

From 083806ee436cba1b8626f4d38e982d01594bee80 Mon Sep 17 00:00:00 2001
From: Athan Reines <kgryte@gmail.com>
Date: Tue, 13 Feb 2024 02:22:23 -0800
Subject: [PATCH 32/33] style: fix backticks

---
 src/array_api_stubs/_draft/info.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index c85d244df..a9cbf09bd 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -52,8 +52,8 @@ def capabilities() -> Capabilities:
 
     The dictionary must contain the following keys:
 
-    -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing. If a conforming implementation fully supports boolean indexing in compliance with this specification (see :ref:`indexing`), the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
-    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, as explicitly demarcated throughout the specification, the corresponding dictionary value must be `True`; otherwise, the value must be `False`.
+    -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing. If a conforming implementation fully supports boolean indexing in compliance with this specification (see :ref:`indexing`), the corresponding dictionary value must be ``True``; otherwise, the value must be ``False``.
+    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, as explicitly demarcated throughout the specification, the corresponding dictionary value must be ``True``; otherwise, the value must be ``False``.
 
     Returns
     -------

From 801545726de0dc77a9e75cfa1997604d84552559 Mon Sep 17 00:00:00 2001
From: Athan <kgryte@gmail.com>
Date: Wed, 14 Feb 2024 15:35:11 -0800
Subject: [PATCH 33/33] Apply suggestions from code review

Co-authored-by: Leo Fang <leo80042@gmail.com>
---
 src/array_api_stubs/_draft/info.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/array_api_stubs/_draft/info.py b/src/array_api_stubs/_draft/info.py
index a9cbf09bd..f70418405 100644
--- a/src/array_api_stubs/_draft/info.py
+++ b/src/array_api_stubs/_draft/info.py
@@ -52,8 +52,8 @@ def capabilities() -> Capabilities:
 
     The dictionary must contain the following keys:
 
-    -   **boolean indexing**: boolean indicating whether an array library supports boolean indexing. If a conforming implementation fully supports boolean indexing in compliance with this specification (see :ref:`indexing`), the corresponding dictionary value must be ``True``; otherwise, the value must be ``False``.
-    -   **data-dependent shapes**: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, as explicitly demarcated throughout the specification, the corresponding dictionary value must be ``True``; otherwise, the value must be ``False``.
+    -   `"boolean indexing"`: boolean indicating whether an array library supports boolean indexing. If a conforming implementation fully supports boolean indexing in compliance with this specification (see :ref:`indexing`), the corresponding dictionary value must be ``True``; otherwise, the value must be ``False``.
+    -   `"data-dependent shapes"`: boolean indicating whether an array library supports data-dependent output shapes. If a conforming implementation fully supports all APIs included in this specification (excluding boolean indexing) which have data-dependent output shapes, as explicitly demarcated throughout the specification, the corresponding dictionary value must be ``True``; otherwise, the value must be ``False``.
 
     Returns
     -------
@@ -82,10 +82,10 @@ def default_dtypes(
 
     The dictionary must have the following keys:
 
-    -   **real floating**: default real floating-point data type.
-    -   **complex floating**: default complex floating-point data type.
-    -   **integral**: default integral data type.
-    -   **indexing**: default array index data type.
+    -   `"real floating"`: default real floating-point data type.
+    -   `"complex floating"`: default complex floating-point data type.
+    -   `"integral"`: default integral data type.
+    -   `"indexing"`: default array index data type.
 
     Dictionary values must be the corresponding data type object.