Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop Python 3.6 support #940

Merged
merged 1 commit into from Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/tests.yml
Expand Up @@ -17,13 +17,10 @@ jobs:
# job.
strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-rc.2"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11.0-rc.2"]
os: [ubuntu-latest, macos-latest, windows-latest]
loop: [asyncio, uvloop]
exclude:
# uvloop does not support Python 3.6
- loop: uvloop
python-version: "3.6"
# uvloop does not support windows
- loop: uvloop
os: windows-latest
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -13,7 +13,7 @@ of PostgreSQL server binary protocol for use with Python's ``asyncio``
framework. You can read more about asyncpg in an introductory
`blog post <http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/>`_.

asyncpg requires Python 3.6 or later and is supported for PostgreSQL
asyncpg requires Python 3.7 or later and is supported for PostgreSQL
versions 9.5 to 14. Older PostgreSQL versions or other databases implementing
the PostgreSQL protocol *may* work, but are not being actively tested.

Expand Down
10 changes: 0 additions & 10 deletions asyncpg/compat.py
Expand Up @@ -8,10 +8,8 @@
import asyncio
import pathlib
import platform
import sys


PY_37 = sys.version_info >= (3, 7)
SYSTEM = platform.uname().system


Expand All @@ -36,14 +34,6 @@ def get_pg_home_directory() -> pathlib.Path:
return pathlib.Path.home()


if PY_37:
def current_asyncio_task(loop):
return asyncio.current_task(loop)
else:
def current_asyncio_task(loop):
return asyncio.Task.current_task(loop)


async def wait_closed(stream):
# Not all asyncio versions have StreamWriter.wait_closed().
if hasattr(stream, 'wait_closed'):
Expand Down
10 changes: 1 addition & 9 deletions asyncpg/connect_utils.py
Expand Up @@ -237,10 +237,6 @@ def _parse_hostlist(hostlist, port, *, unquote=False):


def _parse_tls_version(tls_version):
if not hasattr(ssl_module, 'TLSVersion'):
raise ValueError(
"TLSVersion is not supported in this version of Python"
)
if tls_version.startswith('SSL'):
raise ValueError(
f"Unsupported TLS version: {tls_version}"
Expand Down Expand Up @@ -573,11 +569,7 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
ssl_min_protocol_version
)
else:
try:
ssl.minimum_version = _parse_tls_version('TLSv1.2')
except ValueError:
# Python 3.6 does not have ssl.TLSVersion
pass
ssl.minimum_version = _parse_tls_version('TLSv1.2')

if ssl_max_protocol_version is None:
ssl_max_protocol_version = os.getenv('PGSSLMAXPROTOCOLVERSION')
Expand Down
3 changes: 1 addition & 2 deletions asyncpg/connection.py
Expand Up @@ -20,7 +20,6 @@
import warnings
import weakref

from . import compat
from . import connect_utils
from . import cursor
from . import exceptions
Expand Down Expand Up @@ -1468,7 +1467,7 @@ async def _cancel(self, waiter):
waiter.set_exception(ex)
finally:
self._cancellations.discard(
compat.current_asyncio_task(self._loop))
asyncio.current_task(self._loop))
if not waiter.done():
waiter.set_result(None)

Expand Down
4 changes: 0 additions & 4 deletions asyncpg/pool.py
Expand Up @@ -43,10 +43,6 @@ def __new__(mcls, name, bases, dct, *, wrap=False):

return super().__new__(mcls, name, bases, dct)

def __init__(cls, name, bases, dct, *, wrap=False):
# Needed for Python 3.5 to handle `wrap` class keyword argument.
super().__init__(name, bases, dct)

@staticmethod
def _wrap_connection_method(meth_name):
def call_con_method(self, *args, **kwargs):
Expand Down
11 changes: 2 additions & 9 deletions asyncpg/protocol/scram.pyx
Expand Up @@ -9,18 +9,11 @@ import base64
import hashlib
import hmac
import re
import secrets
import stringprep
import unicodedata


# try to import the secrets library from Python 3.6+ for the
# cryptographic token generator for generating nonces as part of SCRAM
# Otherwise fall back on os.urandom
try:
from secrets import token_bytes as generate_token_bytes
except ImportError:
from os import urandom as generate_token_bytes

@cython.final
cdef class SCRAMAuthentication:
"""Contains the protocol for generating and a SCRAM hashed password.
Expand Down Expand Up @@ -198,7 +191,7 @@ cdef class SCRAMAuthentication:
cdef:
bytes token

token = generate_token_bytes(num_bytes)
token = secrets.token_bytes(num_bytes)

return base64.b64encode(token)

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Expand Up @@ -14,7 +14,7 @@ PostgreSQL and Python/asyncio. asyncpg is an efficient, clean implementation
of PostgreSQL server binary protocol for use with Python's ``asyncio``
framework.

**asyncpg** requires Python 3.6 or later and is supported for PostgreSQL
**asyncpg** requires Python 3.7 or later and is supported for PostgreSQL
versions 9.5 to 14. Older PostgreSQL versions or other databases implementing
the PostgreSQL protocol *may* work, but are not being actively tested.

Expand Down
9 changes: 4 additions & 5 deletions setup.py
Expand Up @@ -7,8 +7,8 @@

import sys

if sys.version_info < (3, 6):
raise RuntimeError('asyncpg requires Python 3.6 or greater')
if sys.version_info < (3, 7):
raise RuntimeError('asyncpg requires Python 3.7 or greater')

import os
import os.path
Expand All @@ -30,7 +30,7 @@
# Minimal dependencies required to test asyncpg.
TEST_DEPENDENCIES = [
'flake8~=5.0.4',
'uvloop>=0.15.3; platform_system != "Windows" and python_version >= "3.7"',
'uvloop>=0.15.3; platform_system != "Windows"',
]

# Dependencies required to build documentation.
Expand Down Expand Up @@ -255,7 +255,6 @@ def finalize_options(self):
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
Expand All @@ -264,7 +263,7 @@ def finalize_options(self):
'Topic :: Database :: Front-Ends',
],
platforms=['macOS', 'POSIX', 'Windows'],
python_requires='>=3.6.0',
python_requires='>=3.7.0',
zip_safe=False,
author='MagicStack Inc',
author_email='hello@magic.io',
Expand Down
5 changes: 0 additions & 5 deletions tests/test_connect.py
Expand Up @@ -14,7 +14,6 @@
import shutil
import ssl
import stat
import sys
import tempfile
import textwrap
import unittest
Expand Down Expand Up @@ -1466,10 +1465,6 @@ async def test_executemany_uvloop_ssl_issue_700(self):
finally:
await con.close()

@unittest.skipIf(
sys.version_info < (3, 7),
"Python < 3.7 doesn't have ssl.TLSVersion"
)
async def test_tls_version(self):
if self.cluster.get_pg_version() < (12, 0):
self.skipTest("PostgreSQL < 12 cannot set ssl protocol version")
Expand Down
4 changes: 0 additions & 4 deletions tests/test_pool.py
Expand Up @@ -10,7 +10,6 @@
import os
import platform
import random
import sys
import textwrap
import time
import unittest
Expand Down Expand Up @@ -741,7 +740,6 @@ async def test_pool_size_and_capacity(self):
self.assertEqual(pool.get_size(), 3)
self.assertEqual(pool.get_idle_size(), 0)

@unittest.skipIf(sys.version_info[:2] < (3, 6), 'no asyncgen support')
async def test_pool_handles_transaction_exit_in_asyncgen_1(self):
pool = await self.create_pool(database='postgres',
min_size=1, max_size=1)
Expand All @@ -763,7 +761,6 @@ class MyException(Exception):
async for _ in iterate(con): # noqa
raise MyException()

@unittest.skipIf(sys.version_info[:2] < (3, 6), 'no asyncgen support')
async def test_pool_handles_transaction_exit_in_asyncgen_2(self):
pool = await self.create_pool(database='postgres',
min_size=1, max_size=1)
Expand All @@ -788,7 +785,6 @@ class MyException(Exception):

del iterator

@unittest.skipIf(sys.version_info[:2] < (3, 6), 'no asyncgen support')
async def test_pool_handles_asyncgen_finalization(self):
pool = await self.create_pool(database='postgres',
min_size=1, max_size=1)
Expand Down