Repository: Qiskit/qiskit

Issue:
Error when number of qubits is of type numpy.int64
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues to confirm this idea does not exist. -->

### What is the expected enhancement?

In `qiskit/validation/base.py`, function `check_types`: currently, if `n_qubits` or `memory_slots` are of type `numpy.int64`, then an error is triggered, because type `int` is expected.

I find it too strict. Especially considering that if the number of qubits is originated in a `numpy` array, then its default type is `numpy.int64`. Terra can allow additional types, or convert the type internally.



Discussion:
Good catch @yaelbh . Do you mind write a small snippet to illustrate the issue? We can add it as a test.
```
>>> import qiskit as qk
>>> import numpy as np
>>> n = np.int64(5)
>>> qr = qk.QuantumRegister(n)
>>> qc = qk.QuantumCircuit(qr)
>>> qobj = qk.assemble_circuits(qc)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/compiler/assembler.py", line 72, in assemble_circuits
    experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots)
  File "/Users/kevin.krsulichibm.com/q/qiskit-terra/qiskit/validation/base.py", line 245, in _decorated
    ex.messages, ex.field_names, ex.fields, ex.data, **ex.kwargs) from None
qiskit.validation.exceptions.ModelValidationError: {'n_qubits': ["Value '5' is not the expected type <class 'int'>"]}
```
I'm not sure how the validation checks, but for a straight up type check you can use `isinstance(obj, (int, np.integer))` or `np.issubdtype(type(obj), np.integer)` to work for both python and numpy int types.

Resolving patch:
diff --git a/qiskit/circuit/register.py b/qiskit/circuit/register.py
--- a/qiskit/circuit/register.py
+++ b/qiskit/circuit/register.py
@@ -36,21 +36,29 @@ def __init__(self, size, name=None):
         """Create a new generic register.
         """
 
+        # validate (or cast) size
+        try:
+            size = int(size)
+        except Exception:
+            raise QiskitError("size needs to be castable to an int")
+        if size <= 0:
+            raise QiskitError("register size must be positive")
+
+        # validate (or cast) name
         if name is None:
             name = '%s%i' % (self.prefix, next(self.instances_counter))
-
-        if not isinstance(name, str):
-            raise QiskitError("The circuit name should be a string "
-                              "(or None for autogenerate a name).")
-
-        test = re.compile('[a-z][a-zA-Z0-9_]*')
-        if test.match(name) is None:
-            raise QiskitError("%s is an invalid OPENQASM register name." % name)
+        else:
+            try:
+                name = str(name)
+            except Exception:
+                raise QiskitError("The circuit name should be castable to a string "
+                                  "(or None for autogenerate a name).")
+            name_format = re.compile('[a-z][a-zA-Z0-9_]*')
+            if name_format.match(name) is None:
+                raise QiskitError("%s is an invalid OPENQASM register name." % name)
 
         self.name = name
         self.size = size
-        if size <= 0:
-            raise QiskitError("register size must be positive")
 
     def __repr__(self):
         """Return the official string representing the register."""
@@ -106,7 +114,7 @@ def __iter__(self):
             iterator: an iterator over the bits/qubits of the register, in the
                 form `tuple (Register, int)`.
         """
-        return zip([self]*self.size, range(self.size))
+        return zip([self] * self.size, range(self.size))
 
     def __eq__(self, other):
         """Two Registers are the same if they are of the same type


Test patch:
diff --git a/test/python/circuit/test_circuit_registers.py b/test/python/circuit/test_circuit_registers.py
--- a/test/python/circuit/test_circuit_registers.py
+++ b/test/python/circuit/test_circuit_registers.py
@@ -19,6 +19,7 @@
 import os
 import tempfile
 import unittest
+import numpy as np
 
 import qiskit.extensions.simulator
 from qiskit import BasicAer
@@ -48,6 +49,25 @@ def test_cregs(self):
         self.assertEqual(cr1.size, 10)
         self.assertEqual(type(cr1), ClassicalRegister)
 
+    def test_qarg_negative_size(self):
+        """Test attempt to create a negative size QuantumRegister.
+        """
+        self.assertRaises(qiskit.exceptions.QiskitError, QuantumRegister, -1)
+
+    def test_qarg_string_size(self):
+        """Test attempt to create a non-integer size QuantumRegister.
+        """
+        self.assertRaises(qiskit.exceptions.QiskitError, QuantumRegister, 'string')
+
+    def test_qarg_numpy_int_size(self):
+        """Test castable to integer size QuantumRegister.
+        """
+        np_int = np.dtype('int').type(10)
+        qr1 = QuantumRegister(np_int, "q")
+        self.assertEqual(qr1.name, "q")
+        self.assertEqual(qr1.size, 10)
+        self.assertEqual(type(qr1), QuantumRegister)
+
     def test_negative_index(self):
         """Test indexing from the back
         """
@@ -175,8 +195,8 @@ def test_apply_ccx_to_slice(self):
         for i, ictl, (gate, qargs, _) in zip(range(len(qc.data)), range(0, 10, 2), qc.data):
             self.assertEqual(gate.name, 'ccx')
             self.assertEqual(len(qargs), 3)
-            self.assertIn(qargs[0][1], [ictl, ictl+1])
-            self.assertIn(qargs[1][1], [ictl, ictl+1])
+            self.assertIn(qargs[0][1], [ictl, ictl + 1])
+            self.assertIn(qargs[1][1], [ictl, ictl + 1])
             self.assertEqual(qargs[2][1], i)
         # test decrementing slice
         qc = QuantumCircuit(qcontrol, qtarget)