Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Align casting methods with Python behaviour #497

Merged
merged 15 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 76 additions & 7 deletions spec/API_specification/array_api/array_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,19 +224,58 @@ def __array_namespace__(self: array, /, *, api_version: Optional[str] = None) ->

def __bool__(self: array, /) -> bool:
"""
Converts a zero-dimensional boolean array to a Python ``bool`` object.
Converts a zero-dimensional array to a Python ``bool`` object.

**Special cases**

For real-valued floating-point operands,

- If ``self`` is ``NaN``, the result is ``True``.
- If ``self`` is either ``+infinity`` or ``-infinity``, the result is ``True``.
- If ``self`` is either ``+0`` or ``-0``, the result is ``False``.

For complex floating-point operands, special cases must be handled as if the operation is implemented as the logical AND of ``bool(real(self))`` and ``bool(imag(self))``.

Parameters
----------
self: array
zero-dimensional array instance. Must have a boolean data type.
zero-dimensional array instance.

Returns
-------
out: bool
a Python ``bool`` object representing the single element of the array.
"""

def __complex__(self: array, /) -> complex:
honno marked this conversation as resolved.
Show resolved Hide resolved
"""
Converts a zero-dimensional array to a Python ``complex`` object.

**Special cases**

For boolean operands,

- If ``self`` is ``True``, the result is ``1+0j``.
- If ``self`` is ``False``, the result is ``0+0j``.

For real-valued floating-point operands,

- If ``self`` is ``NaN``, the result is ``NaN + NaN j``.
- If ``self`` is ``+infinity``, the result is ``+infinity + 0j``.
- If ``self`` is ``-infinity``, the result is ``-infinity + 0j``.
- If ``self`` is a finite number, the result is ``self + 0j``.

Parameters
----------
self: array
zero-dimensional array instance.

Returns
-------
out: complex
a Python ``complex`` object representing the single element of the array instance.
"""

def __dlpack__(self: array, /, *, stream: Optional[Union[int, Any]] = None) -> PyCapsule:
"""
Exports the array for consumption by :func:`~array_api.from_dlpack` as a DLPack capsule.
Expand Down Expand Up @@ -341,12 +380,22 @@ def __eq__(self: array, other: Union[int, float, bool, array], /) -> array:

def __float__(self: array, /) -> float:
"""
Converts a zero-dimensional floating-point array to a Python ``float`` object.
Converts a zero-dimensional array to a Python ``float`` object.

.. note::
Casting integer values outside the representable bounds of Python's float type is not specified and is implementation-dependent.

**Special cases**

For boolean operands,

- If ``self`` is ``True``, the result is ``1``.
- If ``self`` is ``False``, the result is ``0``.

Parameters
----------
self: array
zero-dimensional array instance. Must have a real-valued floating-point data type.
zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex floating-point data type, the function must raise a ``TypeError``.

Returns
-------
Expand Down Expand Up @@ -483,7 +532,7 @@ def __index__(self: array, /) -> int:
Parameters
----------
self: array
zero-dimensional array instance. Must have an integer data type.
zero-dimensional array instance. Should have an integer data type. If ``self`` has a floating-point data type, the function must raise a ``TypeError``.

Returns
-------
Expand All @@ -493,17 +542,37 @@ def __index__(self: array, /) -> int:

def __int__(self: array, /) -> int:
"""
Converts a zero-dimensional integer array to a Python ``int`` object.
Converts a zero-dimensional array to a Python ``int`` object.

**Special cases**

For boolean operands,

- If ``self`` is ``True``, the result is ``1``.
- If ``self`` is ``False``, the result is ``0``.

For floating-point operands,

- If ``self`` is a finite number, the result is the integer part of ``self``.
kgryte marked this conversation as resolved.
Show resolved Hide resolved
- If ``self`` is ``-0``, the result is ``0``.

Parameters
----------
self: array
zero-dimensional array instance. Must have an integer data type.
zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex floating-point data type, the function must raise a ``TypeError``.

Returns
-------
out: int
a Python ``int`` object representing the single element of the array instance.


**Raises**

For floating-point operands,

- If ``self`` is either ``+infinity`` or ``-infinity``, raise ``OverflowError``.
- If ``self`` is ``NaN``, raise ``ValueError``.
honno marked this conversation as resolved.
Show resolved Hide resolved
"""

def __invert__(self: array, /) -> array:
Expand Down
1 change: 1 addition & 0 deletions spec/API_specification/array_object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ Methods
array.__and__
array.__array_namespace__
array.__bool__
array.__complex__
array.__dlpack__
array.__dlpack_device__
array.__eq__
Expand Down