Skip to content

Commit

Permalink
Merge pull request #2157 from python-gitlab/jlvillal/mypy_step_by_step
Browse files Browse the repository at this point in the history
chore: enable mypy check `warn_return_any`
  • Loading branch information
nejch committed Jul 29, 2022
2 parents 1b7cd31 + 76ec4b4 commit b8be32a
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 13 deletions.
12 changes: 9 additions & 3 deletions gitlab/base.py
Expand Up @@ -21,7 +21,7 @@
import pprint
import textwrap
from types import ModuleType
from typing import Any, Dict, Iterable, Optional, Type, Union
from typing import Any, Dict, Iterable, Optional, Type, TYPE_CHECKING, Union

import gitlab
from gitlab import types as g_types
Expand Down Expand Up @@ -245,14 +245,20 @@ def get_id(self) -> Optional[Union[int, str]]:
"""Returns the id of the resource."""
if self._id_attr is None or not hasattr(self, self._id_attr):
return None
return getattr(self, self._id_attr)
id_val = getattr(self, self._id_attr)
if TYPE_CHECKING:
assert id_val is None or isinstance(id_val, (int, str))
return id_val

@property
def _repr_value(self) -> Optional[str]:
"""Safely returns the human-readable resource name if present."""
if self._repr_attr is None or not hasattr(self, self._repr_attr):
return None
return getattr(self, self._repr_attr)
repr_val = getattr(self, self._repr_attr)
if TYPE_CHECKING:
assert isinstance(repr_val, str)
return repr_val

@property
def encoded_id(self) -> Optional[Union[int, str]]:
Expand Down
20 changes: 17 additions & 3 deletions gitlab/cli.py
Expand Up @@ -23,7 +23,18 @@
import re
import sys
from types import ModuleType
from typing import Any, Callable, cast, Dict, Optional, Tuple, Type, TypeVar, Union
from typing import (
Any,
Callable,
cast,
Dict,
Optional,
Tuple,
Type,
TYPE_CHECKING,
TypeVar,
Union,
)

from requests.structures import CaseInsensitiveDict

Expand Down Expand Up @@ -113,8 +124,11 @@ def gitlab_resource_to_cls(
) -> Type[RESTObject]:
classes = CaseInsensitiveDict(namespace.__dict__)
lowercase_class = gitlab_resource.replace("-", "")

return classes[lowercase_class]
class_type = classes[lowercase_class]
if TYPE_CHECKING:
assert isinstance(class_type, type)
assert issubclass(class_type, RESTObject)
return class_type


def cls_to_gitlab_resource(cls: RESTObject) -> str:
Expand Down
16 changes: 13 additions & 3 deletions gitlab/client.py
Expand Up @@ -439,6 +439,7 @@ def markdown(
data = self.http_post("/markdown", post_data=post_data, **kwargs)
if TYPE_CHECKING:
assert not isinstance(data, requests.Response)
assert isinstance(data["html"], str)
return data["html"]

@gitlab.exceptions.on_http_error(gitlab.exceptions.GitlabLicenseError)
Expand Down Expand Up @@ -808,7 +809,10 @@ def http_get(
and not raw
):
try:
return result.json()
json_result = result.json()
if TYPE_CHECKING:
assert isinstance(json_result, dict)
return json_result
except Exception as e:
raise gitlab.exceptions.GitlabParsingError(
error_message="Failed to parse the server message"
Expand Down Expand Up @@ -989,7 +993,10 @@ def http_post(
)
try:
if result.headers.get("Content-Type", None) == "application/json":
return result.json()
json_result = result.json()
if TYPE_CHECKING:
assert isinstance(json_result, dict)
return json_result
except Exception as e:
raise gitlab.exceptions.GitlabParsingError(
error_message="Failed to parse the server message"
Expand Down Expand Up @@ -1037,7 +1044,10 @@ def http_put(
**kwargs,
)
try:
return result.json()
json_result = result.json()
if TYPE_CHECKING:
assert isinstance(json_result, dict)
return json_result
except Exception as e:
raise gitlab.exceptions.GitlabParsingError(
error_message="Failed to parse the server message"
Expand Down
5 changes: 4 additions & 1 deletion gitlab/mixins.py
Expand Up @@ -755,7 +755,10 @@ def time_stats(self, **kwargs: Any) -> Dict[str, Any]:
# Use the existing time_stats attribute if it exist, otherwise make an
# API call
if "time_stats" in self.attributes:
return self.attributes["time_stats"]
time_stats = self.attributes["time_stats"]
if TYPE_CHECKING:
assert isinstance(time_stats, dict)
return time_stats

path = f"{self.manager.path}/{self.encoded_id}/time_stats"
result = self.manager.gitlab.http_get(path, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Expand Up @@ -16,14 +16,14 @@ disallow_untyped_defs = true
no_implicit_reexport = true
strict_equality = true
warn_redundant_casts = true
warn_return_any = true
warn_unused_configs = true
warn_unused_ignores = true

# The following need to have changes made to be able to enable them:
# disallow_any_generics = true
# disallow_untyped_calls = true
# no_implicit_optional = true
# warn_return_any = true

[[tool.mypy.overrides]] # Overrides for currently untyped modules
module = [
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/objects/test_projects.py
Expand Up @@ -431,7 +431,7 @@ def resp_start_housekeeping():
rsps.add(
method=responses.POST,
url="http://localhost/api/v4/projects/1/housekeeping",
json="0ee4c430667fb7be8461f310",
json={},
content_type="application/json",
status=201,
)
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/test_cli.py
Expand Up @@ -24,6 +24,7 @@

import pytest

import gitlab.base
from gitlab import cli
from gitlab.exceptions import GitlabError

Expand All @@ -43,7 +44,7 @@ def test_gitlab_resource_to_cls(gitlab_resource, expected_class):
def _namespace():
pass

ExpectedClass = type(expected_class, (), {})
ExpectedClass = type(expected_class, (gitlab.base.RESTObject,), {})
_namespace.__dict__[expected_class] = ExpectedClass

assert cli.gitlab_resource_to_cls(gitlab_resource, _namespace) == ExpectedClass
Expand Down

0 comments on commit b8be32a

Please sign in to comment.