Repository: redis/redis-py

Issue:
Geo search functions don't work with execute_command
**Version**: What redis-py and what redis version is the issue happening on?
* `redis-py==4.5.1`
* `redis` docker image `redis:5.0.6` 

**Platform**: What platform / version? (For example Python 3.5.1 on Windows 7 / Ubuntu 15.10 / Azure)
Linux, `python:3.8-slim-bullseye` container.

**Description**: Description of your issue, stack traces from errors and code that reproduces the issue

Below is a minimal example that shows the issue

```python
import redis
c = redis.Redis(host="redis", single_connection_client=True)
c.geoadd(name="my-key", values=[1, 2, "data"])

# works fine
x = c.georadius("my-key", 1, 2, 400, unit="m", withcoord=True)
print(x)

# fails
y = c.execute_command("GEORADIUS", 'my-key', 1, 2, 400, "m")
print(y)
```
The stack trace printed is:

```
Traceback (most recent call last):
  File "/opt/.pycharm_helpers/pydev/pydevconsole.py", line 364, in runcode
    coro = func()
  File "<input>", line 1, in <module>
  File "/opt/.pycharm_helpers/pydev/_pydev_bundle/pydev_umd.py", line 198, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/opt/.pycharm_helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/opt/project/apps/park-out-events/api/parkoutevents/redis_check.py", line 48, in <module>
    y = c.execute_command("GEORADIUS", 'poe-2023-03-11T23:38', 1, 2, 400, "m")
  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 1238, in execute_command
    return conn.retry.call_with_retry(
  File "/usr/local/lib/python3.8/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 1239, in <lambda>
    lambda: self._send_command_parse_response(
  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 1215, in _send_command_parse_response
    return self.parse_response(conn, command_name, **options)
  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 1260, in parse_response
    return self.response_callbacks[command_name](response, **options)
  File "/usr/local/lib/python3.8/site-packages/redis/client.py", line 518, in parse_geosearch_generic
    if options["store"] or options["store_dist"]:
KeyError: 'store'
```

It looks like `parse_geosearch_generic` expects `store` and `store_dist` to be boolean args instead of flags in the CLI commands, like they are in the Python interface.
This also happens for `withdist`, `withcoord`, and `withhash` as the function expects them to be present in `**options`.

Digging a bit further, even if the call is made with these flags, they aren't passed through and available in the `options` argument for `parse_geosearch_generic`, e.g.

```python
r.execute_command("GEORADIUS", "barcelona", 2.187, 41.406, 1000, "m", "WITHDIST")
```




Discussion:

Resolving patch:
diff --git a/redis/client.py b/redis/client.py
--- a/redis/client.py
+++ b/redis/client.py
@@ -518,10 +518,13 @@ def parse_geosearch_generic(response, **options):
     Parse the response of 'GEOSEARCH', GEORADIUS' and 'GEORADIUSBYMEMBER'
     commands according to 'withdist', 'withhash' and 'withcoord' labels.
     """
-    if options["store"] or options["store_dist"]:
-        # `store` and `store_dist` cant be combined
-        # with other command arguments.
-        # relevant to 'GEORADIUS' and 'GEORADIUSBYMEMBER'
+    try:
+        if options["store"] or options["store_dist"]:
+            # `store` and `store_dist` cant be combined
+            # with other command arguments.
+            # relevant to 'GEORADIUS' and 'GEORADIUSBYMEMBER'
+            return response
+    except KeyError:  # it means the command was sent via execute_command
         return response
 
     if type(response) != list:


Test patch:
diff --git a/tests/test_commands.py b/tests/test_commands.py
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -3508,6 +3508,12 @@ def test_geosearchstore_dist(self, r):
         # instead of save the geo score, the distance is saved.
         assert r.zscore("places_barcelona", "place1") == 88.05060698409301
 
+    @skip_if_server_version_lt("3.2.0")
+    def test_georadius_Issue2609(self, r):
+        # test for issue #2609 (Geo search functions don't work with execute_command)
+        r.geoadd(name="my-key", values=[1, 2, "data"])
+        assert r.execute_command("GEORADIUS", "my-key", 1, 2, 400, "m") == [b"data"]
+
     @skip_if_server_version_lt("3.2.0")
     def test_georadius(self, r):
         values = (2.1909389952632, 41.433791470673, "place1") + (