Repository: aio-libs-abandoned/aioredis-py

Issue:
Transaction data decoding is incorrect
Transaction data always decoded two times if connection encoding was defined:

Test case:
```python
@pytest.mark.run_loop
async def test_global_encoding(redis, create_redis, server, loop):
    redis = await create_redis(
        server.tcp_address,
        loop=loop, encoding='utf-8')
    res = await redis.set('key', 'value')
    assert res is True
    res = await redis.hmset(
        'hash-key', 'foo', 'val1', 'bar', 'val2')
    assert res is True

    tr = redis.multi_exec()
    fut1 = tr.get('key')
    fut2 = tr.get('key', encoding='utf-8')
    fut3 = tr.get('key', encoding=None)
    fut4 = tr.hgetall('hash-key', encoding='utf-8')
    await tr.execute()
    res = await fut1
    assert res == 'value'
    res = await fut2
    assert res == 'value'
    res = await fut3
    assert res == b'value'
    res = await fut4
    assert res == {'foo': 'val1', 'bar': 'val2'}
```

Tracing for `util.decode`
```python
decode(b'PONG', utf-8)
decode(b'OK', utf-8)
decode(b'OK', utf-8)
decode(b'OK', utf-8)
decode(b'QUEUED', utf-8)
decode(b'QUEUED', utf-8)
decode(b'QUEUED', utf-8)
decode([b'value', b'value', b'value', [b'foo', b'val1', b'bar', b'val2']], utf-8)
decode(b'value', utf-8)
decode(b'value', utf-8)
decode(b'value', utf-8)
decode([b'foo', b'val1', b'bar', b'val2'], utf-8)
decode(b'foo', utf-8)
decode(b'val1', utf-8)
decode(b'bar', utf-8)
decode(b'val2', utf-8)
decode(value, utf-8)
decode(value, utf-8)
decode(['foo', 'val1', 'bar', 'val2'], utf-8)
decode(foo, utf-8)
decode(val1, utf-8)
decode(bar, utf-8)
decode(val2, utf-8)
```

You can see that `multi-exec` response `[b'value', b'value', b'value', [b'foo', b'val1', b'bar', b'val2']]` was decoded twice. In this case decoding in `RedisConnection._end_transaction` is not make sense because we have already decoded it in the `RedisConnection._process_data`.


Discussion:

Resolving patch:
diff --git a/aioredis/connection.py b/aioredis/connection.py
--- a/aioredis/connection.py
+++ b/aioredis/connection.py
@@ -336,6 +336,7 @@ def execute(self, command, *args, encoding=_NOTSET):
             cb = self._start_transaction
         elif command in ('EXEC', b'EXEC'):
             cb = partial(self._end_transaction, discard=False)
+            encoding = None
         elif command in ('DISCARD', b'DISCARD'):
             cb = partial(self._end_transaction, discard=True)
         else:


Test patch:
diff --git a/tests/transaction_commands_test.py b/tests/transaction_commands_test.py
--- a/tests/transaction_commands_test.py
+++ b/tests/transaction_commands_test.py
@@ -215,13 +215,16 @@ async def test_global_encoding(redis, create_redis, server, loop):
     tr = redis.multi_exec()
     fut1 = tr.get('key')
     fut2 = tr.get('key', encoding='utf-8')
-    fut3 = tr.hgetall('hash-key', encoding='utf-8')
+    fut3 = tr.get('key', encoding=None)
+    fut4 = tr.hgetall('hash-key', encoding='utf-8')
     await tr.execute()
     res = await fut1
     assert res == 'value'
     res = await fut2
     assert res == 'value'
     res = await fut3
+    assert res == b'value'
+    res = await fut4
     assert res == {'foo': 'val1', 'bar': 'val2'}