We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
_resolve_parameters_ changes are not backwards-compatible
**Description of the issue**

External code that defined a `_resolve_parameters_` magic method for Cirq 0.9 is broken by #3546, which changed the function signature for that method in a non-backwards-compatible way.

**How to reproduce the issue**

Construct a parameterized circuit in Cirq v0.10.0-dev, then attempt to run it in the latest version of qsim.

**Cirq version**

Occurs when upgrading from v0.9.* to v0.10.0-dev

--- 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/protocols/resolve_parameters.py`
Content:
```
1 # Copyright 2018 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 
15 import numbers
16 from typing import AbstractSet, Any, TYPE_CHECKING
17 
18 import sympy
19 from typing_extensions import Protocol
20 
21 from cirq import study
22 from cirq._doc import doc_private
23 
24 if TYPE_CHECKING:
25     import cirq
26 
27 
28 class SupportsParameterization(Protocol):
29     """An object that can be parameterized by Symbols and resolved
30     via a ParamResolver"""
31 
32     @doc_private
33     def _is_parameterized_(self: Any) -> bool:
34         """Whether the object is parameterized by any Symbols that require
35         resolution. Returns True if the object has any unresolved Symbols
36         and False otherwise."""
37 
38     @doc_private
39     def _parameter_names_(self: Any) -> AbstractSet[str]:
40         """Returns a collection of string names of parameters that require
41         resolution. If _is_parameterized_ is False, the collection is empty.
42         The converse is not necessarily true, because some objects may report
43         that they are parameterized when they contain symbolic constants which
44         need to be evaluated, but no free symbols.
45         """
46 
47     @doc_private
48     def _resolve_parameters_(self: Any, param_resolver: 'cirq.ParamResolver', recursive: bool):
49         """Resolve the parameters in the effect."""
50 
51 
52 def is_parameterized(val: Any) -> bool:
53     """Returns whether the object is parameterized with any Symbols.
54 
55     A value is parameterized when it has an `_is_parameterized_` method and
56     that method returns a truthy value, or if the value is an instance of
57     sympy.Basic.
58 
59     Returns:
60         True if the gate has any unresolved Symbols
61         and False otherwise. If no implementation of the magic
62         method above exists or if that method returns NotImplemented,
63         this will default to False.
64     """
65     if isinstance(val, sympy.Basic):
66         return True
67     if isinstance(val, numbers.Number):
68         return False
69     if isinstance(val, (list, tuple)):
70         return any(is_parameterized(e) for e in val)
71 
72     getter = getattr(val, '_is_parameterized_', None)
73     result = NotImplemented if getter is None else getter()
74 
75     if result is not NotImplemented:
76         return result
77 
78     return bool(parameter_names(val))
79 
80 
81 def parameter_names(val: Any) -> AbstractSet[str]:
82     """Returns parameter names for this object.
83 
84     Args:
85         val: Object for which to find the parameter names.
86         check_symbols: If true, fall back to calling parameter_symbols.
87 
88     Returns:
89         A set of parameter names if the object is parameterized. It the object
90         does not implement the _parameter_names_ magic method or that method
91         returns NotImplemented, returns an empty set.
92     """
93     if isinstance(val, sympy.Basic):
94         return {symbol.name for symbol in val.free_symbols}
95     if isinstance(val, numbers.Number):
96         return set()
97     if isinstance(val, (list, tuple)):
98         return {name for e in val for name in parameter_names(e)}
99 
100     getter = getattr(val, '_parameter_names_', None)
101     result = NotImplemented if getter is None else getter()
102     if result is not NotImplemented:
103         return result
104 
105     return set()
106 
107 
108 def parameter_symbols(val: Any) -> AbstractSet[sympy.Symbol]:
109     """Returns parameter symbols for this object.
110 
111     Args:
112         val: Object for which to find the parameter symbols.
113 
114     Returns:
115         A set of parameter symbols if the object is parameterized. It the object
116         does not implement the _parameter_symbols_ magic method or that method
117         returns NotImplemented, returns an empty set.
118     """
119     return {sympy.Symbol(name) for name in parameter_names(val)}
120 
121 
122 def resolve_parameters(
123     val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType', recursive: bool = True
124 ):
125     """Resolves symbol parameters in the effect using the param resolver.
126 
127     This function will use the `_resolve_parameters_` magic method
128     of `val` to resolve any Symbols with concrete values from the given
129     parameter resolver.
130 
131     Args:
132         val: The object to resolve (e.g. the gate, operation, etc)
133         param_resolver: the object to use for resolving all symbols
134         recursive: if True, resolves parameters recursively over the
135             resolver; otherwise performs a single resolution step.
136 
137     Returns:
138         a gate or operation of the same type, but with all Symbols
139         replaced with floats or terminal symbols according to the
140         given ParamResolver. If `val` has no `_resolve_parameters_`
141         method or if it returns NotImplemented, `val` itself is returned.
142 
143     Raises:
144         RecursionError if the ParamResolver detects a loop in resolution.
145     """
146     if not param_resolver:
147         return val
148 
149     # Ensure it is a dictionary wrapped in a ParamResolver.
150     param_resolver = study.ParamResolver(param_resolver)
151     if isinstance(val, sympy.Basic):
152         return param_resolver.value_of(val, recursive)
153     if isinstance(val, (list, tuple)):
154         return type(val)(resolve_parameters(e, param_resolver, recursive) for e in val)
155 
156     getter = getattr(val, '_resolve_parameters_', None)
157     result = NotImplemented if getter is None else getter(param_resolver, recursive)
158 
159     if result is not NotImplemented:
160         return result
161     else:
162         return val
163 
164 
165 def resolve_parameters_once(val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType'):
166     """Performs a single parameter resolution step using the param resolver."""
167     return resolve_parameters(val, param_resolver, False)
168
```
--- 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/protocols/resolve_parameters.py b/cirq/protocols/resolve_parameters.py
--- a/cirq/protocols/resolve_parameters.py
+++ b/cirq/protocols/resolve_parameters.py
@@ -142,6 +142,8 @@
 
     Raises:
         RecursionError if the ParamResolver detects a loop in resolution.
+        ValueError if `recursive=False` is passed to an external
+            _resolve_parameters_ method with no `recursive` parameter.
     """
     if not param_resolver:
         return val
@@ -154,7 +156,19 @@
         return type(val)(resolve_parameters(e, param_resolver, recursive) for e in val)
 
     getter = getattr(val, '_resolve_parameters_', None)
-    result = NotImplemented if getter is None else getter(param_resolver, recursive)
+    if getter is None:
+        result = NotImplemented
+    # Backwards-compatibility for external _resolve_parameters_ methods.
+    # TODO: remove in Cirq v0.11.0
+    elif 'recursive' in getter.__code__.co_varnames:
+        result = getter(param_resolver, recursive)
+    else:
+        if not recursive:
+            raise ValueError(
+                f'Object type {type(val)} does not support non-recursive parameter resolution.'
+                ' This must be updated before Cirq v0.11.'
+            )
+        result = getter(param_resolver)
 
     if result is not NotImplemented:
         return result

{"golden_diff": "diff --git a/cirq/protocols/resolve_parameters.py b/cirq/protocols/resolve_parameters.py\n--- a/cirq/protocols/resolve_parameters.py\n+++ b/cirq/protocols/resolve_parameters.py\n@@ -142,6 +142,8 @@\n \n     Raises:\n         RecursionError if the ParamResolver detects a loop in resolution.\n+        ValueError if `recursive=False` is passed to an external\n+            _resolve_parameters_ method with no `recursive` parameter.\n     \"\"\"\n     if not param_resolver:\n         return val\n@@ -154,7 +156,19 @@\n         return type(val)(resolve_parameters(e, param_resolver, recursive) for e in val)\n \n     getter = getattr(val, '_resolve_parameters_', None)\n-    result = NotImplemented if getter is None else getter(param_resolver, recursive)\n+    if getter is None:\n+        result = NotImplemented\n+    # Backwards-compatibility for external _resolve_parameters_ methods.\n+    # TODO: remove in Cirq v0.11.0\n+    elif 'recursive' in getter.__code__.co_varnames:\n+        result = getter(param_resolver, recursive)\n+    else:\n+        if not recursive:\n+            raise ValueError(\n+                f'Object type {type(val)} does not support non-recursive parameter resolution.'\n+                ' This must be updated before Cirq v0.11.'\n+            )\n+        result = getter(param_resolver)\n \n     if result is not NotImplemented:\n         return result\n", "issue": "_resolve_parameters_ changes are not backwards-compatible\n**Description of the issue**\r\n\r\nExternal code that defined a `_resolve_parameters_` magic method for Cirq 0.9 is broken by #3546, which changed the function signature for that method in a non-backwards-compatible way.\r\n\r\n**How to reproduce the issue**\r\n\r\nConstruct a parameterized circuit in Cirq v0.10.0-dev, then attempt to run it in the latest version of qsim.\r\n\r\n**Cirq version**\r\n\r\nOccurs when upgrading from v0.9.* to v0.10.0-dev\n", "before_files": [{"content": "# Copyright 2018 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.\n\nimport numbers\nfrom typing import AbstractSet, Any, TYPE_CHECKING\n\nimport sympy\nfrom typing_extensions import Protocol\n\nfrom cirq import study\nfrom cirq._doc import doc_private\n\nif TYPE_CHECKING:\n    import cirq\n\n\nclass SupportsParameterization(Protocol):\n    \"\"\"An object that can be parameterized by Symbols and resolved\n    via a ParamResolver\"\"\"\n\n    @doc_private\n    def _is_parameterized_(self: Any) -> bool:\n        \"\"\"Whether the object is parameterized by any Symbols that require\n        resolution. Returns True if the object has any unresolved Symbols\n        and False otherwise.\"\"\"\n\n    @doc_private\n    def _parameter_names_(self: Any) -> AbstractSet[str]:\n        \"\"\"Returns a collection of string names of parameters that require\n        resolution. If _is_parameterized_ is False, the collection is empty.\n        The converse is not necessarily true, because some objects may report\n        that they are parameterized when they contain symbolic constants which\n        need to be evaluated, but no free symbols.\n        \"\"\"\n\n    @doc_private\n    def _resolve_parameters_(self: Any, param_resolver: 'cirq.ParamResolver', recursive: bool):\n        \"\"\"Resolve the parameters in the effect.\"\"\"\n\n\ndef is_parameterized(val: Any) -> bool:\n    \"\"\"Returns whether the object is parameterized with any Symbols.\n\n    A value is parameterized when it has an `_is_parameterized_` method and\n    that method returns a truthy value, or if the value is an instance of\n    sympy.Basic.\n\n    Returns:\n        True if the gate has any unresolved Symbols\n        and False otherwise. If no implementation of the magic\n        method above exists or if that method returns NotImplemented,\n        this will default to False.\n    \"\"\"\n    if isinstance(val, sympy.Basic):\n        return True\n    if isinstance(val, numbers.Number):\n        return False\n    if isinstance(val, (list, tuple)):\n        return any(is_parameterized(e) for e in val)\n\n    getter = getattr(val, '_is_parameterized_', None)\n    result = NotImplemented if getter is None else getter()\n\n    if result is not NotImplemented:\n        return result\n\n    return bool(parameter_names(val))\n\n\ndef parameter_names(val: Any) -> AbstractSet[str]:\n    \"\"\"Returns parameter names for this object.\n\n    Args:\n        val: Object for which to find the parameter names.\n        check_symbols: If true, fall back to calling parameter_symbols.\n\n    Returns:\n        A set of parameter names if the object is parameterized. It the object\n        does not implement the _parameter_names_ magic method or that method\n        returns NotImplemented, returns an empty set.\n    \"\"\"\n    if isinstance(val, sympy.Basic):\n        return {symbol.name for symbol in val.free_symbols}\n    if isinstance(val, numbers.Number):\n        return set()\n    if isinstance(val, (list, tuple)):\n        return {name for e in val for name in parameter_names(e)}\n\n    getter = getattr(val, '_parameter_names_', None)\n    result = NotImplemented if getter is None else getter()\n    if result is not NotImplemented:\n        return result\n\n    return set()\n\n\ndef parameter_symbols(val: Any) -> AbstractSet[sympy.Symbol]:\n    \"\"\"Returns parameter symbols for this object.\n\n    Args:\n        val: Object for which to find the parameter symbols.\n\n    Returns:\n        A set of parameter symbols if the object is parameterized. It the object\n        does not implement the _parameter_symbols_ magic method or that method\n        returns NotImplemented, returns an empty set.\n    \"\"\"\n    return {sympy.Symbol(name) for name in parameter_names(val)}\n\n\ndef resolve_parameters(\n    val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType', recursive: bool = True\n):\n    \"\"\"Resolves symbol parameters in the effect using the param resolver.\n\n    This function will use the `_resolve_parameters_` magic method\n    of `val` to resolve any Symbols with concrete values from the given\n    parameter resolver.\n\n    Args:\n        val: The object to resolve (e.g. the gate, operation, etc)\n        param_resolver: the object to use for resolving all symbols\n        recursive: if True, resolves parameters recursively over the\n            resolver; otherwise performs a single resolution step.\n\n    Returns:\n        a gate or operation of the same type, but with all Symbols\n        replaced with floats or terminal symbols according to the\n        given ParamResolver. If `val` has no `_resolve_parameters_`\n        method or if it returns NotImplemented, `val` itself is returned.\n\n    Raises:\n        RecursionError if the ParamResolver detects a loop in resolution.\n    \"\"\"\n    if not param_resolver:\n        return val\n\n    # Ensure it is a dictionary wrapped in a ParamResolver.\n    param_resolver = study.ParamResolver(param_resolver)\n    if isinstance(val, sympy.Basic):\n        return param_resolver.value_of(val, recursive)\n    if isinstance(val, (list, tuple)):\n        return type(val)(resolve_parameters(e, param_resolver, recursive) for e in val)\n\n    getter = getattr(val, '_resolve_parameters_', None)\n    result = NotImplemented if getter is None else getter(param_resolver, recursive)\n\n    if result is not NotImplemented:\n        return result\n    else:\n        return val\n\n\ndef resolve_parameters_once(val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType'):\n    \"\"\"Performs a single parameter resolution step using the param resolver.\"\"\"\n    return resolve_parameters(val, param_resolver, False)\n", "path": "cirq/protocols/resolve_parameters.py"}], "after_files": [{"content": "# Copyright 2018 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.\n\nimport numbers\nfrom typing import AbstractSet, Any, TYPE_CHECKING\n\nimport sympy\nfrom typing_extensions import Protocol\n\nfrom cirq import study\nfrom cirq._doc import doc_private\n\nif TYPE_CHECKING:\n    import cirq\n\n\nclass SupportsParameterization(Protocol):\n    \"\"\"An object that can be parameterized by Symbols and resolved\n    via a ParamResolver\"\"\"\n\n    @doc_private\n    def _is_parameterized_(self: Any) -> bool:\n        \"\"\"Whether the object is parameterized by any Symbols that require\n        resolution. Returns True if the object has any unresolved Symbols\n        and False otherwise.\"\"\"\n\n    @doc_private\n    def _parameter_names_(self: Any) -> AbstractSet[str]:\n        \"\"\"Returns a collection of string names of parameters that require\n        resolution. If _is_parameterized_ is False, the collection is empty.\n        The converse is not necessarily true, because some objects may report\n        that they are parameterized when they contain symbolic constants which\n        need to be evaluated, but no free symbols.\n        \"\"\"\n\n    @doc_private\n    def _resolve_parameters_(self: Any, param_resolver: 'cirq.ParamResolver', recursive: bool):\n        \"\"\"Resolve the parameters in the effect.\"\"\"\n\n\ndef is_parameterized(val: Any) -> bool:\n    \"\"\"Returns whether the object is parameterized with any Symbols.\n\n    A value is parameterized when it has an `_is_parameterized_` method and\n    that method returns a truthy value, or if the value is an instance of\n    sympy.Basic.\n\n    Returns:\n        True if the gate has any unresolved Symbols\n        and False otherwise. If no implementation of the magic\n        method above exists or if that method returns NotImplemented,\n        this will default to False.\n    \"\"\"\n    if isinstance(val, sympy.Basic):\n        return True\n    if isinstance(val, numbers.Number):\n        return False\n    if isinstance(val, (list, tuple)):\n        return any(is_parameterized(e) for e in val)\n\n    getter = getattr(val, '_is_parameterized_', None)\n    result = NotImplemented if getter is None else getter()\n\n    if result is not NotImplemented:\n        return result\n\n    return bool(parameter_names(val))\n\n\ndef parameter_names(val: Any) -> AbstractSet[str]:\n    \"\"\"Returns parameter names for this object.\n\n    Args:\n        val: Object for which to find the parameter names.\n        check_symbols: If true, fall back to calling parameter_symbols.\n\n    Returns:\n        A set of parameter names if the object is parameterized. It the object\n        does not implement the _parameter_names_ magic method or that method\n        returns NotImplemented, returns an empty set.\n    \"\"\"\n    if isinstance(val, sympy.Basic):\n        return {symbol.name for symbol in val.free_symbols}\n    if isinstance(val, numbers.Number):\n        return set()\n    if isinstance(val, (list, tuple)):\n        return {name for e in val for name in parameter_names(e)}\n\n    getter = getattr(val, '_parameter_names_', None)\n    result = NotImplemented if getter is None else getter()\n    if result is not NotImplemented:\n        return result\n\n    return set()\n\n\ndef parameter_symbols(val: Any) -> AbstractSet[sympy.Symbol]:\n    \"\"\"Returns parameter symbols for this object.\n\n    Args:\n        val: Object for which to find the parameter symbols.\n\n    Returns:\n        A set of parameter symbols if the object is parameterized. It the object\n        does not implement the _parameter_symbols_ magic method or that method\n        returns NotImplemented, returns an empty set.\n    \"\"\"\n    return {sympy.Symbol(name) for name in parameter_names(val)}\n\n\ndef resolve_parameters(\n    val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType', recursive: bool = True\n):\n    \"\"\"Resolves symbol parameters in the effect using the param resolver.\n\n    This function will use the `_resolve_parameters_` magic method\n    of `val` to resolve any Symbols with concrete values from the given\n    parameter resolver.\n\n    Args:\n        val: The object to resolve (e.g. the gate, operation, etc)\n        param_resolver: the object to use for resolving all symbols\n        recursive: if True, resolves parameters recursively over the\n            resolver; otherwise performs a single resolution step.\n\n    Returns:\n        a gate or operation of the same type, but with all Symbols\n        replaced with floats or terminal symbols according to the\n        given ParamResolver. If `val` has no `_resolve_parameters_`\n        method or if it returns NotImplemented, `val` itself is returned.\n\n    Raises:\n        RecursionError if the ParamResolver detects a loop in resolution.\n        ValueError if `recursive=False` is passed to an external\n            _resolve_parameters_ method with no `recursive` parameter.\n    \"\"\"\n    if not param_resolver:\n        return val\n\n    # Ensure it is a dictionary wrapped in a ParamResolver.\n    param_resolver = study.ParamResolver(param_resolver)\n    if isinstance(val, sympy.Basic):\n        return param_resolver.value_of(val, recursive)\n    if isinstance(val, (list, tuple)):\n        return type(val)(resolve_parameters(e, param_resolver, recursive) for e in val)\n\n    getter = getattr(val, '_resolve_parameters_', None)\n    if getter is None:\n        result = NotImplemented\n    # Backwards-compatibility for external _resolve_parameters_ methods.\n    # TODO: remove in Cirq v0.11.0\n    elif 'recursive' in getter.__code__.co_varnames:\n        result = getter(param_resolver, recursive)\n    else:\n        if not recursive:\n            raise ValueError(\n                f'Object type {type(val)} does not support non-recursive parameter resolution.'\n                ' This must be updated before Cirq v0.11.'\n            )\n        result = getter(param_resolver)\n\n    if result is not NotImplemented:\n        return result\n    else:\n        return val\n\n\ndef resolve_parameters_once(val: Any, param_resolver: 'cirq.ParamResolverOrSimilarType'):\n    \"\"\"Performs a single parameter resolution step using the param resolver.\"\"\"\n    return resolve_parameters(val, param_resolver, False)\n", "path": "cirq/protocols/resolve_parameters.py"}]}