Skip to content

Commit 607a59a

Browse files
authored
Drop python 3.6 support (#2306)
1 parent f665bd3 commit 607a59a

22 files changed

+32
-156
lines changed

.github/workflows/integration.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
strategy:
4040
max-parallel: 15
4141
matrix:
42-
python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', 'pypy-3.7', 'pypy-3.8']
42+
python-version: ['3.7', '3.8', '3.9', '3.10', 'pypy-3.7', 'pypy-3.8']
4343
test-type: ['standalone', 'cluster']
4444
connection-type: ['hiredis', 'plain']
4545
env:
@@ -84,7 +84,7 @@ jobs:
8484
runs-on: ubuntu-latest
8585
strategy:
8686
matrix:
87-
python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', 'pypy-3.7']
87+
python-version: ['3.7', '3.8', '3.9', '3.10', 'pypy-3.7']
8888
steps:
8989
- uses: actions/checkout@v2
9090
- name: install python ${{ matrix.python-version }}

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ this, instead of using make test, you need to pass
126126
Our test suite uses `pytest`. You can run a specific test suite against
127127
a specific Python version like this:
128128

129-
`$ docker-compose run test tox -e py36 -- --redis-url=redis://master:6379/9 tests/test_commands.py`
129+
`$ docker-compose run test tox -e py37 -- --redis-url=redis://master:6379/9 tests/test_commands.py`
130130

131131
### Troubleshooting
132132

redis/asyncio/cluster.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,7 @@ def __del__(self) -> None:
377377
warnings.warn(f"{self._DEL_MESSAGE} {self!r}", ResourceWarning, source=self)
378378
try:
379379
context = {"client": self, "message": self._DEL_MESSAGE}
380-
# TODO: Change to get_running_loop() when dropping support for py3.6
381-
asyncio.get_event_loop().call_exception_handler(context)
380+
asyncio.get_running_loop().call_exception_handler(context)
382381
except RuntimeError:
383382
...
384383

@@ -834,8 +833,7 @@ def __del__(self) -> None:
834833
)
835834
try:
836835
context = {"client": self, "message": self._DEL_MESSAGE}
837-
# TODO: Change to get_running_loop() when dropping support for py3.6
838-
asyncio.get_event_loop().call_exception_handler(context)
836+
asyncio.get_running_loop().call_exception_handler(context)
839837
except RuntimeError:
840838
...
841839
break

redis/asyncio/connection.py

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import os
88
import socket
99
import ssl
10-
import sys
1110
import threading
1211
import weakref
1312
from itertools import chain
@@ -864,12 +863,10 @@ async def _ping_failed(self, error):
864863

865864
async def check_health(self):
866865
"""Check the health of the connection with a PING/PONG"""
867-
if sys.version_info[0:2] == (3, 6):
868-
func = asyncio.get_event_loop
869-
else:
870-
func = asyncio.get_running_loop
871-
872-
if self.health_check_interval and func().time() > self.next_health_check:
866+
if (
867+
self.health_check_interval
868+
and asyncio.get_running_loop().time() > self.next_health_check
869+
):
873870
await self.retry.call_with_retry(self._send_ping, self._ping_failed)
874871

875872
async def _send_packed_command(self, command: Iterable[bytes]) -> None:
@@ -957,11 +954,8 @@ async def read_response(self, disable_decoding: bool = False):
957954
raise
958955

959956
if self.health_check_interval:
960-
if sys.version_info[0:2] == (3, 6):
961-
func = asyncio.get_event_loop
962-
else:
963-
func = asyncio.get_running_loop
964-
self.next_health_check = func().time() + self.health_check_interval
957+
next_time = asyncio.get_running_loop().time() + self.health_check_interval
958+
self.next_health_check = next_time
965959

966960
if isinstance(response, ResponseError):
967961
raise response from None
@@ -992,11 +986,8 @@ async def read_response_without_lock(self, disable_decoding: bool = False):
992986
raise
993987

994988
if self.health_check_interval:
995-
if sys.version_info[0:2] == (3, 6):
996-
func = asyncio.get_event_loop
997-
else:
998-
func = asyncio.get_running_loop
999-
self.next_health_check = func().time() + self.health_check_interval
989+
next_time = asyncio.get_running_loop().time() + self.health_check_interval
990+
self.next_health_check = next_time
1000991

1001992
if isinstance(response, ResponseError):
1002993
raise response from None

redis/asyncio/lock.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import asyncio
2-
import sys
32
import threading
43
import uuid
54
from types import SimpleNamespace
@@ -186,11 +185,6 @@ async def acquire(
186185
object with the default encoding. If a token isn't specified, a UUID
187186
will be generated.
188187
"""
189-
if sys.version_info[0:2] != (3, 6):
190-
loop = asyncio.get_running_loop()
191-
else:
192-
loop = asyncio.get_event_loop()
193-
194188
sleep = self.sleep
195189
if token is None:
196190
token = uuid.uuid1().hex.encode()
@@ -203,14 +197,14 @@ async def acquire(
203197
blocking_timeout = self.blocking_timeout
204198
stop_trying_at = None
205199
if blocking_timeout is not None:
206-
stop_trying_at = loop.time() + blocking_timeout
200+
stop_trying_at = asyncio.get_event_loop().time() + blocking_timeout
207201
while True:
208202
if await self.do_acquire(token):
209203
self.local.token = token
210204
return True
211205
if not blocking:
212206
return False
213-
next_try_at = loop.time() + sleep
207+
next_try_at = asyncio.get_event_loop().time() + sleep
214208
if stop_trying_at is not None and next_try_at > stop_trying_at:
215209
return False
216210
await asyncio.sleep(sleep)

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
},
3131
author="Redis Inc.",
3232
author_email="[email protected]",
33-
python_requires=">=3.6",
33+
python_requires=">=3.7",
3434
install_requires=[
3535
"deprecated>=1.2.3",
3636
"packaging>=20.4",
@@ -47,7 +47,6 @@
4747
"Programming Language :: Python",
4848
"Programming Language :: Python :: 3",
4949
"Programming Language :: Python :: 3 :: Only",
50-
"Programming Language :: Python :: 3.6",
5150
"Programming Language :: Python :: 3.7",
5251
"Programming Language :: Python :: 3.8",
5352
"Programming Language :: Python :: 3.9",

tests/test_asyncio/conftest.py

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import functools
21
import random
3-
import sys
2+
from contextlib import asynccontextmanager as _asynccontextmanager
43
from typing import Union
54
from urllib.parse import urlparse
65

76
import pytest
7+
import pytest_asyncio
88
from packaging.version import Version
99

1010
import redis.asyncio as redis
@@ -21,13 +21,6 @@
2121

2222
from .compat import mock
2323

24-
if sys.version_info[0:2] == (3, 6):
25-
import pytest as pytest_asyncio
26-
27-
pytestmark = pytest.mark.asyncio
28-
else:
29-
import pytest_asyncio
30-
3124

3225
async def _get_info(redis_url):
3326
client = redis.Redis.from_url(redis_url)
@@ -268,17 +261,5 @@ async def __aexit__(self, exc_type, exc_inst, tb):
268261
raise RuntimeError("More pickles")
269262

270263

271-
if sys.version_info[0:2] == (3, 6):
272-
273-
def asynccontextmanager(func):
274-
@functools.wraps(func)
275-
def wrapper(*args, **kwargs):
276-
return AsyncContextManager(func(*args, **kwargs))
277-
278-
return wrapper
279-
280-
else:
281-
from contextlib import asynccontextmanager as _asynccontextmanager
282-
283-
def asynccontextmanager(func):
284-
return _asynccontextmanager(func)
264+
def asynccontextmanager(func):
265+
return _asynccontextmanager(func)

tests/test_asyncio/test_bloom.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
import sys
2-
31
import pytest
42

53
import redis.asyncio as redis
64
from redis.exceptions import ModuleError, RedisError
75
from redis.utils import HIREDIS_AVAILABLE
86

9-
if sys.version_info[0:2] == (3, 6):
10-
pytestmark = pytest.mark.asyncio
11-
127

138
def intlist(obj):
149
return [int(v) for v in obj]

tests/test_asyncio/test_cluster.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,12 @@
22
import binascii
33
import datetime
44
import os
5-
import sys
65
import warnings
76
from typing import Any, Awaitable, Callable, Dict, List, Optional, Type, Union
87
from urllib.parse import urlparse
98

109
import pytest
11-
12-
from .compat import mock
13-
14-
if sys.version_info[0:2] == (3, 6):
15-
import pytest as pytest_asyncio
16-
17-
pytestmark = pytest.mark.asyncio
18-
else:
19-
import pytest_asyncio
20-
10+
import pytest_asyncio
2111
from _pytest.fixtures import FixtureRequest
2212

2313
from redis.asyncio.cluster import ClusterNode, NodesManager, RedisCluster
@@ -44,6 +34,8 @@
4434
skip_unless_arch_bits,
4535
)
4636

37+
from .compat import mock
38+
4739
pytestmark = pytest.mark.onlycluster
4840

4941

tests/test_asyncio/test_commands.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,11 @@
44
import binascii
55
import datetime
66
import re
7-
import sys
87
import time
98
from string import ascii_letters
109

1110
import pytest
12-
13-
if sys.version_info[0:2] == (3, 6):
14-
import pytest as pytest_asyncio
15-
16-
pytestmark = pytest.mark.asyncio
17-
else:
18-
import pytest_asyncio
11+
import pytest_asyncio
1912

2013
import redis
2114
from redis import exceptions

tests/test_asyncio/test_connection.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import asyncio
22
import socket
3-
import sys
43
import types
54
from unittest.mock import patch
65

@@ -19,9 +18,6 @@
1918

2019
from .compat import mock
2120

22-
if sys.version_info[0:2] == (3, 6):
23-
pytestmark = pytest.mark.asyncio
24-
2521

2622
@pytest.mark.onlynoncluster
2723
@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")

tests/test_asyncio/test_connection_pool.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
import asyncio
22
import os
33
import re
4-
import sys
54

65
import pytest
7-
8-
if sys.version_info[0:2] == (3, 6):
9-
import pytest as pytest_asyncio
10-
11-
pytestmark = pytest.mark.asyncio
12-
else:
13-
import pytest_asyncio
6+
import pytest_asyncio
147

158
import redis.asyncio as redis
169
from redis.asyncio.connection import Connection, to_bool

tests/test_asyncio/test_encoding.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
import sys
2-
31
import pytest
4-
5-
if sys.version_info[0:2] == (3, 6):
6-
import pytest as pytest_asyncio
7-
8-
pytestmark = pytest.mark.asyncio
9-
else:
10-
import pytest_asyncio
2+
import pytest_asyncio
113

124
import redis.asyncio as redis
135
from redis.exceptions import DataError

tests/test_asyncio/test_lock.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
import asyncio
2-
import sys
32

43
import pytest
5-
6-
if sys.version_info[0:2] == (3, 6):
7-
import pytest as pytest_asyncio
8-
9-
pytestmark = pytest.mark.asyncio
10-
else:
11-
import pytest_asyncio
4+
import pytest_asyncio
125

136
from redis.asyncio.lock import Lock
147
from redis.exceptions import LockError, LockNotOwnedError

tests/test_asyncio/test_monitor.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
import sys
2-
31
import pytest
42

53
from tests.conftest import skip_if_redis_enterprise, skip_ifnot_redis_enterprise
64

75
from .conftest import wait_for_command
86

9-
if sys.version_info[0:2] == (3, 6):
10-
pytestmark = pytest.mark.asyncio
11-
127

138
@pytest.mark.onlynoncluster
149
class TestMonitor:

tests/test_asyncio/test_pipeline.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
import sys
2-
31
import pytest
42

53
import redis
64
from tests.conftest import skip_if_server_version_lt
75

86
from .conftest import wait_for_command
97

10-
if sys.version_info[0:2] == (3, 6):
11-
pytestmark = pytest.mark.asyncio
12-
138

149
class TestPipeline:
1510
@pytest.mark.onlynoncluster

tests/test_asyncio/test_pubsub.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
import asyncio
22
import functools
3-
import sys
43
from typing import Optional
54

65
import async_timeout
76
import pytest
8-
9-
if sys.version_info[0:2] == (3, 6):
10-
import pytest as pytest_asyncio
11-
12-
pytestmark = pytest.mark.asyncio(forbid_global_loop=True)
13-
else:
14-
import pytest_asyncio
7+
import pytest_asyncio
158

169
import redis.asyncio as redis
1710
from redis.exceptions import ConnectionError

tests/test_asyncio/test_scripting.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
import sys
2-
31
import pytest
4-
5-
if sys.version_info[0:2] == (3, 6):
6-
import pytest as pytest_asyncio
7-
8-
pytestmark = pytest.mark.asyncio
9-
else:
10-
import pytest_asyncio
2+
import pytest_asyncio
113

124
from redis import exceptions
135
from tests.conftest import skip_if_server_version_lt

0 commit comments

Comments
 (0)