Skip to content

Commit 16e1779

Browse files
committed
fixed ruff typing errors
1 parent b73482d commit 16e1779

15 files changed

Lines changed: 144 additions & 81 deletions

.agent/rules/code-style-guide.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
trigger: always_on
3+
---
4+
5+
# General
6+
7+
- All code in English
8+
- Add comments only when needed
9+
- Add docstrings for every function
10+
- Use type hints in all functions
11+
- Use f-strings
12+
- Follow PEP 8 and clean code principles
13+
- Imports always at the top
14+
- Avoid short variable names, abbreviations, or single-letter names
15+
- Avoid the use of noqa unless strictly necessary
16+
17+
# Test
18+
19+
- Add tests following TDD practices
20+
- Mirror the amazon_paapi structure in the tests directory
21+
- Use unittest.TestCase with setUp() and tearDown()
22+
- Use unittest assertions, not native assert
23+
- Use @patch decorators for mocks (avoid context managers)
24+
25+
# References
26+
27+
- Documentation for the Product Advertising API here: https://webservices.amazon.com/paapi5/documentation/operations.html

amazon_paapi/api.py

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
A simple Python wrapper for the last version of the Amazon Product Advertising API.
44
"""
55

6+
from __future__ import annotations
7+
68
import time
7-
from typing import Any, List, Optional, Union
9+
from typing import TYPE_CHECKING, Any
810

911
from . import models
1012
from .errors import InvalidArgument
1113
from .helpers import arguments, requests
1214
from .helpers.generators import get_list_chunks
1315
from .helpers.items import sort_items
14-
from .models.regions import CountryCode
1516
from .sdk.api.default_api import DefaultApi
1617

18+
if TYPE_CHECKING:
19+
from .models.regions import CountryCode
20+
1721

1822
class AmazonApi:
1923
"""Provides methods to get information from Amazon using your API credentials.
@@ -61,14 +65,14 @@ def __init__(
6165

6266
def get_items(
6367
self,
64-
items: Union[str, List[str]],
68+
items: str | list[str],
6569
condition: models.Condition = None,
6670
merchant: models.Merchant = None,
67-
currency_of_preference: Optional[str] = None,
68-
languages_of_preference: Optional[List[str]] = None,
71+
currency_of_preference: str | None = None,
72+
languages_of_preference: list[str] | None = None,
6973
include_unavailable: bool = False,
7074
**kwargs: Any,
71-
) -> List[models.Item]:
75+
) -> list[models.Item]:
7276
"""Get items information from Amazon.
7377
7478
Args:
@@ -116,30 +120,30 @@ def get_items(
116120
items_response = requests.get_items_response(self, request)
117121
results.extend(items_response)
118122

119-
return sort_items(results, items_ids, include_unavailable)
123+
return sort_items(results, items_ids, include_unavailable=include_unavailable)
120124

121125
def search_items(
122126
self, # NOSONAR
123-
item_count: Optional[int] = None,
124-
item_page: Optional[int] = None,
125-
actor: Optional[str] = None,
126-
artist: Optional[str] = None,
127-
author: Optional[str] = None,
128-
brand: Optional[str] = None,
129-
keywords: Optional[str] = None,
130-
title: Optional[str] = None,
127+
item_count: int | None = None,
128+
item_page: int | None = None,
129+
actor: str | None = None,
130+
artist: str | None = None,
131+
author: str | None = None,
132+
brand: str | None = None,
133+
keywords: str | None = None,
134+
title: str | None = None,
131135
availability: models.Availability = None,
132-
browse_node_id: Optional[str] = None,
136+
browse_node_id: str | None = None,
133137
condition: models.Condition = None,
134-
currency_of_preference: Optional[str] = None,
135-
delivery_flags: Optional[List[str]] = None,
136-
languages_of_preference: Optional[List[str]] = None,
138+
currency_of_preference: str | None = None,
139+
delivery_flags: list[str] | None = None,
140+
languages_of_preference: list[str] | None = None,
137141
merchant: models.Merchant = None,
138-
max_price: Optional[int] = None,
139-
min_price: Optional[int] = None,
140-
min_saving_percent: Optional[int] = None,
141-
min_reviews_rating: Optional[int] = None,
142-
search_index: Optional[str] = None,
142+
max_price: int | None = None,
143+
min_price: int | None = None,
144+
min_saving_percent: int | None = None,
145+
min_reviews_rating: int | None = None,
146+
search_index: str | None = None,
143147
sort_by: models.SortBy = None,
144148
**kwargs: Any,
145149
) -> models.SearchResult:
@@ -238,11 +242,11 @@ def search_items(
238242
def get_variations(
239243
self,
240244
asin: str,
241-
variation_count: Optional[int] = None,
242-
variation_page: Optional[int] = None,
245+
variation_count: int | None = None,
246+
variation_page: int | None = None,
243247
condition: models.Condition = None,
244-
currency_of_preference: Optional[str] = None,
245-
languages_of_preference: Optional[List[str]] = None,
248+
currency_of_preference: str | None = None,
249+
languages_of_preference: list[str] | None = None,
246250
merchant: models.Merchant = None,
247251
**kwargs: Any,
248252
) -> models.VariationsResult:
@@ -300,10 +304,10 @@ def get_variations(
300304

301305
def get_browse_nodes(
302306
self,
303-
browse_node_ids: List[str],
304-
languages_of_preference: Optional[List[str]] = None,
307+
browse_node_ids: list[str],
308+
languages_of_preference: list[str] | None = None,
305309
**kwargs: Any,
306-
) -> List[models.BrowseNode]:
310+
) -> list[models.BrowseNode]:
307311
"""Return the specified browse node's information.
308312
309313
Information includes name, children, and ancestors.

amazon_paapi/helpers/arguments.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
"""Module with helper functions for managing arguments."""
22

3-
from typing import Any, List, Union
3+
from __future__ import annotations
4+
5+
from typing import Any
46

57
from amazon_paapi.errors import InvalidArgument
68
from amazon_paapi.tools import get_asin
79

810

9-
def get_items_ids(items: Union[str, List[str]]) -> List[str]:
11+
def get_items_ids(items: str | list[str]) -> list[str]:
1012
"""Parse and extract ASINs from items input.
1113
1214
Args:
@@ -80,6 +82,6 @@ def check_variations_args(**kwargs: Any) -> None:
8082

8183
def check_browse_nodes_args(**kwargs: Any) -> None:
8284
"""Validate browse node arguments."""
83-
if not isinstance(kwargs.get("browse_node_ids"), List):
85+
if not isinstance(kwargs.get("browse_node_ids"), list):
8486
error_message = "Argument browse_node_ids should be a List of strings."
8587
raise InvalidArgument(error_message)

amazon_paapi/helpers/generators.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
"""Module with helper functions for making generators."""
22

3-
from typing import Generator, List
3+
from __future__ import annotations
4+
5+
from typing import TYPE_CHECKING
6+
7+
if TYPE_CHECKING:
8+
from collections.abc import Generator
49

510

611
def get_list_chunks(
7-
full_list: List[str], chunk_size: int
8-
) -> Generator[List[str], None, None]:
12+
full_list: list[str], chunk_size: int
13+
) -> Generator[list[str], None, None]:
914
"""Yield successive chunks from List."""
1015
for i in range(0, len(full_list), chunk_size):
1116
yield full_list[i : i + chunk_size]

amazon_paapi/helpers/items.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
"""Module to manage items."""
22

3-
from typing import List
3+
from __future__ import annotations
44

55
from amazon_paapi import models
66

77

88
def sort_items(
9-
items: List[models.Item], items_ids: List[str], include_unavailable: bool
10-
) -> List[models.Item]:
9+
items: list[models.Item], items_ids: list[str], *, include_unavailable: bool
10+
) -> list[models.Item]:
1111
"""Sort items by the order of the provided items_ids list."""
12-
sorted_items: List[models.Item] = []
12+
sorted_items: list[models.Item] = []
1313

1414
for asin in items_ids:
15-
matches: List[models.Item] = [item for item in items if item.asin == asin]
15+
matches: list[models.Item] = [item for item in items if item.asin == asin]
1616
if matches:
1717
sorted_items.append(matches[0])
1818
elif include_unavailable:

amazon_paapi/helpers/requests.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
import inspect
66
from typing import TYPE_CHECKING, Any, List, NoReturn, cast
77

8-
if TYPE_CHECKING:
9-
from amazon_paapi.api import AmazonApi
10-
from amazon_paapi.sdk.rest import ApiException as ApiExceptionType
11-
128
from amazon_paapi.errors import (
139
AssociateValidationError,
1410
InvalidArgument,
@@ -31,6 +27,10 @@
3127
from amazon_paapi.sdk.models.search_items_request import SearchItemsRequest
3228
from amazon_paapi.sdk.models.search_items_resource import SearchItemsResource
3329
from amazon_paapi.sdk.rest import ApiException
30+
from amazon_paapi.sdk.rest import ApiException as ApiExceptionType
31+
32+
if TYPE_CHECKING:
33+
from amazon_paapi.api import AmazonApi
3434

3535

3636
def get_items_request(
@@ -169,10 +169,10 @@ def get_browse_nodes_response(
169169
return cast(List[BrowseNode], response.browse_nodes_result.browse_nodes)
170170

171171

172-
def _get_request_resources(resources: type[object]) -> list[str]:
172+
def _get_request_resources(resource_class: type[object]) -> list[str]:
173173
"""Extract all resource strings from a resource class."""
174-
resources = inspect.getmembers(resources, lambda a: not inspect.isroutine(a))
175-
return [x[-1] for x in resources if isinstance(x[-1], str) and x[0][0:2] != "__"]
174+
members = inspect.getmembers(resource_class, lambda a: not inspect.isroutine(a))
175+
return [x[-1] for x in members if isinstance(x[-1], str) and x[0][0:2] != "__"]
176176

177177

178178
def _manage_response_exceptions(error: ApiExceptionType) -> NoReturn:

amazon_paapi/models/browse_nodes_result.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Browse node result models for Amazon Product Advertising API."""
22

3-
from typing import List
3+
from __future__ import annotations
44

55
from amazon_paapi.sdk import models as sdk_models
66

@@ -26,5 +26,5 @@ class BrowseNode(sdk_models.BrowseNode):
2626
id: str
2727
is_root: bool
2828
context_free_name: str
29-
children: List[BrowseNodeChild]
29+
children: list[BrowseNodeChild]
3030
ancestor: BrowseNodeAncestor

amazon_paapi/models/item_result.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Item result models for Amazon Product Advertising API."""
22

3-
from typing import List, Optional
3+
from __future__ import annotations
44

55
from amazon_paapi.sdk import models as sdk_models
66

@@ -15,7 +15,7 @@ class ApiLabelLocale:
1515
class ApiMultiValuedAttributeStr(ApiLabelLocale, sdk_models.MultiValuedAttribute):
1616
"""Multi-valued attribute with string display values."""
1717

18-
display_values: List[str]
18+
display_values: list[str]
1919

2020

2121
class ApiDisplayValuesType:
@@ -28,7 +28,7 @@ class ApiDisplayValuesType:
2828
class ApiMultiValuedAttributeType(ApiLabelLocale, sdk_models.MultiValuedAttribute):
2929
"""Multi-valued attribute with typed display values."""
3030

31-
display_values: List[ApiDisplayValuesType]
31+
display_values: list[ApiDisplayValuesType]
3232

3333

3434
class ApiUnitBasedAttribute(ApiLabelLocale, sdk_models.UnitBasedAttribute):
@@ -93,7 +93,7 @@ class ApiImages(sdk_models.Images):
9393
"""Container for primary and variant images."""
9494

9595
primary: ApiImageType
96-
variants: List[ApiImageType]
96+
variants: list[ApiImageType]
9797

9898

9999
class ApiByLineInfo(sdk_models.ByLineInfo):
@@ -116,7 +116,7 @@ class ApiContentInfo(sdk_models.ContentInfo):
116116

117117
edition: ApiSingleStringValuedAttribute
118118
languages: ApiMultiValuedAttributeType
119-
publication_date: Optional[ApiSingleStringValuedAttribute]
119+
publication_date: ApiSingleStringValuedAttribute | None
120120

121121

122122
class ApiContentRating(sdk_models.ContentRating):
@@ -194,12 +194,12 @@ class ApiItemInfo(sdk_models.ItemInfo):
194194

195195
by_line_info: ApiByLineInfo
196196
classifications: ApiClassifications
197-
content_info: Optional[ApiContentInfo]
197+
content_info: ApiContentInfo | None
198198
content_rating: ApiContentRating
199199
external_ids: ApiExternalIds
200200
features: ApiFeatures
201201
manufacture_info: ApiManufactureInfo
202-
product_info: Optional[ApiProductInfo]
202+
product_info: ApiProductInfo | None
203203
technical_info: ApiTechnicalInfo
204204
title: ApiSingleStringValuedAttribute
205205
trade_in_info: ApiTradeInInfo
@@ -303,15 +303,15 @@ class ApiListings(sdk_models.OfferListing):
303303
merchant_info: ApiOfferMerchantInfo
304304
price: ApiOfferPrice
305305
program_eligibility: ApiOfferProgramEligibility
306-
promotions: List[ApiPromotion]
306+
promotions: list[ApiPromotion]
307307
saving_basis: ApiPrice
308308
violates_map: bool
309309

310310

311311
class ApiOffers(sdk_models.Offers):
312312
"""Container for offer listings."""
313313

314-
listings: List[ApiListings]
314+
listings: list[ApiListings]
315315

316316

317317
class ApiBrowseNode(sdk_models.BrowseNode):
@@ -336,7 +336,7 @@ class ApiWebsiteSalesRank(sdk_models.WebsiteSalesRank):
336336
class ApiBrowseNodeInfo(sdk_models.BrowseNodeInfo):
337337
"""Browse node information container."""
338338

339-
browse_nodes: List[ApiBrowseNode]
339+
browse_nodes: list[ApiBrowseNode]
340340
website_sales_rank: ApiWebsiteSalesRank
341341

342342

@@ -353,4 +353,4 @@ class Item(sdk_models.Item):
353353
parent_asin: str
354354
rental_offers: sdk_models.RentalOffers
355355
score: float
356-
variation_attributes: List[sdk_models.VariationAttribute]
356+
variation_attributes: list[sdk_models.VariationAttribute]

amazon_paapi/models/regions.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
from __future__ import annotations
44

5-
from typing import Literal
5+
import sys
6+
7+
if sys.version_info >= (3, 8):
8+
from typing import Literal
9+
else:
10+
from typing_extensions import Literal
611

7-
# Type alias for valid country codes
812
CountryCode = Literal[
913
"AU",
1014
"BE",
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
"""Search result model for Amazon Product Advertising API."""
22

3-
from typing import List
3+
from __future__ import annotations
4+
5+
from typing import TYPE_CHECKING
46

57
from amazon_paapi.sdk import models as sdk_models
68

7-
from .item_result import Item
9+
if TYPE_CHECKING:
10+
from .item_result import Item
811

912

1013
class SearchResult(sdk_models.SearchResult):
1114
"""Represent the result of a search operation."""
1215

13-
items: List[Item]
16+
items: list[Item]
1417
total_result_count: int
1518
search_url: str

0 commit comments

Comments
 (0)