We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
WaitGate on multiple qubits gets confused about num_qubits when resolved
**Description of the issue**
`WaitGate.num_qubits()` appears to mutate when going through parameter resolution.

**How to reproduce the issue**

```python
g = cirq.wait(cirq.LineQubit(1), cirq.LineQubit(2))
cirq.resolve_parameters(g, {'a': 1})
```

<details>
File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/protocols/resolve_parameters.py:184, in resolve_parameters(val, param_resolver, recursive)
    182     result = NotImplemented
    183 else:
--> 184     result = getter(param_resolver, recursive)
    186 if result is not NotImplemented:
    187     return result

File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/gate_operation.py:278, in GateOperation._resolve_parameters_(self, resolver, recursive)
    274 def _resolve_parameters_(
    275     self, resolver: 'cirq.ParamResolver', recursive: bool
    276 ) -> 'cirq.Operation':
    277     resolved_gate = protocols.resolve_parameters(self.gate, resolver, recursive)
--> 278     return self.with_gate(resolved_gate)

File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/gate_operation.py:82, in GateOperation.with_gate(self, new_gate)
     79 if self.gate is new_gate:
     80     # As GateOperation is immutable, this can return the original.
     81     return self
---> 82 return new_gate.on(*self.qubits)

File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/raw_types.py:219, in Gate.on(self, *qubits)
    213 def on(self, *qubits: Qid) -> 'Operation':
    214     """Returns an application of this gate to the given qubits.
    215 
    216     Args:
    217         *qubits: The collection of qubits to potentially apply the gate to.
    218     """
--> 219     return ops.gate_operation.GateOperation(self, list(qubits))

File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/gate_operation.py:61, in GateOperation.__init__(self, gate, qubits)
     54 def __init__(self, gate: 'cirq.Gate', qubits: Sequence['cirq.Qid']) -> None:
     55     """Inits GateOperation.
     56 
     57     Args:
     58         gate: The gate to apply.
     59         qubits: The qubits to operate on.
     60     """
---> 61     gate.validate_args(qubits)
     62     self._gate = gate
     63     self._qubits = tuple(qubits)

File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/raw_types.py:211, in Gate.validate_args(self, qubits)
    194 def validate_args(self, qubits: Sequence['cirq.Qid']) -> None:
    195     """Checks if this gate can be applied to the given qubits.
    196 
    197     By default checks that:
   (...)
    209         ValueError: The gate can't be applied to the qubits.
    210     """
--> 211     _validate_qid_shape(self, qubits)

File ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/raw_types.py:929, in _validate_qid_shape(val, qubits)
    927 qid_shape = protocols.qid_shape(val)
    928 if len(qubits) != len(qid_shape):
--> 929     raise ValueError(
    930         'Wrong number of qubits for <{!r}>. '
    931         'Expected {} qubits but got <{!r}>.'.format(val, len(qid_shape), qubits)
    932     )
    933 if any(qid.dimension != dimension for qid, dimension in zip(qubits, qid_shape)):
    934     raise ValueError(
    935         'Wrong shape of qids for <{!r}>. '
    936         'Expected {} but got {} <{!r}>.'.format(
    937             val, qid_shape, tuple(qid.dimension for qid in qubits), qubits
    938         )
    939     )

ValueError: Wrong number of qubits for <cirq.WaitGate(cirq.Duration(millis=0))>. Expected 1 qubits but got <[cirq.LineQubit(1), cirq.LineQubit(2)]>.
</details>

**Cirq version**
'0.15.0.dev20220503224557'




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cirq-core/cirq/ops/wait_gate.py`
Content:
```
1 # Copyright 2019 The Cirq Developers
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     https://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 from typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING, Union
15 
16 import sympy
17 
18 from cirq import value, protocols
19 from cirq.ops import raw_types
20 
21 if TYPE_CHECKING:
22     import cirq
23 
24 
25 @value.value_equality
26 class WaitGate(raw_types.Gate):
27     r"""An idle gate that represents waiting.
28 
29     In non-noisy simulators, this gate is just an identity gate. But noisy
30     simulators and noise models may insert more error for longer waits.
31     """
32 
33     def __init__(
34         self,
35         duration: 'cirq.DURATION_LIKE',
36         num_qubits: Optional[int] = None,
37         qid_shape: Tuple[int, ...] = None,
38     ) -> None:
39         """Initialize a wait gate with the given duration.
40 
41         Args:
42             duration: A constant or parameterized wait duration. This can be
43                 an instance of `datetime.timedelta` or `cirq.Duration`.
44             num_qubits: The number of qubits the gate operates on. If None and `qid_shape` is None,
45                 this defaults to one qubit.
46             qid_shape: Can be specified instead of `num_qubits` for the case that the gate should
47                 act on qudits.
48 
49         Raises:
50             ValueError: If the `qid_shape` provided is empty or `num_qubits` contradicts
51                 `qid_shape`.
52         """
53         self._duration = value.Duration(duration)
54         if not protocols.is_parameterized(self.duration) and self.duration < 0:
55             raise ValueError('duration < 0')
56         if qid_shape is None:
57             if num_qubits is None:
58                 # Assume one qubit for backwards compatibility
59                 qid_shape = (2,)
60             else:
61                 qid_shape = (2,) * num_qubits
62         if num_qubits is None:
63             num_qubits = len(qid_shape)
64         if not qid_shape:
65             raise ValueError('Waiting on an empty set of qubits.')
66         if num_qubits != len(qid_shape):
67             raise ValueError('len(qid_shape) != num_qubits')
68         self._qid_shape = qid_shape
69 
70     @property
71     def duration(self) -> 'cirq.Duration':
72         return self._duration
73 
74     def _is_parameterized_(self) -> bool:
75         return protocols.is_parameterized(self.duration)
76 
77     def _parameter_names_(self) -> AbstractSet[str]:
78         return protocols.parameter_names(self.duration)
79 
80     def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'WaitGate':
81         return WaitGate(protocols.resolve_parameters(self.duration, resolver, recursive))
82 
83     def _qid_shape_(self) -> Tuple[int, ...]:
84         return self._qid_shape
85 
86     def _has_unitary_(self) -> bool:
87         return True
88 
89     def _apply_unitary_(self, args):
90         return args.target_tensor  # Identity.
91 
92     def _decompose_(self, qubits):
93         return []
94 
95     def _trace_distance_bound_(self):
96         return 0
97 
98     def __pow__(self, power):
99         if power == 1 or power == -1:
100             # The inverse of a wait is still a wait.
101             return self
102         # Other scalar exponents could scale the wait... but ultimately it is
103         # ambiguous whether the user wanted to scale the duration or just wanted
104         # to affect the unitary. Play it safe and fail.
105         return NotImplemented
106 
107     def __str__(self) -> str:
108         return f'WaitGate({self.duration})'
109 
110     def __repr__(self) -> str:
111         return f'cirq.WaitGate({repr(self.duration)})'
112 
113     def _json_dict_(self) -> Dict[str, Any]:
114         d = protocols.obj_to_dict_helper(self, ['duration'])
115         if len(self._qid_shape) != 1:
116             d['num_qubits'] = len(self._qid_shape)
117         if any(d != 2 for d in self._qid_shape):
118             d['qid_shape'] = self._qid_shape
119         return d
120 
121     @classmethod
122     def _from_json_dict_(cls, duration, num_qubits=None, qid_shape=None, **kwargs):
123         return cls(
124             duration=duration,
125             num_qubits=num_qubits,
126             qid_shape=None if qid_shape is None else tuple(qid_shape),
127         )
128 
129     def _value_equality_values_(self) -> Any:
130         return self.duration
131 
132     def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter'):
133         return 'WAIT\n'
134 
135 
136 def wait(
137     *target: 'cirq.Qid',
138     duration: 'cirq.DURATION_LIKE' = None,
139     picos: Union[int, float, sympy.Expr] = 0,
140     nanos: Union[int, float, sympy.Expr] = 0,
141     micros: Union[int, float, sympy.Expr] = 0,
142     millis: Union[int, float, sympy.Expr] = 0,
143 ) -> raw_types.Operation:
144     """Creates a WaitGate applied to all the given qubits.
145 
146     The duration can be specified as a DURATION_LIKE or using keyword args with
147     numbers in the appropriate units. See Duration for details.
148 
149     Args:
150         *target: The qubits that should wait.
151         duration: Wait duration (see Duration).
152         picos: Picoseconds to wait (see Duration).
153         nanos: Nanoseconds to wait (see Duration).
154         micros: Microseconds to wait (see Duration).
155         millis: Milliseconds to wait (see Duration).
156     """
157     return WaitGate(
158         duration=value.Duration(duration, picos=picos, nanos=nanos, micros=micros, millis=millis),
159         qid_shape=protocols.qid_shape(target),
160     ).on(*target)
161
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cirq-core/cirq/ops/wait_gate.py b/cirq-core/cirq/ops/wait_gate.py
--- a/cirq-core/cirq/ops/wait_gate.py
+++ b/cirq-core/cirq/ops/wait_gate.py
@@ -78,7 +78,10 @@
         return protocols.parameter_names(self.duration)
 
     def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'WaitGate':
-        return WaitGate(protocols.resolve_parameters(self.duration, resolver, recursive))
+        return WaitGate(
+            protocols.resolve_parameters(self.duration, resolver, recursive),
+            qid_shape=self._qid_shape,
+        )
 
     def _qid_shape_(self) -> Tuple[int, ...]:
         return self._qid_shape

{"golden_diff": "diff --git a/cirq-core/cirq/ops/wait_gate.py b/cirq-core/cirq/ops/wait_gate.py\n--- a/cirq-core/cirq/ops/wait_gate.py\n+++ b/cirq-core/cirq/ops/wait_gate.py\n@@ -78,7 +78,10 @@\n         return protocols.parameter_names(self.duration)\n \n     def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'WaitGate':\n-        return WaitGate(protocols.resolve_parameters(self.duration, resolver, recursive))\n+        return WaitGate(\n+            protocols.resolve_parameters(self.duration, resolver, recursive),\n+            qid_shape=self._qid_shape,\n+        )\n \n     def _qid_shape_(self) -> Tuple[int, ...]:\n         return self._qid_shape\n", "issue": "WaitGate on multiple qubits gets confused about num_qubits when resolved\n**Description of the issue**\r\n`WaitGate.num_qubits()` appears to mutate when going through parameter resolution.\r\n\r\n**How to reproduce the issue**\r\n\r\n```python\r\ng = cirq.wait(cirq.LineQubit(1), cirq.LineQubit(2))\r\ncirq.resolve_parameters(g, {'a': 1})\r\n```\r\n\r\n<details>\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/protocols/resolve_parameters.py:184, in resolve_parameters(val, param_resolver, recursive)\r\n    182     result = NotImplemented\r\n    183 else:\r\n--> 184     result = getter(param_resolver, recursive)\r\n    186 if result is not NotImplemented:\r\n    187     return result\r\n\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/gate_operation.py:278, in GateOperation._resolve_parameters_(self, resolver, recursive)\r\n    274 def _resolve_parameters_(\r\n    275     self, resolver: 'cirq.ParamResolver', recursive: bool\r\n    276 ) -> 'cirq.Operation':\r\n    277     resolved_gate = protocols.resolve_parameters(self.gate, resolver, recursive)\r\n--> 278     return self.with_gate(resolved_gate)\r\n\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/gate_operation.py:82, in GateOperation.with_gate(self, new_gate)\r\n     79 if self.gate is new_gate:\r\n     80     # As GateOperation is immutable, this can return the original.\r\n     81     return self\r\n---> 82 return new_gate.on(*self.qubits)\r\n\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/raw_types.py:219, in Gate.on(self, *qubits)\r\n    213 def on(self, *qubits: Qid) -> 'Operation':\r\n    214     \"\"\"Returns an application of this gate to the given qubits.\r\n    215 \r\n    216     Args:\r\n    217         *qubits: The collection of qubits to potentially apply the gate to.\r\n    218     \"\"\"\r\n--> 219     return ops.gate_operation.GateOperation(self, list(qubits))\r\n\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/gate_operation.py:61, in GateOperation.__init__(self, gate, qubits)\r\n     54 def __init__(self, gate: 'cirq.Gate', qubits: Sequence['cirq.Qid']) -> None:\r\n     55     \"\"\"Inits GateOperation.\r\n     56 \r\n     57     Args:\r\n     58         gate: The gate to apply.\r\n     59         qubits: The qubits to operate on.\r\n     60     \"\"\"\r\n---> 61     gate.validate_args(qubits)\r\n     62     self._gate = gate\r\n     63     self._qubits = tuple(qubits)\r\n\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/raw_types.py:211, in Gate.validate_args(self, qubits)\r\n    194 def validate_args(self, qubits: Sequence['cirq.Qid']) -> None:\r\n    195     \"\"\"Checks if this gate can be applied to the given qubits.\r\n    196 \r\n    197     By default checks that:\r\n   (...)\r\n    209         ValueError: The gate can't be applied to the qubits.\r\n    210     \"\"\"\r\n--> 211     _validate_qid_shape(self, qubits)\r\n\r\nFile ~/.virtualenvs/pyle/lib/python3.8/site-packages/cirq/ops/raw_types.py:929, in _validate_qid_shape(val, qubits)\r\n    927 qid_shape = protocols.qid_shape(val)\r\n    928 if len(qubits) != len(qid_shape):\r\n--> 929     raise ValueError(\r\n    930         'Wrong number of qubits for <{!r}>. '\r\n    931         'Expected {} qubits but got <{!r}>.'.format(val, len(qid_shape), qubits)\r\n    932     )\r\n    933 if any(qid.dimension != dimension for qid, dimension in zip(qubits, qid_shape)):\r\n    934     raise ValueError(\r\n    935         'Wrong shape of qids for <{!r}>. '\r\n    936         'Expected {} but got {} <{!r}>.'.format(\r\n    937             val, qid_shape, tuple(qid.dimension for qid in qubits), qubits\r\n    938         )\r\n    939     )\r\n\r\nValueError: Wrong number of qubits for <cirq.WaitGate(cirq.Duration(millis=0))>. Expected 1 qubits but got <[cirq.LineQubit(1), cirq.LineQubit(2)]>.\r\n</details>\r\n\r\n**Cirq version**\r\n'0.15.0.dev20220503224557'\r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright 2019 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING, Union\n\nimport sympy\n\nfrom cirq import value, protocols\nfrom cirq.ops import raw_types\n\nif TYPE_CHECKING:\n    import cirq\n\n\n@value.value_equality\nclass WaitGate(raw_types.Gate):\n    r\"\"\"An idle gate that represents waiting.\n\n    In non-noisy simulators, this gate is just an identity gate. But noisy\n    simulators and noise models may insert more error for longer waits.\n    \"\"\"\n\n    def __init__(\n        self,\n        duration: 'cirq.DURATION_LIKE',\n        num_qubits: Optional[int] = None,\n        qid_shape: Tuple[int, ...] = None,\n    ) -> None:\n        \"\"\"Initialize a wait gate with the given duration.\n\n        Args:\n            duration: A constant or parameterized wait duration. This can be\n                an instance of `datetime.timedelta` or `cirq.Duration`.\n            num_qubits: The number of qubits the gate operates on. If None and `qid_shape` is None,\n                this defaults to one qubit.\n            qid_shape: Can be specified instead of `num_qubits` for the case that the gate should\n                act on qudits.\n\n        Raises:\n            ValueError: If the `qid_shape` provided is empty or `num_qubits` contradicts\n                `qid_shape`.\n        \"\"\"\n        self._duration = value.Duration(duration)\n        if not protocols.is_parameterized(self.duration) and self.duration < 0:\n            raise ValueError('duration < 0')\n        if qid_shape is None:\n            if num_qubits is None:\n                # Assume one qubit for backwards compatibility\n                qid_shape = (2,)\n            else:\n                qid_shape = (2,) * num_qubits\n        if num_qubits is None:\n            num_qubits = len(qid_shape)\n        if not qid_shape:\n            raise ValueError('Waiting on an empty set of qubits.')\n        if num_qubits != len(qid_shape):\n            raise ValueError('len(qid_shape) != num_qubits')\n        self._qid_shape = qid_shape\n\n    @property\n    def duration(self) -> 'cirq.Duration':\n        return self._duration\n\n    def _is_parameterized_(self) -> bool:\n        return protocols.is_parameterized(self.duration)\n\n    def _parameter_names_(self) -> AbstractSet[str]:\n        return protocols.parameter_names(self.duration)\n\n    def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'WaitGate':\n        return WaitGate(protocols.resolve_parameters(self.duration, resolver, recursive))\n\n    def _qid_shape_(self) -> Tuple[int, ...]:\n        return self._qid_shape\n\n    def _has_unitary_(self) -> bool:\n        return True\n\n    def _apply_unitary_(self, args):\n        return args.target_tensor  # Identity.\n\n    def _decompose_(self, qubits):\n        return []\n\n    def _trace_distance_bound_(self):\n        return 0\n\n    def __pow__(self, power):\n        if power == 1 or power == -1:\n            # The inverse of a wait is still a wait.\n            return self\n        # Other scalar exponents could scale the wait... but ultimately it is\n        # ambiguous whether the user wanted to scale the duration or just wanted\n        # to affect the unitary. Play it safe and fail.\n        return NotImplemented\n\n    def __str__(self) -> str:\n        return f'WaitGate({self.duration})'\n\n    def __repr__(self) -> str:\n        return f'cirq.WaitGate({repr(self.duration)})'\n\n    def _json_dict_(self) -> Dict[str, Any]:\n        d = protocols.obj_to_dict_helper(self, ['duration'])\n        if len(self._qid_shape) != 1:\n            d['num_qubits'] = len(self._qid_shape)\n        if any(d != 2 for d in self._qid_shape):\n            d['qid_shape'] = self._qid_shape\n        return d\n\n    @classmethod\n    def _from_json_dict_(cls, duration, num_qubits=None, qid_shape=None, **kwargs):\n        return cls(\n            duration=duration,\n            num_qubits=num_qubits,\n            qid_shape=None if qid_shape is None else tuple(qid_shape),\n        )\n\n    def _value_equality_values_(self) -> Any:\n        return self.duration\n\n    def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter'):\n        return 'WAIT\\n'\n\n\ndef wait(\n    *target: 'cirq.Qid',\n    duration: 'cirq.DURATION_LIKE' = None,\n    picos: Union[int, float, sympy.Expr] = 0,\n    nanos: Union[int, float, sympy.Expr] = 0,\n    micros: Union[int, float, sympy.Expr] = 0,\n    millis: Union[int, float, sympy.Expr] = 0,\n) -> raw_types.Operation:\n    \"\"\"Creates a WaitGate applied to all the given qubits.\n\n    The duration can be specified as a DURATION_LIKE or using keyword args with\n    numbers in the appropriate units. See Duration for details.\n\n    Args:\n        *target: The qubits that should wait.\n        duration: Wait duration (see Duration).\n        picos: Picoseconds to wait (see Duration).\n        nanos: Nanoseconds to wait (see Duration).\n        micros: Microseconds to wait (see Duration).\n        millis: Milliseconds to wait (see Duration).\n    \"\"\"\n    return WaitGate(\n        duration=value.Duration(duration, picos=picos, nanos=nanos, micros=micros, millis=millis),\n        qid_shape=protocols.qid_shape(target),\n    ).on(*target)\n", "path": "cirq-core/cirq/ops/wait_gate.py"}], "after_files": [{"content": "# Copyright 2019 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING, Union\n\nimport sympy\n\nfrom cirq import value, protocols\nfrom cirq.ops import raw_types\n\nif TYPE_CHECKING:\n    import cirq\n\n\n@value.value_equality\nclass WaitGate(raw_types.Gate):\n    r\"\"\"An idle gate that represents waiting.\n\n    In non-noisy simulators, this gate is just an identity gate. But noisy\n    simulators and noise models may insert more error for longer waits.\n    \"\"\"\n\n    def __init__(\n        self,\n        duration: 'cirq.DURATION_LIKE',\n        num_qubits: Optional[int] = None,\n        qid_shape: Tuple[int, ...] = None,\n    ) -> None:\n        \"\"\"Initialize a wait gate with the given duration.\n\n        Args:\n            duration: A constant or parameterized wait duration. This can be\n                an instance of `datetime.timedelta` or `cirq.Duration`.\n            num_qubits: The number of qubits the gate operates on. If None and `qid_shape` is None,\n                this defaults to one qubit.\n            qid_shape: Can be specified instead of `num_qubits` for the case that the gate should\n                act on qudits.\n\n        Raises:\n            ValueError: If the `qid_shape` provided is empty or `num_qubits` contradicts\n                `qid_shape`.\n        \"\"\"\n        self._duration = value.Duration(duration)\n        if not protocols.is_parameterized(self.duration) and self.duration < 0:\n            raise ValueError('duration < 0')\n        if qid_shape is None:\n            if num_qubits is None:\n                # Assume one qubit for backwards compatibility\n                qid_shape = (2,)\n            else:\n                qid_shape = (2,) * num_qubits\n        if num_qubits is None:\n            num_qubits = len(qid_shape)\n        if not qid_shape:\n            raise ValueError('Waiting on an empty set of qubits.')\n        if num_qubits != len(qid_shape):\n            raise ValueError('len(qid_shape) != num_qubits')\n        self._qid_shape = qid_shape\n\n    @property\n    def duration(self) -> 'cirq.Duration':\n        return self._duration\n\n    def _is_parameterized_(self) -> bool:\n        return protocols.is_parameterized(self.duration)\n\n    def _parameter_names_(self) -> AbstractSet[str]:\n        return protocols.parameter_names(self.duration)\n\n    def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'WaitGate':\n        return WaitGate(\n            protocols.resolve_parameters(self.duration, resolver, recursive),\n            qid_shape=self._qid_shape,\n        )\n\n    def _qid_shape_(self) -> Tuple[int, ...]:\n        return self._qid_shape\n\n    def _has_unitary_(self) -> bool:\n        return True\n\n    def _apply_unitary_(self, args):\n        return args.target_tensor  # Identity.\n\n    def _decompose_(self, qubits):\n        return []\n\n    def _trace_distance_bound_(self):\n        return 0\n\n    def __pow__(self, power):\n        if power == 1 or power == -1:\n            # The inverse of a wait is still a wait.\n            return self\n        # Other scalar exponents could scale the wait... but ultimately it is\n        # ambiguous whether the user wanted to scale the duration or just wanted\n        # to affect the unitary. Play it safe and fail.\n        return NotImplemented\n\n    def __str__(self) -> str:\n        return f'WaitGate({self.duration})'\n\n    def __repr__(self) -> str:\n        return f'cirq.WaitGate({repr(self.duration)})'\n\n    def _json_dict_(self) -> Dict[str, Any]:\n        d = protocols.obj_to_dict_helper(self, ['duration'])\n        if len(self._qid_shape) != 1:\n            d['num_qubits'] = len(self._qid_shape)\n        if any(d != 2 for d in self._qid_shape):\n            d['qid_shape'] = self._qid_shape\n        return d\n\n    @classmethod\n    def _from_json_dict_(cls, duration, num_qubits=None, qid_shape=None, **kwargs):\n        return cls(\n            duration=duration,\n            num_qubits=num_qubits,\n            qid_shape=None if qid_shape is None else tuple(qid_shape),\n        )\n\n    def _value_equality_values_(self) -> Any:\n        return self.duration\n\n    def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter'):\n        return 'WAIT\\n'\n\n\ndef wait(\n    *target: 'cirq.Qid',\n    duration: 'cirq.DURATION_LIKE' = None,\n    picos: Union[int, float, sympy.Expr] = 0,\n    nanos: Union[int, float, sympy.Expr] = 0,\n    micros: Union[int, float, sympy.Expr] = 0,\n    millis: Union[int, float, sympy.Expr] = 0,\n) -> raw_types.Operation:\n    \"\"\"Creates a WaitGate applied to all the given qubits.\n\n    The duration can be specified as a DURATION_LIKE or using keyword args with\n    numbers in the appropriate units. See Duration for details.\n\n    Args:\n        *target: The qubits that should wait.\n        duration: Wait duration (see Duration).\n        picos: Picoseconds to wait (see Duration).\n        nanos: Nanoseconds to wait (see Duration).\n        micros: Microseconds to wait (see Duration).\n        millis: Milliseconds to wait (see Duration).\n    \"\"\"\n    return WaitGate(\n        duration=value.Duration(duration, picos=picos, nanos=nanos, micros=micros, millis=millis),\n        qid_shape=protocols.qid_shape(target),\n    ).on(*target)\n", "path": "cirq-core/cirq/ops/wait_gate.py"}]}