diff --git a/packages/abstractions/kiota_abstractions/base_request_configuration.py b/packages/abstractions/kiota_abstractions/base_request_configuration.py index ebfbdc84..e8ef5ec9 100644 --- a/packages/abstractions/kiota_abstractions/base_request_configuration.py +++ b/packages/abstractions/kiota_abstractions/base_request_configuration.py @@ -4,7 +4,7 @@ # See License in the project root for license information. # ------------------------------------ from dataclasses import dataclass, field -from typing import Generic, Optional, TypeVar +from typing import Any, Generic, Optional, TypeVar from warnings import warn from .headers_collection import HeadersCollection @@ -27,9 +27,9 @@ class RequestConfiguration(Generic[QueryParameters]): @dataclass -class BaseRequestConfiguration(RequestConfiguration): +class BaseRequestConfiguration(RequestConfiguration[Any]): - def __post_init__(self): + def __post_init__(self) -> None: warn( "BaseRequestConfiguration is deprecated. Use RequestConfiguration class instead.", DeprecationWarning diff --git a/packages/abstractions/kiota_abstractions/headers_collection.py b/packages/abstractions/kiota_abstractions/headers_collection.py index 93904123..729295dc 100644 --- a/packages/abstractions/kiota_abstractions/headers_collection.py +++ b/packages/abstractions/kiota_abstractions/headers_collection.py @@ -119,7 +119,7 @@ def keys(self) -> list[str]: """ return list(self._headers.keys()) - def count(self): + def count(self) -> int: """Gets the number of headers present in the collection.""" return len(self._headers) diff --git a/packages/abstractions/kiota_abstractions/multipart_body.py b/packages/abstractions/kiota_abstractions/multipart_body.py index ec76540e..e3edbf27 100644 --- a/packages/abstractions/kiota_abstractions/multipart_body.py +++ b/packages/abstractions/kiota_abstractions/multipart_body.py @@ -146,7 +146,9 @@ def _get_comtent_disposition( return f'form-data; name="{part_name}"; filename="{part_value[2]}"' return f'form-data; name="{part_name}"' - def _write_parsable(self, writer, part_value) -> None: + def _write_parsable( + self, writer: SerializationWriter, part_value: tuple[str, Any, Optional[str]] + ) -> None: if not self.request_adapter or not self.request_adapter.get_serialization_writer_factory(): raise ValueError("Request adapter or serialization writer factory cannot be null") part_writer = ( diff --git a/packages/abstractions/kiota_abstractions/request_information.py b/packages/abstractions/kiota_abstractions/request_information.py index 9538f177..79239196 100644 --- a/packages/abstractions/kiota_abstractions/request_information.py +++ b/packages/abstractions/kiota_abstractions/request_information.py @@ -81,7 +81,9 @@ def __init__( # The Request Body self.content: Optional[bytes] = None - def configure(self, request_configuration: Optional[RequestConfiguration]) -> None: + def configure( + self, request_configuration: Optional[RequestConfiguration[QueryParameters]] + ) -> None: """Configures the current request information headers, query parameters, and options based on the request configuration provided @@ -100,7 +102,7 @@ def url(self) -> Url: raw_url = self.path_parameters.get(self.RAW_URL_KEY) if self.__uri: return self.__uri - if raw_url: + if isinstance(raw_url, str) and raw_url: return raw_url if self.query_parameters is None: raise Exception("Query parameters cannot be null") @@ -130,7 +132,7 @@ def url(self, url: Url) -> None: self.path_parameters.clear() @property - def request_headers(self) -> Optional[dict]: + def request_headers(self) -> Optional[dict[str, str]]: final = {} for key, values in self.headers.get_all().items(): final[key] = ', '.join(values) @@ -203,10 +205,10 @@ def set_content_from_scalar( writer = self._get_serialization_writer(request_adapter, content_type, span) if isinstance(values, list): - writer.writer = writer.write_collection_of_primitive_values(None, values) + writer.write_collection_of_primitive_values(None, values) span.set_attribute(self.REQUEST_TYPE_KEY, "[]") else: - function_values: dict[type, Callable] = { + function_values: dict[type, Callable[[Optional[str], Any], None]] = { bool: writer.write_bool_value, str: writer.write_str_value, int: writer.write_int_value, @@ -246,7 +248,7 @@ def set_query_string_parameters_from_raw_object(self, q: Optional[QueryParameter for field in fields(q): key = field.name if hasattr(q, "get_query_parameter"): - serialization_key = q.get_query_parameter(key) # type: ignore + serialization_key = q.get_query_parameter(key) if serialization_key: key = serialization_key value = getattr(q, field.name) @@ -258,7 +260,7 @@ def _get_serialization_writer( request_adapter: Optional["RequestAdapter"], content_type: Optional[str], parent_span: trace.Span, - ): + ) -> SerializationWriter: """_summary_ Args: @@ -282,7 +284,7 @@ def _get_serialization_writer( def _set_content_and_content_type_header( self, writer: SerializationWriter, content_type: Optional[str] - ): + ) -> None: if content_type: self.headers.try_add(self.CONTENT_TYPE_HEADER, content_type) self.content = writer.get_serialized_content() diff --git a/packages/abstractions/kiota_abstractions/utils.py b/packages/abstractions/kiota_abstractions/utils.py index 6e01b84b..e0433ebd 100644 --- a/packages/abstractions/kiota_abstractions/utils.py +++ b/packages/abstractions/kiota_abstractions/utils.py @@ -1,8 +1,9 @@ import importlib.util import sys +from types import ModuleType -def lazy_import(name): +def lazy_import(name: str) -> ModuleType: """Lazily imports a python module given its absolute path. Note: This a utility method for use in Kiota generated code only and not @@ -26,6 +27,9 @@ def lazy_import(name): if not spec: raise ValueError(f"No spec found for: {name}") + if not spec.loader: + raise ValueError(f"No loader found for: {name}") + loader = importlib.util.LazyLoader(spec.loader) spec.loader = loader diff --git a/packages/abstractions/tests/test_request_information.py b/packages/abstractions/tests/test_request_information.py index 4b2b782f..a257975b 100644 --- a/packages/abstractions/tests/test_request_information.py +++ b/packages/abstractions/tests/test_request_information.py @@ -10,6 +10,7 @@ from kiota_abstractions.headers_collection import HeadersCollection from kiota_abstractions.method import Method from kiota_abstractions.request_information import RequestInformation +from kiota_abstractions.serialization import SerializationWriter from .conftest import QueryParams, TestEnum @@ -153,6 +154,18 @@ def test_sets_boundary_on_multipart_request_body( assert mock_request_information.headers.get("content-type") == {"multipart/form-data; boundary=" + mock_multipart_body.boundary} +def test_sets_content_from_a_list_of_scalars( + mock_request_information, mock_request_adapter, mock_serialization_writer_factory +): + writer = Mock(spec_set=SerializationWriter) + writer.get_serialized_content.return_value = b"[1,2]" + mock_serialization_writer_factory.get_serialization_writer = Mock(return_value=writer) + mock_request_adapter.get_serialization_writer_factory = Mock(return_value=mock_serialization_writer_factory) + mock_request_information.set_content_from_scalar(mock_request_adapter, "application/json", [1, 2]) + writer.write_collection_of_primitive_values.assert_called_once_with(None, [1, 2]) + assert mock_request_information.content == b"[1,2]" + + def test_sets_enum_value_in_query_parameters(): """Tests setting enum values in query parameters """