diff --git a/.mypy.ini b/.mypy.ini index 9556bcdb2..a40199e8e 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -1,7 +1,6 @@ [mypy] python_version = 3.8 warn_unused_configs = True -plugins = sqlmypy namespace_packages = True [mypy-google.auth.*] @@ -21,6 +20,3 @@ ignore_missing_imports = True [mypy-pytest] ignore_missing_imports = True - -[mypy-OpenSSL] -ignore_missing_imports = True diff --git a/google/cloud/sql/connector/__init__.py b/google/cloud/sql/connector/__init__.py index fe2e40d7a..22ee9f328 100644 --- a/google/cloud/sql/connector/__init__.py +++ b/google/cloud/sql/connector/__init__.py @@ -14,9 +14,9 @@ limitations under the License. """ -from google.cloud.sql.connector.connector import Connector, create_async_connector +from google.cloud.sql.connector.connector import Connector +from google.cloud.sql.connector.connector import create_async_connector from google.cloud.sql.connector.instance import IPTypes from google.cloud.sql.connector.version import __version__ - __all__ = ["__version__", "create_async_connector", "Connector", "IPTypes"] diff --git a/google/cloud/sql/connector/connector.py b/google/cloud/sql/connector/connector.py index b0c5fa900..28b42587f 100755 --- a/google/cloud/sql/connector/connector.py +++ b/google/cloud/sql/connector/connector.py @@ -24,18 +24,15 @@ from typing import Any, Dict, Optional, Type, TYPE_CHECKING import google.cloud.sql.connector.asyncpg as asyncpg -from google.cloud.sql.connector.exceptions import ( - ConnectorLoopError, - DnsNameResolutionError, -) -from google.cloud.sql.connector.instance import ( - Instance, - IPTypes, -) +from google.cloud.sql.connector.exceptions import ConnectorLoopError +from google.cloud.sql.connector.exceptions import DnsNameResolutionError +from google.cloud.sql.connector.instance import Instance +from google.cloud.sql.connector.instance import IPTypes import google.cloud.sql.connector.pg8000 as pg8000 import google.cloud.sql.connector.pymysql as pymysql import google.cloud.sql.connector.pytds as pytds -from google.cloud.sql.connector.utils import format_database_user, generate_keys +from google.cloud.sql.connector.utils import format_database_user +from google.cloud.sql.connector.utils import generate_keys if TYPE_CHECKING: from google.auth.credentials import Credentials diff --git a/google/cloud/sql/connector/instance.py b/google/cloud/sql/connector/instance.py index 7be5d0735..8f6ba6033 100644 --- a/google/cloud/sql/connector/instance.py +++ b/google/cloud/sql/connector/instance.py @@ -21,31 +21,22 @@ import re import ssl from tempfile import TemporaryDirectory -from typing import ( - Any, - Dict, - Optional, - Tuple, - TYPE_CHECKING, -) +from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING import aiohttp - from google.auth.credentials import Credentials -from google.cloud.sql.connector.exceptions import ( - AutoIAMAuthNotSupported, - CloudSQLIPTypeError, - CredentialsTypeError, - TLSVersionError, -) + +from google.cloud.sql.connector.exceptions import AutoIAMAuthNotSupported +from google.cloud.sql.connector.exceptions import CloudSQLIPTypeError +from google.cloud.sql.connector.exceptions import CredentialsTypeError +from google.cloud.sql.connector.exceptions import TLSVersionError from google.cloud.sql.connector.rate_limiter import AsyncRateLimiter -from google.cloud.sql.connector.refresh_utils import ( - _get_ephemeral, - _get_metadata, - _is_valid, - _seconds_until_refresh, -) -from google.cloud.sql.connector.utils import _auth_init, write_to_file +from google.cloud.sql.connector.refresh_utils import _get_ephemeral +from google.cloud.sql.connector.refresh_utils import _get_metadata +from google.cloud.sql.connector.refresh_utils import _is_valid +from google.cloud.sql.connector.refresh_utils import _seconds_until_refresh +from google.cloud.sql.connector.utils import _auth_init +from google.cloud.sql.connector.utils import write_to_file from google.cloud.sql.connector.version import __version__ as version if TYPE_CHECKING: diff --git a/google/cloud/sql/connector/refresh_utils.py b/google/cloud/sql/connector/refresh_utils.py index 6db1667a9..1b9e03eb0 100644 --- a/google/cloud/sql/connector/refresh_utils.py +++ b/google/cloud/sql/connector/refresh_utils.py @@ -23,8 +23,8 @@ from cryptography.hazmat.backends import default_backend from cryptography.x509 import load_pem_x509_certificate - -from google.auth.credentials import Credentials, Scoped +from google.auth.credentials import Credentials +from google.auth.credentials import Scoped import google.auth.transport.requests if TYPE_CHECKING: diff --git a/google/cloud/sql/connector/utils.py b/google/cloud/sql/connector/utils.py index 46b7ae85f..08f5145e1 100755 --- a/google/cloud/sql/connector/utils.py +++ b/google/cloud/sql/connector/utils.py @@ -18,9 +18,9 @@ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa - from google.auth import default -from google.auth.credentials import Credentials, with_scopes_if_required +from google.auth.credentials import Credentials +from google.auth.credentials import with_scopes_if_required async def generate_keys() -> Tuple[bytes, str]: diff --git a/noxfile.py b/noxfile.py index 05c25c518..6b3f55b46 100644 --- a/noxfile.py +++ b/noxfile.py @@ -16,13 +16,18 @@ from __future__ import absolute_import + import os + import nox -BLACK_PATHS = ["google", "tests"] +BLACK_VERSION = "black==23.12.1" +ISORT_VERSION = "isort==5.13.2" +MYPY_VERSION = "mypy==0.982" + +LINT_PATHS = ["google", "tests", "noxfile.py", "setup.py"] -if os.path.exists("samples"): - BLACK_PATHS.append("samples") +TEST_PYTHON_VERSIONS = ["3.8", "3.9", "3.10", "3.11"] @nox.session @@ -31,22 +36,63 @@ def lint(session): Returns a failure if the linters find linting errors or sufficiently serious code quality issues. """ - session.install("-r", "requirements-test.txt") session.install("-r", "requirements.txt") - session.install("flake8-import-order") - session.run("black", "--check", *BLACK_PATHS) + session.install( + "flake8", + "flake8-annotations", + MYPY_VERSION, + BLACK_VERSION, + ISORT_VERSION, + "types-setuptools", + "twine", + ) + session.run( + "isort", + "--fss", + "--check-only", + "--diff", + "--profile=google", + *LINT_PATHS, + ) + session.run("black", "--check", "--diff", *LINT_PATHS) session.run( "flake8", - "--import-order-style=google", - "--application-import-names=google,tests", "google", "tests", ) - session.run("mypy", "-p", "google", "--show-traceback") + session.run( + "mypy", + "-p", + "google", + "--install-types", + "--non-interactive", + "--show-traceback", + ) session.run("python", "setup.py", "sdist") session.run("twine", "check", "dist/*") +@nox.session() +def format(session): + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sectionss + session.run( + "isort", + "--fss", + "--profile=google", + *LINT_PATHS, + ) + session.run( + "black", + *LINT_PATHS, + ) + + def default(session, path): # Install all test dependencies, then install this package in-place. session.install("-r", "requirements-test.txt") @@ -55,7 +101,7 @@ def default(session, path): # Run py.test against the unit tests. session.run( "pytest", - "--cov=google/cloud/sql/connector", + "--cov=google.cloud.sql.connector", "-v", "--cov-config=.coveragerc", "--cov-report=", @@ -66,17 +112,17 @@ def default(session, path): ) -@nox.session(python=["3.8", "3.9", "3.10", "3.11"]) +@nox.session(python=TEST_PYTHON_VERSIONS) def unit(session): default(session, os.path.join("tests", "unit")) -@nox.session(python=["3.8", "3.9", "3.10", "3.11"]) +@nox.session(python=TEST_PYTHON_VERSIONS) def system(session): default(session, os.path.join("tests", "system")) -@nox.session(python=["3.8", "3.9", "3.10", "3.11"]) +@nox.session(python=TEST_PYTHON_VERSIONS) def test(session): default(session, os.path.join("tests", "unit")) default(session, os.path.join("tests", "system")) diff --git a/requirements-test.txt b/requirements-test.txt index 9425c22b5..4f14460fd 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -4,14 +4,7 @@ pytest-cov==4.1.0 pytest-asyncio==0.23.3 SQLAlchemy==2.0.25 sqlalchemy-pytds==1.0.0 -flake8==5.0.4 -flake8-annotations==2.9.1 -black==23.12.1 -mypy==0.982 sqlalchemy-stubs==0.4 -types-PyMySQL==1.1.0.1 -types-mock==5.1.0.3 -twine==4.0.2 PyMySQL==1.1.0 pg8000==1.30.4 asyncpg==0.29.0 diff --git a/setup.py b/setup.py index 3a7fea96f..8952b54d8 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ import io import os -from setuptools import find_namespace_packages, setup +import setuptools name = "cloud-sql-python-connector" description = ( @@ -45,11 +45,13 @@ # Only include packages under the 'google' namespace. Do not include tests, # samples, etc. packages = [ - package for package in find_namespace_packages() if package.startswith("google") + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") ] -setup( +setuptools.setup( name=name, version=version, description=description, diff --git a/tests/conftest.py b/tests/conftest.py index f111feec6..9b971eb5c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,15 +20,16 @@ from typing import Any, AsyncGenerator, Generator, Tuple from aioresponses import aioresponses +from google.auth.credentials import Credentials +from google.auth.credentials import with_scopes_if_required +from google.oauth2 import service_account from mock import patch import pytest # noqa F401 Needed to run the tests from unit.mocks import FakeCSQLInstance # type: ignore -from google.auth.credentials import Credentials, with_scopes_if_required from google.cloud.sql.connector import Connector from google.cloud.sql.connector.instance import Instance from google.cloud.sql.connector.utils import generate_keys -from google.oauth2 import service_account SCOPES = ["https://www.googleapis.com/auth/sqlservice.admin"] diff --git a/tests/system/test_asyncpg_connection.py b/tests/system/test_asyncpg_connection.py index 1769f0fbf..7ca7265ed 100644 --- a/tests/system/test_asyncpg_connection.py +++ b/tests/system/test_asyncpg_connection.py @@ -21,7 +21,8 @@ import asyncpg import pytest import sqlalchemy -from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine +from sqlalchemy.ext.asyncio import AsyncEngine +from sqlalchemy.ext.asyncio import create_async_engine from google.cloud.sql.connector import Connector diff --git a/tests/system/test_asyncpg_iam_auth.py b/tests/system/test_asyncpg_iam_auth.py index 5cda850b7..470568076 100644 --- a/tests/system/test_asyncpg_iam_auth.py +++ b/tests/system/test_asyncpg_iam_auth.py @@ -21,7 +21,8 @@ import asyncpg import pytest import sqlalchemy -from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine +from sqlalchemy.ext.asyncio import AsyncEngine +from sqlalchemy.ext.asyncio import create_async_engine from google.cloud.sql.connector import Connector diff --git a/tests/system/test_connector_object.py b/tests/system/test_connector_object.py index 84633cd8c..84d305e27 100644 --- a/tests/system/test_connector_object.py +++ b/tests/system/test_connector_object.py @@ -20,15 +20,13 @@ import os from threading import Thread +import google.auth import pymysql import pytest import sqlalchemy -import google.auth from google.cloud.sql.connector import Connector -from google.cloud.sql.connector.exceptions import ( - AutoIAMAuthNotSupported, -) +from google.cloud.sql.connector.exceptions import AutoIAMAuthNotSupported def init_connection_engine( diff --git a/tests/system/test_ip_types.py b/tests/system/test_ip_types.py index 0c8d6e9ce..4ebcb467d 100644 --- a/tests/system/test_ip_types.py +++ b/tests/system/test_ip_types.py @@ -20,7 +20,8 @@ import pytest import sqlalchemy -from google.cloud.sql.connector import Connector, IPTypes +from google.cloud.sql.connector import Connector +from google.cloud.sql.connector import IPTypes table_name = f"books_{uuid.uuid4().hex}" diff --git a/tests/unit/mocks.py b/tests/unit/mocks.py index 1ed4ecda0..13bb59079 100644 --- a/tests/unit/mocks.py +++ b/tests/unit/mocks.py @@ -23,13 +23,15 @@ from cryptography import x509 from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.x509.oid import NameOID from google.cloud.sql.connector import IPTypes from google.cloud.sql.connector.instance import ConnectionInfo -from google.cloud.sql.connector.utils import generate_keys, write_to_file +from google.cloud.sql.connector.utils import generate_keys +from google.cloud.sql.connector.utils import write_to_file class MockInstance: diff --git a/tests/unit/test_asyncpg.py b/tests/unit/test_asyncpg.py index 6d7473b67..3076a6415 100644 --- a/tests/unit/test_asyncpg.py +++ b/tests/unit/test_asyncpg.py @@ -16,7 +16,8 @@ import ssl from typing import Any -from mock import AsyncMock, patch +from mock import AsyncMock +from mock import patch import pytest from google.cloud.sql.connector.asyncpg import connect diff --git a/tests/unit/test_connector.py b/tests/unit/test_connector.py index 45b8f617e..cc0623c69 100644 --- a/tests/unit/test_connector.py +++ b/tests/unit/test_connector.py @@ -19,7 +19,9 @@ from mocks import MockInstance import pytest # noqa F401 Needed to run the tests -from google.cloud.sql.connector import Connector, create_async_connector, IPTypes +from google.cloud.sql.connector import Connector +from google.cloud.sql.connector import create_async_connector +from google.cloud.sql.connector import IPTypes from google.cloud.sql.connector.exceptions import ConnectorLoopError diff --git a/tests/unit/test_instance.py b/tests/unit/test_instance.py index 2c92d85f1..e13afeb27 100644 --- a/tests/unit/test_instance.py +++ b/tests/unit/test_instance.py @@ -17,24 +17,21 @@ import datetime from typing import Tuple -from aiohttp import ClientResponseError, RequestInfo +from aiohttp import ClientResponseError +from aiohttp import RequestInfo from aioresponses import aioresponses +from google.auth.credentials import Credentials from mock import patch import mocks import pytest # noqa F401 Needed to run the tests -from google.auth.credentials import Credentials -from google.cloud.sql.connector.exceptions import ( - AutoIAMAuthNotSupported, - CloudSQLIPTypeError, - CredentialsTypeError, -) -from google.cloud.sql.connector.instance import ( - _parse_instance_connection_name, - ConnectionInfo, - Instance, - IPTypes, -) +from google.cloud.sql.connector.exceptions import AutoIAMAuthNotSupported +from google.cloud.sql.connector.exceptions import CloudSQLIPTypeError +from google.cloud.sql.connector.exceptions import CredentialsTypeError +from google.cloud.sql.connector.instance import _parse_instance_connection_name +from google.cloud.sql.connector.instance import ConnectionInfo +from google.cloud.sql.connector.instance import Instance +from google.cloud.sql.connector.instance import IPTypes from google.cloud.sql.connector.rate_limiter import AsyncRateLimiter from google.cloud.sql.connector.utils import generate_keys diff --git a/tests/unit/test_rate_limiter.py b/tests/unit/test_rate_limiter.py index 77733898e..587e76809 100644 --- a/tests/unit/test_rate_limiter.py +++ b/tests/unit/test_rate_limiter.py @@ -17,9 +17,7 @@ import pytest # noqa F401 Needed to run the tests -from google.cloud.sql.connector.rate_limiter import ( - AsyncRateLimiter, -) +from google.cloud.sql.connector.rate_limiter import AsyncRateLimiter @pytest.mark.asyncio diff --git a/tests/unit/test_refresh_utils.py b/tests/unit/test_refresh_utils.py index 5688d8996..55f587aaa 100644 --- a/tests/unit/test_refresh_utils.py +++ b/tests/unit/test_refresh_utils.py @@ -14,31 +14,29 @@ limitations under the License. """ import asyncio -from datetime import datetime, timedelta +from datetime import datetime +from datetime import timedelta from typing import Any, no_type_check import aiohttp from aioresponses import aioresponses from conftest import SCOPES # type: ignore -from mock import Mock, patch -from mocks import ( # type: ignore - FakeCSQLInstance, - instance_metadata_expired, - instance_metadata_success, -) -import pytest # noqa F401 Needed to run the tests - import google.auth from google.auth.credentials import Credentials -from google.cloud.sql.connector.refresh_utils import ( - _downscope_credentials, - _get_ephemeral, - _get_metadata, - _is_valid, - _seconds_until_refresh, -) -from google.cloud.sql.connector.utils import generate_keys import google.oauth2.credentials +from mock import Mock +from mock import patch +from mocks import FakeCSQLInstance # type: ignore +from mocks import instance_metadata_expired +from mocks import instance_metadata_success +import pytest # noqa F401 Needed to run the tests + +from google.cloud.sql.connector.refresh_utils import _downscope_credentials +from google.cloud.sql.connector.refresh_utils import _get_ephemeral +from google.cloud.sql.connector.refresh_utils import _get_metadata +from google.cloud.sql.connector.refresh_utils import _is_valid +from google.cloud.sql.connector.refresh_utils import _seconds_until_refresh +from google.cloud.sql.connector.utils import generate_keys @pytest.fixture diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 3d6595efb..d7c384d66 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -13,10 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. """ +from google.auth.credentials import Credentials from mock import patch import pytest # noqa F401 Needed to run the tests -from google.auth.credentials import Credentials from google.cloud.sql.connector import utils