amazon-orders 5.2.0__tar.gz → 5.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/CHANGELOG.md +11 -1
  2. {amazon_orders-5.2.0/amazon_orders.egg-info → amazon_orders-5.2.1}/PKG-INFO +1 -1
  3. {amazon_orders-5.2.0 → amazon_orders-5.2.1/amazon_orders.egg-info}/PKG-INFO +1 -1
  4. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/__init__.py +2 -1
  5. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/order.py +4 -0
  6. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/parsable.py +29 -10
  7. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/LICENSE +0 -0
  8. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/MANIFEST.in +0 -0
  9. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/README.md +0 -0
  10. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/SOURCES.txt +0 -0
  11. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/dependency_links.txt +0 -0
  12. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/entry_points.txt +0 -0
  13. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/requires.txt +0 -0
  14. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazon_orders.egg-info/top_level.txt +0 -0
  15. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/banner.txt +0 -0
  16. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/cli.py +0 -0
  17. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/conf.py +0 -0
  18. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/constants.py +0 -0
  19. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/__init__.py +0 -0
  20. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/browser/__init__.py +0 -0
  21. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/browser/playwright.py +0 -0
  22. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/__init__.py +0 -0
  23. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/anticaptcha.py +0 -0
  24. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/base.py +0 -0
  25. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/capsolver.py +0 -0
  26. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/contrib/waf/twocaptcha.py +0 -0
  27. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/__init__.py +0 -0
  28. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/family_member.py +0 -0
  29. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/gift_card_activity.py +0 -0
  30. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/invoice.py +0 -0
  31. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/item.py +0 -0
  32. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/order_search_result.py +0 -0
  33. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/prime_payment.py +0 -0
  34. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/recipient.py +0 -0
  35. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/seller.py +0 -0
  36. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/shipment.py +0 -0
  37. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/tracking.py +0 -0
  38. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/entity/transaction.py +0 -0
  39. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/exception.py +0 -0
  40. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/forms.py +0 -0
  41. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/gift_cards.py +0 -0
  42. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/orders.py +0 -0
  43. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/output.py +0 -0
  44. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/paging.py +0 -0
  45. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/prime.py +0 -0
  46. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/py.typed +0 -0
  47. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/region_data.py +0 -0
  48. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/selectors.py +0 -0
  49. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/session.py +0 -0
  50. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/transactions.py +0 -0
  51. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/amazonorders/util.py +0 -0
  52. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/pyproject.toml +0 -0
  53. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/setup.cfg +0 -0
  54. {amazon_orders-5.2.0 → amazon_orders-5.2.1}/tests/testcase.py +0 -0
@@ -4,7 +4,17 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [Unreleased](https://github.com/alexdlaird/amazon-orders/compare/5.2.0...HEAD)
7
+ ## [Unreleased](https://github.com/alexdlaird/amazon-orders/compare/5.2.1...HEAD)
8
+
9
+ ## [5.2.1](https://github.com/alexdlaird/amazon-orders/compare/5.2.0...5.2.1) - 2026-10-31
10
+
11
+ ### Added
12
+
13
+ - `parse_failures` on every entity, the fields that failed to parse and were left `None`, to tell them apart from fields that are `None` by design.
14
+
15
+ ### Changed
16
+
17
+ - `safe_simple_parse()`'s warning names the selector that failed, instead of `simple_parse`.
8
18
 
9
19
  ## [5.2.0](https://github.com/alexdlaird/amazon-orders/compare/5.1.0...5.2.0) - 2026-10-25
10
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amazon-orders
3
- Version: 5.2.0
3
+ Version: 5.2.1
4
4
  Summary: A Python library (and CLI) for Amazon order history, line items, and transactions
5
5
  Author-email: Alex Laird <contact@alexlaird.com>
6
6
  Maintainer-email: Alex Laird <contact@alexlaird.com>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amazon-orders
3
- Version: 5.2.0
3
+ Version: 5.2.1
4
4
  Summary: A Python library (and CLI) for Amazon order history, line items, and transactions
5
5
  Author-email: Alex Laird <contact@alexlaird.com>
6
6
  Maintainer-email: Alex Laird <contact@alexlaird.com>
@@ -1,3 +1,4 @@
1
1
  __copyright__ = "Copyright (c) 2024-2025 Alex Laird"
2
2
  __license__ = "MIT"
3
- __version__ = "5.2.0"
3
+ __version__ = "5.2.1"
4
+ __muppets__ = 42
@@ -38,6 +38,10 @@ class Order(Parsable):
38
38
  order_number: Optional[str] = None) -> None:
39
39
  super().__init__(parsed, config)
40
40
 
41
+ if clone:
42
+ # Fields copied from the clone keep its failures; fields parsed again here clear their own
43
+ self.parse_failures = list(clone.parse_failures)
44
+
41
45
  #: If the Orders full details were populated from its details page.
42
46
  self.full_details: bool = full_details
43
47
 
@@ -3,7 +3,7 @@ __license__ = "MIT"
3
3
 
4
4
  import logging
5
5
  from datetime import date
6
- from typing import Any, Callable, Dict, Optional, Type, Union
6
+ from typing import Any, Callable, Dict, List, Optional, Type, Union
7
7
 
8
8
  from bs4 import Tag
9
9
 
@@ -14,6 +14,17 @@ from amazonorders.exception import AmazonOrdersEntityError, AmazonOrdersError
14
14
  logger = logging.getLogger(__name__)
15
15
 
16
16
 
17
+ def _field_name(parse_function: Callable[..., Any],
18
+ kwargs: Dict[str, Any]) -> str:
19
+ """
20
+ The name a field's parse failure is logged and recorded under: the field, or for ``simple_parse`` its selector.
21
+ """
22
+ if parse_function.__name__ != "simple_parse":
23
+ return parse_function.__name__.split("_parse_")[1]
24
+ selector = kwargs.get("selector", "")
25
+ return selector if isinstance(selector, str) else ", ".join(selector)
26
+
27
+
17
28
  class Parsable:
18
29
  """
19
30
  A base class that contains a parsed representation of the entity, which can be extended to build an entity that
@@ -27,6 +38,9 @@ class Parsable:
27
38
  self.parsed: Tag = parsed
28
39
  #: The config to use.
29
40
  self.config: AmazonOrdersConfig = config
41
+ #: The fields :func:`safe_parse` could not parse and left ``None`` (the selector, for
42
+ #: :func:`safe_simple_parse`), so a failed field can be told apart from one that is ``None`` by design.
43
+ self.parse_failures: List[str] = []
30
44
 
31
45
  def __getstate__(self) -> Dict:
32
46
  state = self.__dict__.copy()
@@ -38,7 +52,7 @@ class Parsable:
38
52
  """
39
53
  Serialize the entity to a ``dict`` of primitives, suitable for JSON, YAML, or CSV output.
40
54
  Nested entities and lists of them are converted recursively, dates become ISO 8601 strings,
41
- and the parsed ``Tag`` and the config are omitted.
55
+ and the parsed ``Tag``, the config, and ``parse_failures`` are omitted.
42
56
 
43
57
  :param exclude_none: Leave out fields whose value is ``None``, in nested entities too. Only ``None`` is left
44
58
  out: ``False``, ``0``, and empty lists are values.
@@ -46,7 +60,7 @@ class Parsable:
46
60
  """
47
61
  serialized: Dict[str, Any] = {}
48
62
  for field, value in vars(self).items():
49
- if field in ["parsed", "config"] or (exclude_none and value is None):
63
+ if field in ["parsed", "config", "parse_failures"] or (exclude_none and value is None):
50
64
  continue
51
65
 
52
66
  if isinstance(value, Parsable):
@@ -66,7 +80,8 @@ class Parsable:
66
80
  **kwargs: Any) -> Any:
67
81
  """
68
82
  Execute the given parse function on a field, handling any common parse exceptions and passing
69
- them as warnings to the logger (suppressing them as exceptions).
83
+ them as warnings to the logger (suppressing them as exceptions). A field that fails is listed in
84
+ :attr:`parse_failures` until it parses.
70
85
 
71
86
  :param parse_function: The parse function to attempt safe execution.
72
87
  :param kwargs: The ``kwargs`` will be passed to ``parse_function``.
@@ -76,19 +91,23 @@ class Parsable:
76
91
  raise AmazonOrdersError("The name of the \"parse_function\" passed to this method must start with "
77
92
  "\"_parse_\".")
78
93
 
94
+ field = _field_name(parse_function, kwargs)
79
95
  try:
80
- return parse_function(**kwargs)
96
+ value = parse_function(**kwargs)
81
97
  except (AttributeError, IndexError, ValueError, TypeError, RecursionError):
82
- function = "simple_parse"
83
- if parse_function.__name__ != function:
84
- function = parse_function.__name__.split("_parse_")[1]
85
98
  logger.warning(
86
- "When building {name}, `{function}` "
99
+ "When building {name}, `{field}` "
87
100
  "could not be parsed.".format(name=self.__class__.__name__,
88
- function=function),
101
+ field=field),
89
102
  exc_info=True)
103
+ if field not in self.parse_failures:
104
+ self.parse_failures.append(field)
90
105
  return None
91
106
 
107
+ if field in self.parse_failures:
108
+ self.parse_failures.remove(field)
109
+ return value
110
+
92
111
  def simple_parse(self,
93
112
  selector: Union[str, list],
94
113
  attr_name: Optional[str] = None,
File without changes
File without changes
File without changes
File without changes