diff --git a/changelog.d/20260106_193940_sirosen_fix_typing_strictness_bug.rst b/changelog.d/20260106_193940_sirosen_fix_typing_strictness_bug.rst new file mode 100644 index 000000000..50fc6f99b --- /dev/null +++ b/changelog.d/20260106_193940_sirosen_fix_typing_strictness_bug.rst @@ -0,0 +1,6 @@ +Fixed +----- + +- The type of ``scope_requirements`` in the init signature for ``ClientApp`` + has been expanded to ``typing.Mapping`` to match other locations where a + ``scope_requirements`` mapping is accepted. (:pr:`NUMBER`) diff --git a/src/globus_sdk/globus_app/client_app.py b/src/globus_sdk/globus_app/client_app.py index 4718099c0..f8974beed 100644 --- a/src/globus_sdk/globus_app/client_app.py +++ b/src/globus_sdk/globus_app/client_app.py @@ -61,7 +61,7 @@ def __init__( client_id: uuid.UUID | str | None = None, client_secret: str | None = None, scope_requirements: ( - dict[str, str | Scope | t.Iterable[str | Scope]] | None + t.Mapping[str, str | Scope | t.Iterable[str | Scope]] | None ) = None, config: GlobusAppConfig = DEFAULT_CONFIG, ) -> None: diff --git a/tests/non-pytest/mypy-ignore-tests/app_scope_requirements.py b/tests/non-pytest/mypy-ignore-tests/app_scope_requirements.py index b49b214c5..3b9143245 100644 --- a/tests/non-pytest/mypy-ignore-tests/app_scope_requirements.py +++ b/tests/non-pytest/mypy-ignore-tests/app_scope_requirements.py @@ -1,4 +1,9 @@ -from globus_sdk import UserApp +from types import MappingProxyType + +from globus_sdk import ClientApp, UserApp + +my_user_app = UserApp("...", client_id="...") +my_client_app = ClientApp("...", client_id="...", client_secret="...") # declare scope data in the form of a subtype of the # `str | Scope | t.Iterable[str | Scope]` (`list[str]`) indexed in a dict, @@ -9,5 +14,26 @@ # `dict[str, str | Scope | t.Iterable[str | Scope]]` which will reject the input # type because `dict` is a mutable container, and therefore invariant scopes: dict[str, list[str]] = {"foo": ["bar"]} -my_app = UserApp("...", client_id="...") -my_app.add_scope_requirements(scopes) +my_user_app.add_scope_requirements(scopes) +my_client_app.add_scope_requirements(scopes) + +# a mapping proxy is an immutable mapping (proxy) and should be accepted by apps as well +# meaning that any mapping is fine, not just `dict` specifically (or MutableMapping) +my_user_app.add_scope_requirements(MappingProxyType(scopes)) +my_client_app.add_scope_requirements(MappingProxyType(scopes)) + + +# both of the above tests repeated, but now on init +my_user_app = UserApp("...", client_id="...", scope_requirements=scopes) +my_user_app = UserApp( + "...", client_id="...", scope_requirements=MappingProxyType(scopes) +) +my_client_app = ClientApp( + "...", client_id="...", client_secret="...", scope_requirements=scopes +) +my_client_app = ClientApp( + "...", + client_id="...", + client_secret="...", + scope_requirements=MappingProxyType(scopes), +)