Skip to content

Commit

Permalink
feat: Add support for Python 3.13 (#315)
Browse files Browse the repository at this point in the history
* chore: Configure Ruby clients for google-ads-ad_manager

PiperOrigin-RevId: 689139590

Source-Link: googleapis/googleapis@296f2ac

Source-Link: googleapis/googleapis-gen@2692736
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMjY5MjczNjJlMGFhMTI5MzI1OGZjMjNmZTNjZTgzYzVjMjFkNWZiYiJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* chore: remove body selector from http rule

PiperOrigin-RevId: 693215877

Source-Link: googleapis/googleapis@bb6b53e

Source-Link: googleapis/googleapis-gen@db8b5a9
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiZGI4YjVhOTM0ODRhZDQ0MDU1YjJiYWNjNGM3Y2Y4N2U5NzBmZTBlZCJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* Add python 3.13 to unittest.yml / noxfile.py

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* Add python 3.13 to noxfile.py

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Co-authored-by: Anthonios Partheniou <partheniou@google.com>
  • Loading branch information
3 people authored Nov 12, 2024
1 parent 445d335 commit 2b6bd80
Show file tree
Hide file tree
Showing 7 changed files with 17 additions and 123 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
40 changes: 3 additions & 37 deletions google/cloud/orgpolicy_v2/services/org_policy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,36 +519,6 @@ def _get_universe_domain(
raise ValueError("Universe Domain cannot be an empty string.")
return universe_domain

@staticmethod
def _compare_universes(
client_universe: str, credentials: ga_credentials.Credentials
) -> bool:
"""Returns True iff the universe domains used by the client and credentials match.
Args:
client_universe (str): The universe domain configured via the client options.
credentials (ga_credentials.Credentials): The credentials being used in the client.
Returns:
bool: True iff client_universe matches the universe in credentials.
Raises:
ValueError: when client_universe does not match the universe in credentials.
"""

default_universe = OrgPolicyClient._DEFAULT_UNIVERSE
credentials_universe = getattr(credentials, "universe_domain", default_universe)

if client_universe != credentials_universe:
raise ValueError(
"The configured universe domain "
f"({client_universe}) does not match the universe domain "
f"found in the credentials ({credentials_universe}). "
"If you haven't configured the universe domain explicitly, "
f"`{default_universe}` is the default."
)
return True

def _validate_universe_domain(self):
"""Validates client's and credentials' universe domains are consistent.
Expand All @@ -558,13 +528,9 @@ def _validate_universe_domain(self):
Raises:
ValueError: If the configured universe domain is not valid.
"""
self._is_universe_domain_valid = (
self._is_universe_domain_valid
or OrgPolicyClient._compare_universes(
self.universe_domain, self.transport._credentials
)
)
return self._is_universe_domain_valid

# NOTE (b/349488459): universe validation is disabled until further notice.
return True

@property
def api_endpoint(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
grpc_version=None,
rest_version=requests_version,
rest_version=f"requests@{requests_version}",
)


Expand Down
8 changes: 4 additions & 4 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

DEFAULT_PYTHON_VERSION = "3.8"

UNIT_TEST_PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
UNIT_TEST_PYTHON_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
UNIT_TEST_STANDARD_DEPENDENCIES = [
"mock",
"asyncmock",
Expand Down Expand Up @@ -384,15 +384,15 @@ def docfx(session):
)


@nox.session(python="3.12")
@nox.session(python="3.13")
@nox.parametrize(
"protobuf_implementation",
["python", "upb", "cpp"],
)
def prerelease_deps(session, protobuf_implementation):
"""Run all tests with prerelease versions of dependencies installed."""

if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"):
if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"):
session.skip("cpp implementation is not supported in python 3.11+")

# Install all dependencies
Expand Down Expand Up @@ -489,7 +489,7 @@ def unit_remote(session, library, prerelease, protobuf_implementation):
* Asset: GAPIC which uses google-cloud-org-policy
"""

if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"):
if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"):
session.skip("cpp implementation is not supported in python 3.11+")

repository, package = library
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
# See https://github.com/googleapis/google-cloud-python/issues/12364
"google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0",
"proto-plus >= 1.22.3, <2.0.0dev",
"proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'",
"protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5",
]
extras = {}
Expand Down Expand Up @@ -82,6 +83,7 @@
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
"Topic :: Internet",
],
Expand Down
6 changes: 6 additions & 0 deletions testing/constraints-3.13.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# This constraints file is required for unit tests.
# List all library dependencies and extras in this file.
google-api-core
proto-plus
protobuf
80 changes: 0 additions & 80 deletions tests/unit/gapic/orgpolicy_v2/test_org_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,86 +296,6 @@ def test__get_universe_domain():
assert str(excinfo.value) == "Universe Domain cannot be an empty string."


@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
[
(OrgPolicyClient, transports.OrgPolicyGrpcTransport, "grpc"),
(OrgPolicyClient, transports.OrgPolicyRestTransport, "rest"),
],
)
def test__validate_universe_domain(client_class, transport_class, transport_name):
client = client_class(
transport=transport_class(credentials=ga_credentials.AnonymousCredentials())
)
assert client._validate_universe_domain() == True

# Test the case when universe is already validated.
assert client._validate_universe_domain() == True

if transport_name == "grpc":
# Test the case where credentials are provided by the
# `local_channel_credentials`. The default universes in both match.
channel = grpc.secure_channel(
"http://localhost/", grpc.local_channel_credentials()
)
client = client_class(transport=transport_class(channel=channel))
assert client._validate_universe_domain() == True

# Test the case where credentials do not exist: e.g. a transport is provided
# with no credentials. Validation should still succeed because there is no
# mismatch with non-existent credentials.
channel = grpc.secure_channel(
"http://localhost/", grpc.local_channel_credentials()
)
transport = transport_class(channel=channel)
transport._credentials = None
client = client_class(transport=transport)
assert client._validate_universe_domain() == True

# TODO: This is needed to cater for older versions of google-auth
# Make this test unconditional once the minimum supported version of
# google-auth becomes 2.23.0 or higher.
google_auth_major, google_auth_minor = [
int(part) for part in google.auth.__version__.split(".")[0:2]
]
if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23):
credentials = ga_credentials.AnonymousCredentials()
credentials._universe_domain = "foo.com"
# Test the case when there is a universe mismatch from the credentials.
client = client_class(transport=transport_class(credentials=credentials))
with pytest.raises(ValueError) as excinfo:
client._validate_universe_domain()
assert (
str(excinfo.value)
== "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default."
)

# Test the case when there is a universe mismatch from the client.
#
# TODO: Make this test unconditional once the minimum supported version of
# google-api-core becomes 2.15.0 or higher.
api_core_major, api_core_minor = [
int(part) for part in api_core_version.__version__.split(".")[0:2]
]
if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15):
client = client_class(
client_options={"universe_domain": "bar.com"},
transport=transport_class(
credentials=ga_credentials.AnonymousCredentials(),
),
)
with pytest.raises(ValueError) as excinfo:
client._validate_universe_domain()
assert (
str(excinfo.value)
== "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default."
)

# Test that ValueError is raised if universe_domain is provided via client options and credentials is None
with pytest.raises(ValueError):
client._compare_universes("foo.bar", None)


@pytest.mark.parametrize(
"client_class,transport_name",
[
Expand Down

0 comments on commit 2b6bd80

Please sign in to comment.