diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index f0f80d482..3270f60e6 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -35,21 +35,19 @@ jobs: nox -s prerelease_deps unit: name: unit${{ matrix.option }}-${{ matrix.python }} - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2303): use `ubuntu-latest` once this bug is fixed. - # Use ubuntu-22.04 until Python 3.7 is removed from the test matrix - # https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest strategy: matrix: python: - - "3.7" - - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" + option: + - "" + - "_protobuf_4x" steps: - name: Checkout uses: actions/checkout@v4 @@ -64,14 +62,14 @@ jobs: python -m pip install nox - name: Run unit tests env: - COVERAGE_FILE: .coverage-${{matrix.python }} + COVERAGE_FILE: .coverage${{ matrix.option }}-${{matrix.python }} run: | - nox -s unit-${{ matrix.python }} + nox -s unit${{ matrix.option }}-${{ matrix.python }} - name: Upload coverage results uses: actions/upload-artifact@v4 with: - name: coverage-artifact-${{ matrix.python }} - path: .coverage-${{ matrix.python }} + name: coverage-artifact-${{ matrix.option }}-${{ matrix.python }} + path: .coverage${{ matrix.option }}-${{ matrix.python }} include-hidden-files: true report-coverage: diff --git a/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg deleted file mode 100644 index a3aa10b5a..000000000 --- a/.kokoro/samples/python3.7/common.cfg +++ /dev/null @@ -1,40 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.7" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-py37" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-api-core/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-api-core/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.7/continuous.cfg b/.kokoro/samples/python3.7/continuous.cfg deleted file mode 100644 index a1c8d9759..000000000 --- a/.kokoro/samples/python3.7/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg deleted file mode 100644 index a18c0cfc6..000000000 --- a/.kokoro/samples/python3.7/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-api-core/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.7/periodic.cfg b/.kokoro/samples/python3.7/periodic.cfg deleted file mode 100644 index 71cd1e597..000000000 --- a/.kokoro/samples/python3.7/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.7/presubmit.cfg b/.kokoro/samples/python3.7/presubmit.cfg deleted file mode 100644 index a1c8d9759..000000000 --- a/.kokoro/samples/python3.7/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg deleted file mode 100644 index 20c941aa9..000000000 --- a/.kokoro/samples/python3.8/common.cfg +++ /dev/null @@ -1,40 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.8" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-py38" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-api-core/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-api-core/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.8/continuous.cfg b/.kokoro/samples/python3.8/continuous.cfg deleted file mode 100644 index a1c8d9759..000000000 --- a/.kokoro/samples/python3.8/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg deleted file mode 100644 index a18c0cfc6..000000000 --- a/.kokoro/samples/python3.8/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-api-core/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.8/periodic.cfg b/.kokoro/samples/python3.8/periodic.cfg deleted file mode 100644 index 71cd1e597..000000000 --- a/.kokoro/samples/python3.8/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.8/presubmit.cfg b/.kokoro/samples/python3.8/presubmit.cfg deleted file mode 100644 index a1c8d9759..000000000 --- a/.kokoro/samples/python3.8/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh index 53e365bc4..55910c8ba 100755 --- a/.kokoro/test-samples-impl.sh +++ b/.kokoro/test-samples-impl.sh @@ -33,8 +33,7 @@ export PYTHONUNBUFFERED=1 env | grep KOKORO # Install nox -# `virtualenv==20.26.6` is added for Python 3.7 compatibility -python3.9 -m pip install --upgrade --quiet nox virtualenv==20.26.6 +python3.9 -m pip install --upgrade --quiet nox # Use secrets acessor service account to get secrets if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 0ac24bc08..946b49d70 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -21,7 +21,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. + 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -197,8 +197,6 @@ Supported Python Versions We support: -- `Python 3.7`_ -- `Python 3.8`_ - `Python 3.9`_ - `Python 3.10`_ - `Python 3.11`_ @@ -206,8 +204,6 @@ We support: - `Python 3.13`_ - `Python 3.14`_ -.. _Python 3.7: https://docs.python.org/3.7/ -.. _Python 3.8: https://docs.python.org/3.8/ .. _Python 3.9: https://docs.python.org/3.9/ .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ diff --git a/google/api_core/_python_package_support.py b/google/api_core/_python_package_support.py index 06da2bb00..d75295f24 100644 --- a/google/api_core/_python_package_support.py +++ b/google/api_core/_python_package_support.py @@ -15,7 +15,6 @@ """Code to check versions of dependencies used by Google Cloud Client Libraries.""" import warnings -import sys from typing import Optional, Tuple from collections import namedtuple @@ -25,12 +24,7 @@ _get_distribution_and_import_packages, ) -if sys.version_info >= (3, 8): - from importlib import metadata -else: - # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove - # this code path once we drop support for Python 3.7 - import importlib_metadata as metadata +from importlib import metadata ParsedVersion = Tuple[int, ...] @@ -43,7 +37,7 @@ _PACKAGE_DEPENDENCY_WARNINGS = [ DependencyConstraint( "google.protobuf", - minimum_fully_supported_version="4.25.8", + minimum_fully_supported_version="5.0.0", recommended_version="6.x", ) ] @@ -85,8 +79,7 @@ def get_dependency_version( """Get the parsed version of an installed package dependency. This function checks for an installed package and returns its version - as a comparable tuple of integers object for safe comparison. It handles - both modern (Python 3.8+) and legacy (Python 3.7) environments. + as a comparable tuple of integers object for safe comparison. Args: dependency_name: The distribution name of the package (e.g., 'requests'). diff --git a/google/api_core/gapic_v1/method.py b/google/api_core/gapic_v1/method.py index 0f14ea9c3..b4481ca19 100644 --- a/google/api_core/gapic_v1/method.py +++ b/google/api_core/gapic_v1/method.py @@ -31,9 +31,6 @@ class _MethodDefault(enum.Enum): # Uses enum so that pytype/mypy knows that this is the only possible value. # https://stackoverflow.com/a/60605919/101923 - # - # Literal[_DEFAULT_VALUE] is an alternative, but only added in Python 3.8. - # https://docs.python.org/3/library/typing.html#typing.Literal _DEFAULT_VALUE = object() diff --git a/google/api_core/grpc_helpers.py b/google/api_core/grpc_helpers.py index 430b8ce48..b1353641c 100644 --- a/google/api_core/grpc_helpers.py +++ b/google/api_core/grpc_helpers.py @@ -27,25 +27,7 @@ from google.api_core import exceptions, general_helpers -PROTOBUF_VERSION = google.protobuf.__version__ - -# The grpcio-gcp package only has support for protobuf < 4 -if PROTOBUF_VERSION[0:2] == "3.": # pragma: NO COVER - try: - import grpc_gcp - - warnings.warn( - """Support for grpcio-gcp is deprecated. This feature will be - removed from `google-api-core` after January 1, 2024. If you need to - continue to use this feature, please pin to a specific version of - `google-api-core`.""", - DeprecationWarning, - ) - HAS_GRPC_GCP = True - except ImportError: - HAS_GRPC_GCP = False -else: - HAS_GRPC_GCP = False +HAS_GRPC_GCP = False # The list of gRPC Callable interfaces that return iterators. @@ -366,8 +348,7 @@ def create_channel( result in `ValueError` as this combination is not yet supported. kwargs: Additional key-word args passed to - :func:`grpc_gcp.secure_channel` or :func:`grpc.secure_channel`. - Note: `grpc_gcp` is only supported in environments with protobuf < 4.0.0. + :func:`grpc.secure_channel`. Returns: grpc.Channel: The created channel. @@ -393,20 +374,6 @@ def create_channel( default_host=default_host, ) - # Note that grpcio-gcp is deprecated - if HAS_GRPC_GCP: # pragma: NO COVER - if compression is not None and compression != grpc.Compression.NoCompression: - warnings.warn( - "The `compression` argument is ignored for grpc_gcp.secure_channel creation.", - DeprecationWarning, - ) - if attempt_direct_path: - warnings.warn( - """The `attempt_direct_path` argument is ignored for grpc_gcp.secure_channel creation.""", - DeprecationWarning, - ) - return grpc_gcp.secure_channel(target, composite_credentials, **kwargs) - if attempt_direct_path: target = _modify_target_for_direct_path(target) diff --git a/google/api_core/operations_v1/__init__.py b/google/api_core/operations_v1/__init__.py index 4db32a4cb..1ff6a833f 100644 --- a/google/api_core/operations_v1/__init__.py +++ b/google/api_core/operations_v1/__init__.py @@ -33,7 +33,7 @@ from google.api_core.operations_v1.operations_rest_client_async import AsyncOperationsRestClient __all__ += ["AsyncOperationsRestClient", "AsyncOperationsRestTransport"] -except ImportError: +except ImportError: # pragma: NO COVER # This import requires the `async_rest` extra. # Don't raise an exception if `AsyncOperationsRestTransport` cannot be imported # as other transports are still available. diff --git a/google/api_core/operations_v1/abstract_operations_base_client.py b/google/api_core/operations_v1/abstract_operations_base_client.py index 160c2a88f..a3e6629ae 100644 --- a/google/api_core/operations_v1/abstract_operations_base_client.py +++ b/google/api_core/operations_v1/abstract_operations_base_client.py @@ -32,7 +32,7 @@ ) HAS_ASYNC_REST_DEPENDENCIES = True -except ImportError as e: +except ImportError as e: # pragma: NO COVER HAS_ASYNC_REST_DEPENDENCIES = False ASYNC_REST_EXCEPTION = e @@ -51,7 +51,7 @@ class AbstractOperationsBaseClientMeta(type): _transport_registry = OrderedDict() # type: Dict[str, Type[OperationsTransport]] _transport_registry["rest"] = OperationsRestTransport - if HAS_ASYNC_REST_DEPENDENCIES: + if HAS_ASYNC_REST_DEPENDENCIES: # pragma: NO COVER _transport_registry["rest_asyncio"] = AsyncOperationsRestTransport def get_transport_class( diff --git a/google/api_core/operations_v1/transports/__init__.py b/google/api_core/operations_v1/transports/__init__.py index 8c24ce6ef..7b6e2878b 100644 --- a/google/api_core/operations_v1/transports/__init__.py +++ b/google/api_core/operations_v1/transports/__init__.py @@ -32,7 +32,7 @@ _transport_registry["rest_asyncio"] = cast( OperationsTransport, AsyncOperationsRestTransport ) -except ImportError: +except ImportError: # pragma: NO COVER # This import requires the `async_rest` extra. # Don't raise an exception if `AsyncOperationsRestTransport` cannot be imported # as other transports are still available. diff --git a/noxfile.py b/noxfile.py index 9f53dbde0..655d6d15e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -28,7 +28,7 @@ # Black and flake8 clash on the syntax for ignoring flake8's F401 in this file. BLACK_EXCLUDES = ["--exclude", "^/google/api_core/operations_v1/__init__.py"] -PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] +PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] DEFAULT_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -40,6 +40,7 @@ "unit_wo_grpc", "unit_w_prerelease_deps", "unit_w_async_rest_extra", + "unit_protobuf_4x", # TODO: Remove once we stop support for protobuf 4.x "cover", "pytype", "mypy", @@ -91,7 +92,9 @@ def install_prerelease_dependencies(session, constraints_path): r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE ) ] - session.install(*constraints_deps) + if constraints_deps: + session.install(*constraints_deps) + prerel_deps = [ "google-auth", "googleapis-common-protos", @@ -107,6 +110,9 @@ def install_prerelease_dependencies(session, constraints_path): # Remaining dependencies other_deps = [ "requests", + "pyasn1", + "cryptography", + "cachetools", ] session.install(*other_deps) @@ -124,7 +130,6 @@ def default(session, install_grpc=True, prerelease=False, install_async_rest=Fal session.install( "dataclasses", - "mock; python_version=='3.7'", "pytest", "pytest-cov", "pytest-mock", @@ -216,29 +221,16 @@ def default(session, install_grpc=True, prerelease=False, install_async_rest=Fal @nox.session(python=PYTHON_VERSIONS) @nox.parametrize( - ["install_grpc_gcp", "install_grpc", "install_async_rest"], + ["install_grpc", "install_async_rest"], [ - (False, True, False), # Run unit tests with grpcio installed - (True, True, False), # Run unit tests with grpcio/grpcio-gcp installed - (False, False, False), # Run unit tests without grpcio installed - (False, True, True), # Run unit tests with grpcio and async rest installed + (True, False), # Run unit tests with grpcio installed + (False, False), # Run unit tests without grpcio installed + (True, True), # Run unit tests with grpcio and async rest installed ], ) -def unit(session, install_grpc_gcp, install_grpc, install_async_rest): +def unit(session, install_grpc, install_async_rest): """Run the unit test suite.""" - # `grpcio-gcp` doesn't support protobuf 4+. - # Remove extra `grpcgcp` when protobuf 3.x is dropped. - # https://github.com/googleapis/python-api-core/issues/594 - if install_grpc_gcp: - constraints_path = str( - CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - ) - # Install grpcio-gcp - session.install("-e", ".[grpcgcp]", "-c", constraints_path) - # Install protobuf < 4.0.0 - session.install("protobuf<4.0.0") - default( session=session, install_grpc=install_grpc, @@ -246,6 +238,18 @@ def unit(session, install_grpc_gcp, install_grpc, install_async_rest): ) +# TODO: Remove once we stop support for protobuf 4.x. +@nox.session(python=PYTHON_VERSIONS) +def unit_protobuf_4x(session): + """Run the unit test suite with protobuf 4.x.""" + if session.python not in ["3.9", "3.10", "3.11"]: + session.log(f"Skipping session for Python {session.python}") + session.skip() + # Pin protobuf to a 4.x version to ensure coverage for the legacy code path. + session.install("protobuf>=4.25.8,<5.0.0") + default(session, install_grpc=True) + + @nox.session(python=DEFAULT_PYTHON_VERSION) def prerelease_deps(session): """Run the unit test suite.""" @@ -276,7 +280,6 @@ def mypy(session): "types-requests", "types-protobuf", "types-dataclasses", - "types-mock; python_version=='3.7'", ) session.run("mypy", "google", "tests") diff --git a/pyproject.toml b/pyproject.toml index 31f82052a..ced0feed9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ build-backend = "setuptools.build_meta" name = "google-api-core" authors = [{ name = "Google LLC", email = "googleapis-packages@google.com" }] license = { text = "Apache 2.0" } -requires-python = ">=3.7" +requires-python = ">=3.9" readme = "README.rst" description = "Google API client core library" classifiers = [ @@ -33,8 +33,7 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -45,15 +44,12 @@ classifiers = [ "Topic :: Internet", ] dependencies = [ - "googleapis-common-protos >= 1.56.2, < 2.0.0", - "protobuf >= 3.19.5, < 7.0.0, != 3.20.0, != 3.20.1, != 4.21.0, != 4.21.1, != 4.21.2, != 4.21.3, != 4.21.4, != 4.21.5", + "googleapis-common-protos >= 1.56.3, < 2.0.0", + "protobuf >= 4.25.8, < 7.0.0", "proto-plus >= 1.22.3, < 2.0.0", "proto-plus >= 1.25.0, < 2.0.0; python_version >= '3.13'", - "google-auth >= 2.14.1, < 3.0.0", - "requests >= 2.18.0, < 3.0.0", - # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove - # `importlib_metadata` once we drop support for Python 3.7 - "importlib_metadata>=1.4; python_version<'3.8'", + "google-auth >= 2.35.0, < 3.0.0", + "requests >= 2.20.0, < 3.0.0", ] dynamic = ["version"] @@ -71,8 +67,7 @@ grpc = [ "grpcio-status >= 1.49.1, < 2.0.0; python_version >= '3.11'", "grpcio-status >= 1.75.1, < 2.0.0; python_version >= '3.14'", ] -grpcgcp = ["grpcio-gcp >= 0.2.2, < 1.0.0"] -grpcio-gcp = ["grpcio-gcp >= 0.2.2, < 1.0.0"] + [tool.setuptools.dynamic] version = { attr = "google.api_core.version.__version__" } @@ -83,7 +78,7 @@ version = { attr = "google.api_core.version.__version__" } include = ["google*"] [tool.mypy] -python_version = "3.7" +python_version = "3.9" namespace_packages = true ignore_missing_imports = true @@ -97,19 +92,12 @@ filterwarnings = [ "ignore:.*The --rsyncdir command line argument and rsyncdirs config variable are deprecated:DeprecationWarning", # Remove once https://github.com/protocolbuffers/protobuf/issues/12186 is fixed "ignore:.*custom tp_new.*in Python 3.14:DeprecationWarning", - # Remove once support for python 3.7 is dropped - # This warning only appears when using python 3.7 - "ignore:.*Using or importing the ABCs from.*collections:DeprecationWarning", - # Remove once support for grpcio-gcp is deprecated - # See https://github.com/googleapis/python-api-core/blob/42e8b6e6f426cab749b34906529e8aaf3f133d75/google/api_core/grpc_helpers.py#L39-L45 - "ignore:.*Support for grpcio-gcp is deprecated:DeprecationWarning", - "ignore: The `compression` argument is ignored for grpc_gcp.secure_channel creation:DeprecationWarning", - "ignore:The `attempt_direct_path` argument is ignored for grpc_gcp.secure_channel creation:DeprecationWarning", + + # Remove once the minimum supported version of googleapis-common-protos is 1.62.0 "ignore:.*pkg_resources.declare_namespace:DeprecationWarning", "ignore:.*pkg_resources is deprecated as an API:DeprecationWarning", # Remove once https://github.com/grpc/grpc/issues/35086 is fixed (and version newer than 1.60.0 is published) "ignore:There is no current event loop:DeprecationWarning", - # Remove after support for Python 3.7 is dropped - "ignore:After January 1, 2024, new releases of this library will drop support for Python 3.7:DeprecationWarning", + ] diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst index 6f069c6c8..f21db80c4 100644 --- a/scripts/readme-gen/templates/install_deps.tmpl.rst +++ b/scripts/readme-gen/templates/install_deps.tmpl.rst @@ -12,7 +12,7 @@ Install Dependencies .. _Python Development Environment Setup Guide: https://cloud.google.com/python/setup -#. Create a virtualenv. Samples are compatible with Python 3.7+. +#. Create a virtualenv. Samples are compatible with Python 3.9+. .. code-block:: bash diff --git a/setup.cfg b/setup.cfg index f7b5a3bc6..54620e1c6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [pytype] -python_version = 3.7 +python_version = 3.9 inputs = google/ exclude = diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt deleted file mode 100644 index 1a9b85d12..000000000 --- a/testing/constraints-3.7.txt +++ /dev/null @@ -1,16 +0,0 @@ -# This constraints file is used to check that lower bounds -# are correct in setup.py -# List *all* library dependencies and extras in this file. -# Pin the version to the lower bound. -# -# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", -# Then this file should have foo==1.14.0 -googleapis-common-protos==1.56.2 -protobuf==3.19.5 -google-auth==2.14.1 -requests==2.18.0 -grpcio==1.33.2 -grpcio-status==1.33.2 -grpcio-gcp==0.2.2 -proto-plus==1.22.3 -importlib_metadata==1.4 diff --git a/testing/constraints-3.8.txt b/testing/constraints-3.8.txt deleted file mode 100644 index 1b5bb58ea..000000000 --- a/testing/constraints-3.8.txt +++ /dev/null @@ -1,2 +0,0 @@ -googleapis-common-protos==1.56.3 -protobuf==4.21.6 \ No newline at end of file diff --git a/testing/constraints-3.9.txt b/testing/constraints-3.9.txt index e69de29bb..082851955 100644 --- a/testing/constraints-3.9.txt +++ b/testing/constraints-3.9.txt @@ -0,0 +1,14 @@ +# This constraints file is used to check that lower bounds +# are correct in pyproject.toml +# List *all* library dependencies and extras in this file. +# Pin the version to the lower bound. +# +# e.g., if pyproject.toml has "foo >= 1.14.0, < 2.0.0dev", +# Then this file should have foo==1.14.0 +googleapis-common-protos==1.56.3 +protobuf==4.25.8 +google-auth==2.35.0 +requests==2.20.0 +grpcio==1.33.2 +grpcio-status==1.33.2 +proto-plus==1.22.3 diff --git a/testing/constraints-async-rest-3.7.txt b/testing/constraints-async-rest-3.7.txt deleted file mode 100644 index 7aedeb1ca..000000000 --- a/testing/constraints-async-rest-3.7.txt +++ /dev/null @@ -1,17 +0,0 @@ -# This constraints file is used to check that lower bounds -# are correct in setup.py -# List *all* library dependencies and extras in this file. -# Pin the version to the lower bound. -# -# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", -# Then this file should have foo==1.14.0 -googleapis-common-protos==1.56.2 -protobuf==3.19.5 -google-auth==2.35.0 -# from google-auth[aiohttp] -aiohttp==3.6.2 -requests==2.20.0 -grpcio==1.33.2 -grpcio-status==1.33.2 -grpcio-gcp==0.2.2 -proto-plus==1.22.3 diff --git a/tests/asyncio/test_operation_async.py b/tests/asyncio/test_operation_async.py index 5b2f012bf..22a4bd68a 100644 --- a/tests/asyncio/test_operation_async.py +++ b/tests/asyncio/test_operation_async.py @@ -181,7 +181,7 @@ async def test_unexpected_result(unused_sleep): async def test_from_gapic(): operation_proto = make_operation_proto(done=True) operations_client = mock.create_autospec( - operations_v1.OperationsClient, instance=True + operations_v1.OperationsAsyncClient, instance=True ) future = operation_async.from_gapic( diff --git a/tests/asyncio/test_rest_streaming_async.py b/tests/asyncio/test_rest_streaming_async.py index 13549c7f9..6aca9ea06 100644 --- a/tests/asyncio/test_rest_streaming_async.py +++ b/tests/asyncio/test_rest_streaming_async.py @@ -33,7 +33,7 @@ try: from google.auth.aio.transport import Response -except ImportError: +except ImportError: # pragma: NO COVER pytest.skip( "google-api-core[async_rest] is required to test asynchronous rest streaming.", allow_module_level=True, diff --git a/tests/unit/test_python_package_support.py b/tests/unit/test_python_package_support.py index 6a93e7154..0feb26440 100644 --- a/tests/unit/test_python_package_support.py +++ b/tests/unit/test_python_package_support.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys import warnings from unittest.mock import patch @@ -31,16 +30,9 @@ @pytest.mark.parametrize("version_string_to_test", ["1.2.3", "1.2.3b1"]) def test_get_dependency_version(mocker, version_string_to_test): """Test get_dependency_version.""" - if sys.version_info >= (3, 8): - mock_importlib = mocker.patch( - "importlib.metadata.version", return_value=version_string_to_test - ) - else: - # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove - # `importlib_metadata` once we drop support for Python 3.7 - mock_importlib = mocker.patch( - "importlib_metadata.version", return_value=version_string_to_test - ) + mock_importlib = mocker.patch( + "importlib.metadata.version", return_value=version_string_to_test + ) expected = DependencyVersion( parse_version_to_tuple(version_string_to_test), version_string_to_test )