diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce95923a..8bc40f95 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,6 @@ jobs: fail-fast: false matrix: python-version: [ - 3.5, 3.6, 3.7, 3.8, diff --git a/README.md b/README.md index 87e22a60..93307810 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Introduction This package provides a client interface to query [Trino](https://trino.io/) -a distributed SQL engine. It supports Python>=3.5 and pypy. +a distributed SQL engine. It supports Python>=3.6 and pypy. # Installation diff --git a/setup.py b/setup.py index 28543f18..25ef8716 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,6 @@ "Operating System :: Microsoft :: Windows", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", @@ -68,7 +67,7 @@ "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Database :: Front-Ends", ], - python_requires='>=3.5', + python_requires='>=3.6', install_requires=["click", "requests"], extras_require={ "all": all_require, diff --git a/trino/auth.py b/trino/auth.py index ff04c80f..48128311 100644 --- a/trino/auth.py +++ b/trino/auth.py @@ -13,11 +13,11 @@ import abc import os -from typing import Any, Optional, Text # NOQA +from typing import Optional from requests.auth import AuthBase -class Authentication(metaclass=abc.ABCMeta): # type: ignore +class Authentication(metaclass=abc.ABCMeta): @abc.abstractmethod def set_http_session(self, http_session): pass @@ -40,17 +40,16 @@ def handle_err(self, error): class KerberosAuthentication(Authentication): def __init__( self, - config=None, # type: Optional[Text] - service_name=None, # type: Text - mutual_authentication=False, # type: bool - force_preemptive=False, # type: bool - hostname_override=None, # type: Optional[Text] - sanitize_mutual_error_response=True, # type: bool - principal=None, # type: Optional[Text] - delegate=False, # type: bool - ca_bundle=None, # type: Optional[Text] - ): - # type: (...) -> None + config: Optional[str] = None, + service_name: str = None, + mutual_authentication: bool = False, + force_preemptive: bool = False, + hostname_override: Optional[str] = None, + sanitize_mutual_error_response: bool = True, + principal: Optional[str] = None, + delegate: bool = False, + ca_bundle: Optional[str] = None, + ) -> None: self._config = config self._service_name = service_name self._mutual_authentication = mutual_authentication diff --git a/trino/client.py b/trino/client.py index 36706a27..6168b569 100644 --- a/trino/client.py +++ b/trino/client.py @@ -35,7 +35,7 @@ import copy import os -from typing import Any, Dict, List, Optional, Text, Tuple, Union # NOQA for mypy types +from typing import Any, Dict, List, Optional, Tuple, Union import requests @@ -184,31 +184,30 @@ class TrinoRequest(object): http = requests HTTP_EXCEPTIONS = ( - http.ConnectionError, # type: ignore - http.Timeout, # type: ignore + http.ConnectionError, + http.Timeout, ) def __init__( self, - host, # type: Text - port, # type: int - user, # type: Text - source=None, # type: Text - catalog=None, # type: Text - schema=None, # type: Text - session_properties=None, # type: Optional[Dict[Text, Any]] - http_session=None, # type: Any - http_headers=None, # type: Optional[Dict[Text, Text]] - transaction_id=NO_TRANSACTION, # type: Optional[Text] - http_scheme=constants.HTTP, # type: Text - auth=constants.DEFAULT_AUTH, # type: Optional[Any] - redirect_handler=None, - max_attempts=MAX_ATTEMPTS, # type: int - request_timeout=constants.DEFAULT_REQUEST_TIMEOUT, # type: Union[float, Tuple[float, float]] + host: str, + port: int, + user: str, + source: str = None, + catalog: str = None, + schema: str = None, + session_properties: Optional[Dict[str, Any]] = None, + http_session: Any = None, + http_headers: Optional[Dict[str, str]] = None, + transaction_id: Optional[str] = NO_TRANSACTION, + http_scheme: str = constants.HTTP, + auth: Optional[Any] = constants.DEFAULT_AUTH, + redirect_handler: Any = None, + max_attempts: int = MAX_ATTEMPTS, + request_timeout: Union[float, Tuple[float, float]] = constants.DEFAULT_REQUEST_TIMEOUT, handle_retry=exceptions.RetryWithExponentialBackoff(), - verify=True # type: Any - ): - # type: (...) -> None + verify: bool = True + ) -> None: self._client_session = ClientSession( catalog, schema, @@ -221,13 +220,12 @@ def __init__( self._host = host self._port = port - self._next_uri = None # type: Optional[Text] + self._next_uri: Optional[str] = None if http_session is not None: self._http_session = http_session else: - # mypy cannot follow module import - self._http_session = self.http.Session() # type: ignore + self._http_session = self.http.Session() self._http_session.verify = verify self._http_session.headers.update(self.http_headers) self._exceptions = self.HTTP_EXCEPTIONS @@ -253,8 +251,7 @@ def transaction_id(self, value): self._client_session.transaction_id = value @property - def http_headers(self): - # type: () -> Dict[Text, Text] + def http_headers(self) -> Dict[str, str]: headers = {} headers[constants.HEADER_CATALOG] = self._client_session.catalog @@ -280,13 +277,11 @@ def http_headers(self): return headers @property - def max_attempts(self): - # type: () -> int + def max_attempts(self) -> int: return self._max_attempts @max_attempts.setter - def max_attempts(self, value): - # type: (int) -> None + def max_attempts(self, value) -> None: self._max_attempts = value if value == 1: # No retry self._get = self._http_session.get @@ -308,20 +303,17 @@ def max_attempts(self, value): self._post = with_retry(self._http_session.post) self._delete = with_retry(self._http_session.delete) - def get_url(self, path): - # type: (Text) -> Text + def get_url(self, path) -> str: return "{protocol}://{host}:{port}{path}".format( protocol=self._http_scheme, host=self._host, port=self._port, path=path ) @property - def statement_url(self): - # type: () -> Text + def statement_url(self) -> str: return self.get_url(constants.URL_STATEMENT_PATH) @property - def next_uri(self): - # type: () -> Text + def next_uri(self) -> str: return self._next_uri def post(self, sql, additional_http_headers=None): @@ -387,8 +379,7 @@ def raise_response_error(self, http_response): ) ) - def process(self, http_response): - # type: (requests.Response) -> TrinoStatus + def process(self, http_response) -> TrinoStatus: if not http_response.ok: self.raise_response_error(http_response) @@ -437,8 +428,7 @@ def __init__(self, query, rows=None): self._rownumber = 0 @property - def rownumber(self): - # type: () -> int + def rownumber(self) -> int: return self._rownumber def __iter__(self): @@ -466,16 +456,14 @@ class TrinoQuery(object): def __init__( self, - request, # type: TrinoRequest - sql, # type: Text - ): - # type: (...) -> None - self.query_id = None # type: Optional[Text] - - self._stats = {} # type: Dict[Any, Any] - self._warnings = [] # type: List[Dict[Any, Any]] - self._columns = None # type: Optional[List[Text]] - + request: TrinoRequest, + sql: str, + ) -> None: + self.query_id: Optional[str] = None + + self._stats: Dict[Any, Any] = {} + self._warnings: List[Dict[Any, Any]] = [] + self._columns: Optional[List[str]] = None self._finished = False self._cancelled = False self._request = request @@ -504,8 +492,7 @@ def warnings(self): def result(self): return self._result - def execute(self, additional_http_headers=None): - # type: () -> TrinoResult + def execute(self, additional_http_headers=None) -> TrinoResult: """Initiate a Trino query by sending the SQL statement This is the first HTTP request sent to the coordinator. @@ -527,8 +514,7 @@ def execute(self, additional_http_headers=None): self._result = TrinoResult(self, status.rows) return self._result - def fetch(self): - # type: () -> List[List[Any]] + def fetch(self) -> List[List[Any]]: """Continue fetching data for the current query_id""" response = self._request.get(self._request.next_uri) status = self._request.process(response) @@ -541,8 +527,7 @@ def fetch(self): self._finished = True return status.rows - def cancel(self): - # type: () -> None + def cancel(self) -> None: """Cancel the current query""" if self.query_id is None or self.finished: return @@ -557,19 +542,17 @@ def cancel(self): return self._request.raise_response_error(response) - def is_finished(self): + def is_finished(self) -> bool: import warnings warnings.warn("is_finished is deprecated, use finished instead", DeprecationWarning) return self.finished @property - def finished(self): - # type: () -> bool + def finished(self) -> bool: return self._finished @property - def cancelled(self): - # type: () -> bool + def cancelled(self) -> bool: return self._cancelled @property diff --git a/trino/constants.py b/trino/constants.py index 57c3a862..9c81617f 100644 --- a/trino/constants.py +++ b/trino/constants.py @@ -10,16 +10,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Any, Optional, Text # NOQA: mypy types +from typing import Any, Optional DEFAULT_PORT = 8080 DEFAULT_SOURCE = "trino-python-client" -DEFAULT_CATALOG = None # type: Optional[Text] -DEFAULT_SCHEMA = None # type: Optional[Text] -DEFAULT_AUTH = None # type: Optional[Any] +DEFAULT_CATALOG: Optional[str] = None +DEFAULT_SCHEMA: Optional[str] = None +DEFAULT_AUTH: Optional[Any] = None DEFAULT_MAX_ATTEMPTS = 3 -DEFAULT_REQUEST_TIMEOUT = 30.0 # type: float +DEFAULT_REQUEST_TIMEOUT: float = 30.0 HTTP = "http" HTTPS = "https" diff --git a/trino/dbapi.py b/trino/dbapi.py index 3ce5a631..616ae341 100644 --- a/trino/dbapi.py +++ b/trino/dbapi.py @@ -400,8 +400,7 @@ def execute(self, operation, params=None): def executemany(self, operation, seq_of_params): raise trino.exceptions.NotSupportedError - def fetchone(self): - # type: () -> Optional[List[Any]] + def fetchone(self) -> Optional[List[Any]]: """ PEP-0249: Fetch the next row of a query result set, returning a single @@ -418,8 +417,7 @@ def fetchone(self): except trino.exceptions.HttpError as err: raise trino.exceptions.OperationalError(str(err)) - def fetchmany(self, size=None): - # type: (Optional[int]) -> List[List[Any]] + def fetchmany(self, size=None) -> List[List[Any]]: """ PEP-0249: Fetch the next set of rows of a query result, returning a sequence of sequences (e.g. a list of tuples). An empty sequence is @@ -455,8 +453,7 @@ def fetchmany(self, size=None): def genall(self): return self._query.result - def fetchall(self): - # type: () -> List[List[Any]] + def fetchall(self) -> List[List[Any]]: return list(self.genall()) def cancel(self):