Qiskit-terra: Using a numpy integer type as an index for a QuantumRegister fails

Created on 4 Mar 2020  路  16Comments  路  Source: Qiskit/qiskit-terra

Information

  • Qiskit Terra version: 0.11.1
  • Python version: 3.7.6
  • Operating system: Ubuntu 18.04.4 LTS

What is the current behavior?

An error is raised:

File "/lib/python3.7/site-packages/qiskit/circuit/register.py", line 90, in __getitem__
    raise CircuitError("expected integer or slice index into register")
qiskit.circuit.exceptions.CircuitError: 'expected integer or slice index into register'

Steps to reproduce the problem

from qiskit import QuantumRegister
import numpy as np
qr = QuantumRegister(3)
qubit_index = np.int64(0)
qubit = qr[qubit_index]

What is the expected behavior?

Since numpy is used extensively in scientific programming, the type checking should not be as strict.

Suggested solutions

Change line 89 of register.py from:

if not isinstance(key, (int, slice, list)):

to

if not isinstance(key, (int, slice, list, np.integer)):
bug

Most helpful comment

Hi, I am keen to contribute to solving this as my first issue. Can I work on this?

All 16 comments

@bjader I agree, please feel free to push a PR with your suggested change (probably with a unit test covering passing a numpy int in), it'll be an easy approval :)

Great, I'll get round to it over the next few days! Looking forward to my first PR

Why not use the Python numbers library here?

@nonhermitian In what way? Does the numbers library have a common type between python ints and numpy ints? I'm not familiar with the library.

Edit: Aha, as such?

isinstance(np.int64(0), numbers.Number)
Out[31]: True

Everything should be a numbers.Number

But floats and complex are also numbers.

I think the approach should be trying casting to int before the type check. My 2 cents.

isinstance(foo, numbers.Integral) and 0 <= foo < len(self) should cover those cases.

Agree, in general, try/catch is more pythonic (and would simplify implementation), but would leave gaps for users who are new to python. e.g. int(3.5) == 3.

Actually, numbers.Integral evaluates to False if passed a complex. So using Integral should be fine I think.

If another user wants to make the change / pull request please feel free. Unfortunately, I've become swamped since the pandemic.

Hi, I am keen to contribute to solving this as my first issue. Can I work on this?

Yes that would be great! Do you know where to start or do you need a hand? 馃檪

Thank you!
I changed line 120/121 of register.py from:

if not isinstance(key, (int, slice, list)):

to

if not isinstance(key, (int, slice, list, np.integer)):

as suggested above and it works:
image
Can I make a pull request?

Can you use numbers.Integral instead, as it also covers other integer types? I.e.

if not isinstance(key, (numbers.Integral, slice, list)):

Yes numbers.Integral works too

Then you can open a PR 馃憤

Thank you, just opened a PR!

Was this page helpful?
0 / 5 - 0 ratings