numpy / numpy/numpy

BUG: `numpy.str_` and `numpy.bytes_` scalars do not support `[()]` indexing despite having `shape == ()`

Open
#31,435 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

00 - Bug
Dominant language
Python
Stars
32.8k
Forks
12.8k
Avg merge
1d 7h
Merged PRs (30d)
197

Description

Describe the issue:

numpy.str_ and numpy.bytes_ are 0-dimensional numpy scalars (shape == (), ndim == 0), yet indexing them with [()] (empty tuple, which is the standard way to extract the value from a 0-d array/scalar) raises a TypeError. This is inconsistent with all other numpy scalar types where scalar[()] works correctly.

The issue appears to be that Python's str.__getitem__ / bytes.__getitem__ takes priority over numpy's scalar indexing protocol, interpreting () as a tuple index into the string/bytes sequence rather than as a 0-d array index.

Expected behavior

numpy.str_('hello')[()] should return 'hello' (the Python str value), consistent with how numpy.int64(5)[()] returns 5.

Since numpy.str_ reports shape == () and ndim == 0, it should support the standard 0-d indexing protocol that all other numpy scalars support. Code that generically extracts values from 0-d numpy scalars via val[()] breaks specifically for string and bytes scalars.

Workaround

Use .item() instead of [()]:

np.str_('hello').item()   # => 'hello'  (works)
np.bytes_(b'hello').item()  # => b'hello'  (works)

.item() works consistently across all numpy scalar types.

Reproduce the code example:
import numpy as np

# All other numpy scalar types support [()] indexing:
assert np.int64(5)[()] == 5
assert np.float64(3.14)[()] == 3.14
assert np.bool_(True)[()] == True
assert np.complex128(1+2j)[()] == (1+2j)

# numpy.str_ and numpy.bytes_ do NOT, despite having shape == ():
s = np.str_('hello')
print(f"type: {type(s)}, shape: {s.shape}, ndim: {s.ndim}")  # shape=(), ndim=0

s[()]  # TypeError: string indices must be integers, not 'tuple'

b = np.bytes_(b'hello')
print(f"type: {type(b)}, shape: {b.shape}, ndim: {b.ndim}")  # shape=(), ndim=0

b[()]  # TypeError: byte indices must be integers or slices, not tuple
Error message:
TypeError: string indices must be integers, not 'tuple'



TypeError: byte indices must be integers or slices, not tuple
Python and NumPy Versions:
numpy version: 2.2.6
Python 3.11.2 (main, Aug 26 2024, 07:20:54) [GCC 12.2.0]
Runtime Environment:

No response

How does this issue affect you or how did you find it:

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the provided reproduction for numpy.str_ and numpy.bytes_ and compare it with the working scalar examples using [()]. Start by tracing the scalar indexing path around the Python string/bytes indexing behavior and NumPy's 0-dimensional scalar protocol. Done means both string and bytes scalars accept [()] and return their Python values without breaking existing indexing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
57/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.