Repository: Qiskit/qiskit

Issue:
Allow for np.integer as pulse duration
<!-- ⚠️ 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?
`duration` of pulse command should be python integer, but this limitation might degrade usability. It is better to allow for `np.integers` - e.g. when we prepare series of pulse commands with many durations with `np.arange`.


Discussion:

Resolving patch:
diff --git a/qiskit/pulse/commands/command.py b/qiskit/pulse/commands/command.py
--- a/qiskit/pulse/commands/command.py
+++ b/qiskit/pulse/commands/command.py
@@ -18,7 +18,8 @@
 import re
 
 from abc import ABCMeta, abstractmethod
-from typing import List, Optional
+from typing import List, Optional, Union
+import numpy as np
 
 from qiskit.pulse.exceptions import PulseError
 from qiskit.pulse.channels import Channel
@@ -42,7 +43,7 @@ class Command(metaclass=MetaCount):
     prefix = 'c'
 
     @abstractmethod
-    def __init__(self, duration: int = None):
+    def __init__(self, duration: Union[int, np.integer] = None):
         """Create a new command.
 
         Args:
@@ -50,8 +51,8 @@ def __init__(self, duration: int = None):
         Raises:
             PulseError: when duration is not number of points
         """
-        if isinstance(duration, int):
-            self._duration = duration
+        if isinstance(duration, (int, np.integer)):
+            self._duration = int(duration)
         else:
             raise PulseError('Pulse duration should be integer.')
 
diff --git a/qiskit/pulse/commands/pulse_decorators.py b/qiskit/pulse/commands/pulse_decorators.py
--- a/qiskit/pulse/commands/pulse_decorators.py
+++ b/qiskit/pulse/commands/pulse_decorators.py
@@ -38,7 +38,7 @@ def functional_pulse(func: Callable):
     @functools.wraps(func)
     def to_pulse(duration, *args, name=None, **kwargs):
         """Return SamplePulse."""
-        if isinstance(duration, int) and duration > 0:
+        if isinstance(duration, (int, np.integer)) and duration > 0:
             samples = func(duration, *args, **kwargs)
             samples = np.asarray(samples, dtype=np.complex128)
             return SamplePulse(samples=samples, name=name)


Test patch:
diff --git a/test/python/pulse/test_commands.py b/test/python/pulse/test_commands.py
--- a/test/python/pulse/test_commands.py
+++ b/test/python/pulse/test_commands.py
@@ -102,6 +102,21 @@ def gaussian(duration, amp, t0, sig):
         # check duration
         self.assertEqual(pulse_command.duration, 10)
 
+    def test_variable_duration(self):
+        """Test generation of sample pulse with variable duration.
+        """
+
+        @functional_pulse
+        def gaussian(duration, amp, t0, sig):
+            x = np.linspace(0, duration - 1, duration)
+            return amp * np.exp(-(x - t0) ** 2 / sig ** 2)
+
+        _durations = np.arange(10, 15, 1)
+
+        for _duration in _durations:
+            pulse_command = gaussian(duration=_duration, amp=1, t0=5, sig=1)
+            self.assertEqual(len(pulse_command.samples), _duration)
+
 
 class TestPersistentValue(QiskitTestCase):
     """PersistentValue tests."""