Skip to content

Commit

Permalink
Update to 3.6 type annotations and remove 3.5 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanforbes committed Jul 19, 2020
1 parent b9e0ef9 commit da85005
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 191 deletions.
20 changes: 1 addition & 19 deletions .travis.yml
Expand Up @@ -3,7 +3,7 @@ language: generic
env:
global:
- PYMODULE=asyncpg
- RELEASE_PYTHON_VERSIONS="3.5 3.6 3.7 3.8"
- RELEASE_PYTHON_VERSIONS="3.6 3.7 3.8"

- S3_UPLOAD_USERNAME=oss-ci-bot
- S3_UPLOAD_BUCKET=magicstack-oss-releases
Expand Down Expand Up @@ -93,20 +93,6 @@ jobs:

# Do a full test run on the latest supported version of PostgreSQL
# on each supported version of Python.
- name: "Test py 3.5"
os: linux
dist: focal
language: python
python: "3.5"
env: BUILD=tests PGVERSION=12
addons:
apt:
sources:
- sourceline: 'deb https://apt.postgresql.org/pub/repos/apt/ focal-pgdg main'
key_url: 'https://www.postgresql.org/media/keys/ACCC4CF8.asc'
packages:
- postgresql-12

- name: "Test py 3.6"
os: linux
dist: focal
Expand Down Expand Up @@ -195,10 +181,6 @@ jobs:
addons:
postgresql: "12"

- name: "OSX py 3.5"
os: osx
env: BUILD=tests,wheels PYTHON_VERSION=3.5.9 PGVERSION=12

- name: "OSX py 3.6"
os: osx
env: BUILD=tests,wheels PYTHON_VERSION=3.6.10 PGVERSION=12
Expand Down
23 changes: 11 additions & 12 deletions asyncpg/cluster.py
Expand Up @@ -31,10 +31,9 @@
from . import types


_ConnectionSpec = typing_extensions.TypedDict('_ConnectionSpec', {
'host': str,
'port': str
})
class _ConnectionSpec(typing_extensions.TypedDict):
host: str
port: str


_system = platform.uname().system
Expand All @@ -53,7 +52,7 @@ def find_available_port(port_range: typing.Tuple[int, int] = (49152, 65535),
max_tries: int = 1000) -> typing.Optional[int]:
low, high = port_range

port = low # type: typing.Optional[int]
port: typing.Optional[int] = low
try_no = 0

while try_no < max_tries:
Expand Down Expand Up @@ -85,11 +84,11 @@ def __init__(self, data_dir: str, *,
self._data_dir = data_dir
self._pg_config_path = pg_config_path
self._pg_bin_dir = os.environ.get('PGINSTALLATION')
self._pg_ctl = None # type: typing.Optional[str]
self._daemon_pid = None # type: typing.Optional[int]
self._daemon_process = None # type: typing.Optional[subprocess.Popen[bytes]] # noqa: E501
self._connection_addr = None # type: typing.Optional[_ConnectionSpec]
self._connection_spec_override = None # type: typing.Optional[_ConnectionSpec] # noqa: E501
self._pg_ctl: typing.Optional[str] = None
self._daemon_pid: typing.Optional[int] = None
self._daemon_process: typing.Optional[subprocess.Popen[bytes]] = None
self._connection_addr: typing.Optional[_ConnectionSpec] = None
self._connection_spec_override: typing.Optional[_ConnectionSpec] = None

def get_pg_version(self) -> 'types.ServerVersion':
return self._pg_version
Expand Down Expand Up @@ -132,7 +131,7 @@ def get_status(self) -> str:
async def connect(self,
loop: typing.Optional[asyncio.AbstractEventLoop] = None,
**kwargs: typing.Any) -> 'connection.Connection':
conn_info = self.get_connection_spec() # type: typing.Optional[typing.Any] # noqa: E501
conn_info: typing.Optional[typing.Any] = self.get_connection_spec()
conn_info.update(kwargs) # type: ignore[union-attr]
return await asyncpg.connect(loop=loop, **conn_info) # type: ignore[misc] # noqa: E501

Expand Down Expand Up @@ -215,7 +214,7 @@ def start(self, wait: int = 60, *,
# is not permitted and there is no easy way to drop
# privileges.
if os.getenv('ASYNCPG_DEBUG_SERVER'):
stdout = sys.stdout # type: typing.Union[int, typing.TextIO]
stdout: typing.Union[int, typing.TextIO] = sys.stdout
else:
stdout = subprocess.DEVNULL

Expand Down
61 changes: 0 additions & 61 deletions asyncpg/compat.py
Expand Up @@ -6,78 +6,17 @@


import asyncio
import functools
import os
import pathlib
import platform
import sys
import typing
import typing_extensions


_T_co = typing.TypeVar('_T_co', covariant=True)
_F = typing.TypeVar('_F', bound=typing.Callable[..., typing.Any])
_F_35 = typing.TypeVar('_F_35', bound=typing.Callable[
...,
typing.Coroutine[typing.Any, typing.Any, typing.Any]
])

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


if sys.version_info < (3, 5, 2):
def aiter_compat(func: _F) -> _F_35:
@functools.wraps(func)
async def wrapper(self: typing.Any) -> typing.Any:
return func(self)
return typing.cast(_F_35, wrapper)
else:
def aiter_compat(func: _F) -> _F: # type: ignore[misc]
return func


class PathLike(typing_extensions.Protocol[_T_co]):
def __fspath__(self) -> _T_co:
...


if sys.version_info >= (3, 6):
fspath = os.fspath
else:
@typing.overload
def fspath(path: str) -> str:
...

@typing.overload
def fspath(path: bytes) -> bytes:
...

@typing.overload
def fspath(path: PathLike[typing.AnyStr]) -> typing.AnyStr:
...

def fspath(path: typing.Any) -> typing.Any:
fsp = getattr(path, '__fspath__', None)
if fsp is not None and callable(fsp):
path = fsp()
if not isinstance(path, (str, bytes)):
raise TypeError(
'expected {}() to return str or bytes, not {}'.format(
fsp.__qualname__, type(path).__name__
))
return path
elif isinstance(path, (str, bytes)):
return path
else:
raise TypeError(
'expected str, bytes or path-like object, not {}'.format(
type(path).__name__
)
)


if SYSTEM == 'Windows':
import ctypes.wintypes

Expand Down
52 changes: 24 additions & 28 deletions asyncpg/connect_utils.py
Expand Up @@ -37,27 +37,22 @@
HostType = typing.Union[typing.List[str], str]
PortType = typing.Union[typing.List[int], int]

_ConnectionParameters = typing.NamedTuple(
'ConnectionParameters',
[
('user', str),
('password', typing.Optional[str]),
('database', str),
('ssl', typing.Optional[SSLType]),
('ssl_is_advisory', typing.Optional[bool]),
('connect_timeout', typing.Optional[float]),
('server_settings', typing.Optional[typing.Dict[str, str]])
])


_ClientConfiguration = typing.NamedTuple(
'ConnectionConfiguration',
[
('command_timeout', typing.Optional[float]),
('statement_cache_size', int),
('max_cached_statement_lifetime', int),
('max_cacheable_statement_size', int),
])

class _ConnectionParameters(typing.NamedTuple):
user: str
password: typing.Optional[str]
database: str
ssl: typing.Optional[SSLType]
ssl_is_advisory: typing.Optional[bool]
connect_timeout: typing.Optional[float]
server_settings: typing.Optional[typing.Dict[str, str]]


class _ClientConfiguration(typing.NamedTuple):
command_timeout: typing.Optional[float]
statement_cache_size: int
max_cached_statement_lifetime: int
max_cacheable_statement_size: int


_system = platform.uname().system
Expand Down Expand Up @@ -175,15 +170,16 @@ def _parse_hostlist(hostlist: str,
else:
hostspecs = [hostlist]

hosts = [] # type: typing.List[str]
hostlist_ports = [] # type: typing.List[int]
ports = None # type: typing.Optional[typing.List[int]]
hosts: typing.List[str] = []
hostlist_ports: typing.List[int] = []
ports: typing.Optional[typing.List[int]] = None

if not port:
portspec = os.environ.get('PGPORT')
if portspec:
if ',' in portspec:
temp_port = [int(p) for p in portspec.split(',')] # type: typing.Union[typing.List[int], int] # noqa: E501
temp_port: typing.Union[typing.List[int], int] = [
int(p) for p in portspec.split(',')]
else:
temp_port = int(portspec)
else:
Expand Down Expand Up @@ -274,7 +270,7 @@ def _parse_connect_dsn_and_args(*, dsn: typing.Optional[str],

if parsed.query:
query = urllib.parse.parse_qs(parsed.query, strict_parsing=True)
query_str = {} # type: typing.Dict[str, str]
query_str: typing.Dict[str, str] = {}
for key, val in query.items():
if isinstance(val, list):
query_str[key] = val[-1]
Expand Down Expand Up @@ -404,7 +400,7 @@ def _parse_connect_dsn_and_args(*, dsn: typing.Optional[str],
database=database, user=user,
passfile=passfile) # type: ignore[arg-type]

addrs = [] # type: typing.List[AddrType]
addrs: typing.List[AddrType] = []
for h, p in zip(host, port):
if h.startswith('/'):
# UNIX socket name
Expand Down Expand Up @@ -726,7 +722,7 @@ async def _connect(*, loop: typing.Optional[asyncio.AbstractEventLoop],

addrs, params, config = _parse_connect_arguments(timeout=timeout, **kwargs)

last_error = None # type: typing.Optional[BaseException]
last_error: typing.Optional[BaseException] = None
addr = None
for addr in addrs:
before = time.monotonic()
Expand Down

0 comments on commit da85005

Please sign in to comment.