Repository: quantumlib/Cirq

Issue:
Find a better pattern for implementing control and target keywords and us for control gates.
Currently `CXPowGate` has a special override of `on` which allows one to pass in `control` and `target` when turning into a `GateOperation`.  It seems like we never followed up to do this for any other gates, and if we are going to do this we shouldn't do it in a one off manner.


Discussion:
At the very least the code can be simplified to `def on(self, target, control)` instead of the args/kwargs stuff that's there.

I'm fine with deprecating it.
discussed at Cirq Cync: vote was to keep it, but to do it in a way that is not adding this code to every gate.  

Discussion from cirq cync: cut this.

Resolving patch:
diff --git a/cirq-core/cirq/ops/common_gates.py b/cirq-core/cirq/ops/common_gates.py
--- a/cirq-core/cirq/ops/common_gates.py
+++ b/cirq-core/cirq/ops/common_gates.py
@@ -1264,19 +1264,6 @@ def __repr__(self) -> str:
             f'global_shift={self._global_shift!r})'
         )
 
-    def on(self, *args: 'cirq.Qid', **kwargs: 'cirq.Qid') -> raw_types.Operation:
-        if not kwargs:
-            return super().on(*args)
-        if not args and set(kwargs.keys()) == {'control', 'target'}:
-            return super().on(kwargs['control'], kwargs['target'])
-        raise ValueError(
-            "Expected two positional argument or else 'target' AND 'control' "
-            "keyword arguments. But got args={!r}, kwargs={!r}.".format(args, kwargs)
-        )
-
-    def __call__(self, *qubits: 'cirq.Qid', **kwargs: 'cirq.Qid'):
-        return self.on(*qubits, **kwargs)
-
 
 def rx(rads: value.TParamVal) -> Rx:
     """Returns a gate with the matrix e^{-i X rads / 2}."""


Test patch:
diff --git a/cirq-core/cirq/ops/common_gates_test.py b/cirq-core/cirq/ops/common_gates_test.py
--- a/cirq-core/cirq/ops/common_gates_test.py
+++ b/cirq-core/cirq/ops/common_gates_test.py
@@ -740,47 +740,6 @@ def test_cnot_unitary():
     )
 
 
-def test_cnot_keyword_arguments():
-    a = cirq.NamedQubit('a')
-    b = cirq.NamedQubit('b')
-
-    eq_tester = cirq.testing.EqualsTester()
-    eq_tester.add_equality_group(cirq.CNOT(a, b), cirq.CNOT(control=a, target=b))
-    eq_tester.add_equality_group(cirq.CNOT(b, a), cirq.CNOT(control=b, target=a))
-
-
-def test_cnot_keyword_not_equal():
-    a = cirq.NamedQubit('a')
-    b = cirq.NamedQubit('b')
-
-    with pytest.raises(AssertionError):
-        eq_tester = cirq.testing.EqualsTester()
-        eq_tester.add_equality_group(cirq.CNOT(a, b), cirq.CNOT(target=a, control=b))
-
-
-def test_cnot_keyword_too_few_arguments():
-    a = cirq.NamedQubit('a')
-
-    with pytest.raises(ValueError):
-        _ = cirq.CNOT(control=a)
-
-
-def test_cnot_mixed_keyword_and_positional_arguments():
-    a = cirq.NamedQubit('a')
-    b = cirq.NamedQubit('b')
-
-    with pytest.raises(ValueError):
-        _ = cirq.CNOT(a, target=b)
-
-
-def test_cnot_unknown_keyword_argument():
-    a = cirq.NamedQubit('a')
-    b = cirq.NamedQubit('b')
-
-    with pytest.raises(ValueError):
-        _ = cirq.CNOT(target=a, controlled=b)
-
-
 def test_cnot_decompose():
     a = cirq.NamedQubit('a')
     b = cirq.NamedQubit('b')