diff --git a/gitlab/v4/objects/users.py b/gitlab/v4/objects/users.py index 69d72e9d7..69d875ed9 100644 --- a/gitlab/v4/objects/users.py +++ b/gitlab/v4/objects/users.py @@ -3,7 +3,7 @@ https://docs.gitlab.com/ee/api/users.html https://docs.gitlab.com/ee/api/projects.html#list-projects-starred-by-a-user """ -from typing import Any, cast, Dict, List, Union +from typing import Any, cast, Dict, List, Optional, Union import requests @@ -163,7 +163,7 @@ class User(SaveMixin, ObjectDeleteMixin, RESTObject): @cli.register_custom_action("User") @exc.on_http_error(exc.GitlabBlockError) - def block(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]: + def block(self, **kwargs: Any) -> Optional[bool]: """Block the user. Args: @@ -177,7 +177,11 @@ def block(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]: Whether the user status has been changed """ path = f"/users/{self.encoded_id}/block" - server_data = self.manager.gitlab.http_post(path, **kwargs) + # NOTE: Undocumented behavior of the GitLab API is that it returns a + # boolean or None + server_data = cast( + Optional[bool], self.manager.gitlab.http_post(path, **kwargs) + ) if server_data is True: self._attrs["state"] = "blocked" return server_data @@ -220,7 +224,7 @@ def unfollow(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]: @cli.register_custom_action("User") @exc.on_http_error(exc.GitlabUnblockError) - def unblock(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]: + def unblock(self, **kwargs: Any) -> Optional[bool]: """Unblock the user. Args: @@ -234,7 +238,11 @@ def unblock(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]: Whether the user status has been changed """ path = f"/users/{self.encoded_id}/unblock" - server_data = self.manager.gitlab.http_post(path, **kwargs) + # NOTE: Undocumented behavior of the GitLab API is that it returns a + # boolean or None + server_data = cast( + Optional[bool], self.manager.gitlab.http_post(path, **kwargs) + ) if server_data is True: self._attrs["state"] = "active" return server_data diff --git a/pyproject.toml b/pyproject.toml index dcb578c69..43359e986 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,8 @@ disallow_incomplete_defs = true disallow_subclassing_any = true disallow_untyped_decorators = true disallow_untyped_defs = true +no_implicit_reexport = true +strict_equality = true warn_redundant_casts = true warn_unused_configs = true warn_unused_ignores = true @@ -21,8 +23,6 @@ warn_unused_ignores = true # disallow_any_generics = true # disallow_untyped_calls = true # no_implicit_optional = true -no_implicit_reexport = true -# strict_equality = true # warn_return_any = true [[tool.mypy.overrides]] # Overrides for currently untyped modules diff --git a/tests/functional/api/test_users.py b/tests/functional/api/test_users.py index bdee1304d..a099e8fb2 100644 --- a/tests/functional/api/test_users.py +++ b/tests/functional/api/test_users.py @@ -28,14 +28,26 @@ def test_create_user(gl, fixture_dir): def test_block_user(gl, user): - user.block() + result = user.block() + assert result is True users = gl.users.list(blocked=True) assert user in users - user.unblock() + # block again + result = user.block() + # Trying to block an already blocked user returns None + assert result is None + + result = user.unblock() + assert result is True users = gl.users.list(blocked=False) assert user in users + # unblock again + result = user.unblock() + # Trying to unblock an already blocked user returns False + assert result is False + def test_ban_user(gl, user): user.ban()