From 6b85f772187975cd77a9dd5b0b496a37236e7abd Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Wed, 12 Apr 2023 14:46:59 -0500 Subject: [PATCH] Fix the return type annotation for get_identities This was annotated as GlobusHTTPResponse when it should have been GetIdentitiesResponse. The result is that type checkers could not see that an iterable type was returned. A new mypy test case confirms that the type is now seen correctly, as well as validating several arguments and usages for get_identities. --- ...20230412_144457_sirosen_fix_type_error.rst | 2 ++ src/globus_sdk/__init__.py | 3 +++ src/globus_sdk/_generate_init.py | 1 + src/globus_sdk/services/auth/__init__.py | 7 ++++- src/globus_sdk/services/auth/client/base.py | 2 +- .../mypy-ignore-tests/get_identities.py | 26 +++++++++++++++++++ 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 changelog.d/20230412_144457_sirosen_fix_type_error.rst create mode 100644 tests/non-pytest/mypy-ignore-tests/get_identities.py diff --git a/changelog.d/20230412_144457_sirosen_fix_type_error.rst b/changelog.d/20230412_144457_sirosen_fix_type_error.rst new file mode 100644 index 000000000..06c68daff --- /dev/null +++ b/changelog.d/20230412_144457_sirosen_fix_type_error.rst @@ -0,0 +1,2 @@ +* The return type of ``AuthClient.get_identities`` is now correctly annotated as + an iterable type, ``globus_sdk.GetIdentitiesResponse`` (:pr:`NUMBER`) diff --git a/src/globus_sdk/__init__.py b/src/globus_sdk/__init__.py index 0308c77de..a3961bb2e 100644 --- a/src/globus_sdk/__init__.py +++ b/src/globus_sdk/__init__.py @@ -56,6 +56,7 @@ def _force_eager_imports() -> None: "ConfidentialAppAuthClient", "IdentityMap", "NativeAppAuthClient", + "GetIdentitiesResponse", "OAuthDependentTokenResponse", "OAuthTokenResponse", }, @@ -151,6 +152,7 @@ def _force_eager_imports() -> None: from .services.auth import ConfidentialAppAuthClient from .services.auth import IdentityMap from .services.auth import NativeAppAuthClient + from .services.auth import GetIdentitiesResponse from .services.auth import OAuthDependentTokenResponse from .services.auth import OAuthTokenResponse from .services.gcs import CollectionDocument @@ -260,6 +262,7 @@ def __getattr__(name: str) -> t.Any: "GCSAPIError", "GCSClient", "GCSRoleDocument", + "GetIdentitiesResponse", "GlobusAPIError", "GlobusConnectPersonalOwnerInfo", "GlobusConnectionError", diff --git a/src/globus_sdk/_generate_init.py b/src/globus_sdk/_generate_init.py index e6ec54cee..c1bd5874e 100755 --- a/src/globus_sdk/_generate_init.py +++ b/src/globus_sdk/_generate_init.py @@ -114,6 +114,7 @@ def __getattr__(name: str) -> t.Any: "ConfidentialAppAuthClient", "IdentityMap", "NativeAppAuthClient", + "GetIdentitiesResponse", "OAuthDependentTokenResponse", "OAuthTokenResponse", ), diff --git a/src/globus_sdk/services/auth/__init__.py b/src/globus_sdk/services/auth/__init__.py index 2a0fb3f9f..11e116687 100644 --- a/src/globus_sdk/services/auth/__init__.py +++ b/src/globus_sdk/services/auth/__init__.py @@ -5,7 +5,11 @@ GlobusNativeAppFlowManager, ) from .identity_map import IdentityMap -from .response import OAuthDependentTokenResponse, OAuthTokenResponse +from .response import ( + GetIdentitiesResponse, + OAuthDependentTokenResponse, + OAuthTokenResponse, +) __all__ = [ "AuthClient", @@ -15,6 +19,7 @@ "IdentityMap", "GlobusNativeAppFlowManager", "GlobusAuthorizationCodeFlowManager", + "GetIdentitiesResponse", "OAuthDependentTokenResponse", "OAuthTokenResponse", ] diff --git a/src/globus_sdk/services/auth/client/base.py b/src/globus_sdk/services/auth/client/base.py index fbfb790b0..7f9ec7b76 100644 --- a/src/globus_sdk/services/auth/client/base.py +++ b/src/globus_sdk/services/auth/client/base.py @@ -83,7 +83,7 @@ def get_identities( ids: t.Iterable[UUIDLike] | UUIDLike | None = None, provision: bool = False, query_params: dict[str, t.Any] | None = None, - ) -> GlobusHTTPResponse: + ) -> GetIdentitiesResponse: r""" Given ``usernames=`` or (exclusive) ``ids=`` as keyword arguments, looks up identity information for the set of identities diff --git a/tests/non-pytest/mypy-ignore-tests/get_identities.py b/tests/non-pytest/mypy-ignore-tests/get_identities.py new file mode 100644 index 000000000..24b14d738 --- /dev/null +++ b/tests/non-pytest/mypy-ignore-tests/get_identities.py @@ -0,0 +1,26 @@ +import uuid + +from globus_sdk import AuthClient + +zero_id = uuid.UUID(int=0) + +# ok usages +ac = AuthClient() +ac.get_identities(ids="foo") +ac.get_identities(ids=zero_id) +ac.get_identities(ids=("foo", "bar")) +ac.get_identities(ids=(zero_id,)) +ac.get_identities(usernames="foo,bar") +ac.get_identities(usernames=("foo", "bar")) +ac.get_identities(usernames=("foo", "bar"), provision=True) +ac.get_identities(usernames=("foo", "bar"), query_params={"provision": False}) + +# bad usage +ac.get_identities(usernames=zero_id) # type: ignore[arg-type] +ac.get_identities(usernames=(zero_id,)) # type: ignore[arg-type] + + +# test the response object is iterable +res = ac.get_identities(usernames="foo") +for x in res: + print(x)