Skip to content

Commit

Permalink
feat: add more missing type info
Browse files Browse the repository at this point in the history
  • Loading branch information
tngraf committed Dec 9, 2023
1 parent 5df9694 commit b583101
Show file tree
Hide file tree
Showing 17 changed files with 507 additions and 302 deletions.
19 changes: 19 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,22 @@ mypy_path = "stubs"
exclude = [
'/tests',
]
show_error_codes = "True"
pretty = "True"

warn_unreachable = "True"
allow_redefinition = "False"

### Strict mode ###
warn_unused_configs = "True"
disallow_subclassing_any = "True"
disallow_any_generics = "True"
disallow_untyped_calls = "True"
disallow_untyped_defs = "True"
disallow_incomplete_defs = "True"
check_untyped_defs = "True"
disallow_untyped_decorators = "True"
no_implicit_optional = "True"
warn_redundant_casts = "True"
warn_unused_ignores = "True"
no_implicit_reexport = "True"
9 changes: 8 additions & 1 deletion stubs/responses.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ from io import BufferedReader, BytesIO
from re import Pattern
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator,
List, Mapping, NamedTuple, Optional, Sequence, Sized,
Tuple, Type, Union)
Tuple, Type, TypeVar, Union)

from requests.adapters import HTTPAdapter
# from urllib3.response import HTTPHeaderDict
Expand Down Expand Up @@ -59,6 +59,13 @@ _real_send = HTTPAdapter.send
_UNSET = object()


F = TypeVar('F', bound=Callable[..., Any])


def activate(func: F) -> F:
...


class FalseBool:
def __bool__(self) -> bool:
...
Expand Down
4 changes: 2 additions & 2 deletions sw360/attachments.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@


class AttachmentsMixin(BaseMixin):
def get_attachment_infos_by_hash(self, hashvalue) -> Optional[Dict[str, Any]]:
def get_attachment_infos_by_hash(self, hashvalue: str) -> Optional[Dict[str, Any]]:
"""Get information about attachments with a given sha1 hash value.
This usually returns zero or one result, but if the same binary file
Expand Down Expand Up @@ -202,7 +202,7 @@ def _upload_resource_attachment(self, resource_type: str, resource_id: str, uplo
if resource_type not in ("releases", "components", "projects"):
raise SW360Error(message="Invalid resource type provided!")

if type(resource_id) is not str:
if (type(resource_id) is not str) or (resource_id == ""):
raise SW360Error(message="Invalid resource id provided!")

filename = os.path.basename(upload_file)
Expand Down
2 changes: 1 addition & 1 deletion sw360/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
class ComponentsMixin(BaseMixin):
# return type List[Dict[str, Any]] | Optional[Dict[str, Any]] for Python 3.11 is good,
# Union[List[Dict[str, Any]], Optional[Dict[str, Any]]] for lower Python versions is not good
def get_all_components(self, fields=None, page=-1, page_size=-1,
def get_all_components(self, fields: str = "", page: int = -1, page_size: int = -1,
all_details: bool = False,
sort: str = "") -> Any:
"""Get information of about all components
Expand Down
2 changes: 1 addition & 1 deletion sw360/license.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def create_new_license(
fullName: str,
text: str,
checked: bool = False,
license_details={},
license_details: Dict[str, Any] = {},
) -> Any:
"""Create a new license
Expand Down
4 changes: 2 additions & 2 deletions sw360/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def get_project_vulnerabilities(self, project_id: str) -> Optional[Dict[str, Any

return resp

def create_new_project(self, name: str, project_type: str, visibility,
def create_new_project(self, name: str, project_type: str, visibility: Any,
description: str = "", version: str = "",
project_details: Dict[str, Any] = {}) -> Optional[Dict[str, Any]]:
"""Create a new project.
Expand Down Expand Up @@ -352,7 +352,7 @@ def update_project(self, project: Dict[str, Any], project_id: str,

raise SW360Error(response, url)

def update_project_releases(self, releases, project_id: str, add: bool = False) -> bool:
def update_project_releases(self, releases: List[Dict[str, Any]], project_id: str, add: bool = False) -> bool:
"""Update the releases of an existing project. If `add` is True,
given `releases` are added to the project, otherwise, the existing
releases will be replaced.
Expand Down
99 changes: 59 additions & 40 deletions tests/test_sw360_attachments.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import os
import sys
import tempfile
from typing import Any
import unittest
import warnings
from unittest.mock import MagicMock, patch
Expand All @@ -26,10 +27,10 @@ class Sw360TestAttachments(unittest.TestCase):
MYURL = "https://my.server.com/"
ERROR_MSG_NO_LOGIN = "Unable to login"

def setUp(self):
def setUp(self) -> None:
warnings.simplefilter("ignore", ResourceWarning)

def _add_login_response(self):
def _add_login_response(self) -> None:
"""
Add the response for a successfull login.
"""
Expand All @@ -42,18 +43,18 @@ def _add_login_response(self):
adding_headers={"Authorization": "Token " + self.MYTOKEN},
)

def _my_matcher(self):
def _my_matcher(self) -> Any:
"""
Helper method to display the JSON parameters of a REST call.
"""
def display_json_params(request_body):
def display_json_params(request_body: Any) -> bool:
print("MyMatcher:'" + request_body + "'")
return True

return display_json_params

@responses.activate
def test_get_attachment_infos_by_hash(self):
def test_get_attachment_infos_by_hash(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -71,14 +72,15 @@ def test_get_attachment_infos_by_hash(self):

data = lib.get_attachment_infos_by_hash("5f392efeb0934339fb6b0f3e021076db19fad164")
self.assertIsNotNone(data)
self.assertTrue("_embedded" in data)
self.assertTrue("sw360:attachments" in data["_embedded"])
att_info = data["_embedded"]["sw360:attachments"]
self.assertTrue(len(att_info) > 0)
self.assertEqual("5f392efeb0934339fb6b0f3e021076db19fad164", att_info[0]["sha1"])
if data: # only for mypy
self.assertTrue("_embedded" in data)
self.assertTrue("sw360:attachments" in data["_embedded"])
att_info = data["_embedded"]["sw360:attachments"]
self.assertTrue(len(att_info) > 0)
self.assertEqual("5f392efeb0934339fb6b0f3e021076db19fad164", att_info[0]["sha1"])

@responses.activate
def test_get_attachment_infos_for_release(self):
def test_get_attachment_infos_for_release(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -100,7 +102,7 @@ def test_get_attachment_infos_for_release(self):
self.assertEqual("ABCD", attachments[0]["sha1"])

@responses.activate
def test_get_attachment_infos_for_component(self):
def test_get_attachment_infos_for_component(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -121,7 +123,7 @@ def test_get_attachment_infos_for_component(self):
self.assertTrue(len(attachments) > 0)

@responses.activate
def test_get_attachment_infos_for_project(self):
def test_get_attachment_infos_for_project(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -142,7 +144,7 @@ def test_get_attachment_infos_for_project(self):
self.assertTrue(len(attachments) > 0)

@responses.activate
def test_get_attachment_by_url(self):
def test_get_attachment_by_url(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -160,36 +162,37 @@ def test_get_attachment_by_url(self):

attachments = lib.get_attachment_by_url(self.MYURL + "resource/api/releases/1234/attachments/5678") # noqa
self.assertIsNotNone(attachments)
self.assertTrue(len(attachments) > 0)
if attachments: # only for mypy
self.assertTrue(len(attachments) > 0)

@responses.activate
def test_download_release_attachment_no_resource_id(self):
def test_download_release_attachment_no_resource_id(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
actual = lib.login_api()
self.assertTrue(actual)

with self.assertRaises(SW360Error) as context:
lib.download_release_attachment("myfile.txt", None, "5678")
lib.download_release_attachment("myfile.txt", "", "5678")

self.assertEqual("No resource id provided!", context.exception.message)

@responses.activate
def test_download_release_attachment_no_attachment_id(self):
def test_download_release_attachment_no_attachment_id(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
actual = lib.login_api()
self.assertTrue(actual)

with self.assertRaises(SW360Error) as context:
lib.download_release_attachment("myfile.txt", "1234", None)
lib.download_release_attachment("myfile.txt", "1234", "")

self.assertEqual("No attachment id provided!", context.exception.message)

@responses.activate
def test_download_release_attachment(self):
def test_download_release_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand Down Expand Up @@ -217,7 +220,7 @@ def test_download_release_attachment(self):
os.removedirs(tmpdir)

@responses.activate
def test_download_release_attachment_404(self):
def test_download_release_attachment_404(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -243,12 +246,20 @@ def test_download_release_attachment_404(self):
with self.assertRaises(SW360Error) as context:
lib.download_release_attachment(filename, "1234", "5678")
self.assertFalse(os.path.exists(filename))

if not context.exception:
self.assertTrue(False, "no exception")

self.assertEqual(context.exception.url, url)
self.assertEqual(context.exception.response.status_code, 404)
if context.exception.response is None:
self.assertTrue(False, "no response")
else:
self.assertEqual(context.exception.response.status_code, 404)

os.removedirs(tmpdir)

@responses.activate
def test_download_project_attachment(self):
def test_download_project_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand Down Expand Up @@ -276,7 +287,7 @@ def test_download_project_attachment(self):
os.removedirs(tmpdir)

@responses.activate
def test_download_component_attachment(self):
def test_download_component_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand Down Expand Up @@ -304,7 +315,7 @@ def test_download_component_attachment(self):
os.removedirs(tmpdir)

@responses.activate
def test_get_attachment(self):
def test_get_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -322,10 +333,11 @@ def test_get_attachment(self):

attachments = lib.get_attachment("1234")
self.assertIsNotNone(attachments)
self.assertTrue(len(attachments) > 0)
if attachments: # only for mypy
self.assertTrue(len(attachments) > 0)

@responses.activate
def test_upload_resource_attachment_no_resource_type(self):
def test_upload_resource_attachment_no_resource_type(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -335,7 +347,7 @@ def test_upload_resource_attachment_no_resource_type(self):
_, filename = tempfile.mkstemp()
self.assertTrue(os.path.exists(filename))
with self.assertRaises(SW360Error) as context:
lib._upload_resource_attachment(None, "123", filename)
lib._upload_resource_attachment("", "123", filename)

self.assertTrue(context.exception.message.startswith("Invalid resource type provided!"))
try:
Expand All @@ -345,7 +357,7 @@ def test_upload_resource_attachment_no_resource_type(self):
pass

@responses.activate
def test_upload_attachment_file_does_not_exist(self):
def test_upload_attachment_file_does_not_exist(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -360,7 +372,7 @@ def test_upload_attachment_file_does_not_exist(self):
self.assertTrue(context.exception.message.startswith("ERROR: file not found:"))

@responses.activate
def test_upload_release_attachment_no_release_id(self):
def test_upload_release_attachment_no_release_id(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -370,7 +382,7 @@ def test_upload_release_attachment_no_release_id(self):
_, filename = tempfile.mkstemp()
self.assertTrue(os.path.exists(filename))
with self.assertRaises(SW360Error) as context:
lib.upload_release_attachment(None, filename)
lib.upload_release_attachment("", filename)

self.assertTrue(context.exception.message.startswith("Invalid resource id provided!"))
try:
Expand All @@ -380,7 +392,7 @@ def test_upload_release_attachment_no_release_id(self):
pass

@responses.activate
def test_upload_release_attachment(self):
def test_upload_release_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -406,7 +418,7 @@ def test_upload_release_attachment(self):
pass

@responses.activate
def test_upload_release_attachment_failed(self):
def test_upload_release_attachment_failed(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand Down Expand Up @@ -434,13 +446,20 @@ def test_upload_release_attachment_failed(self):
# ignore
pass

self.assertEqual(500, context.exception.response.status_code)
self.assertEqual("500", context.exception.details["status"])
self.assertEqual("Internal Server Error", context.exception.details["error"])
self.assertEqual("forbidded", context.exception.details["message"])
if not context.exception:
self.assertTrue(False, "no exception")

if context.exception.response is None:
self.assertTrue(False, "no response")
else:
self.assertEqual(500, context.exception.response.status_code)
if context.exception.details:
self.assertEqual("500", context.exception.details["status"])
self.assertEqual("Internal Server Error", context.exception.details["error"])
self.assertEqual("forbidded", context.exception.details["message"])

@responses.activate
def test_upload_release_attachment_returns_202(self):
def test_upload_release_attachment_returns_202(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand Down Expand Up @@ -476,7 +495,7 @@ def test_upload_release_attachment_returns_202(self):
pass

@responses.activate
def test_upload_component_attachment(self):
def test_upload_component_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand All @@ -502,7 +521,7 @@ def test_upload_component_attachment(self):
pass

@responses.activate
def test_upload_project_attachment(self):
def test_upload_project_attachment(self) -> None:
lib = SW360(self.MYURL, self.MYTOKEN, False)
lib.force_no_session = True
self._add_login_response()
Expand Down
Loading

0 comments on commit b583101

Please sign in to comment.