assertpy2 2.3.4__tar.gz → 2.3.5__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 (82) hide show
  1. {assertpy2-2.3.4 → assertpy2-2.3.5}/PKG-INFO +11 -2
  2. {assertpy2-2.3.4 → assertpy2-2.3.5}/README.md +10 -1
  3. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/assertpy.py +1 -4
  4. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/collection.py +0 -2
  5. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/exception.py +0 -1
  6. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/helpers.py +0 -6
  7. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/matchers.py +6 -6
  8. {assertpy2-2.3.4 → assertpy2-2.3.5}/docs/api.md +32 -0
  9. {assertpy2-2.3.4 → assertpy2-2.3.5}/pyproject.toml +2 -2
  10. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_matchers.py +67 -0
  11. {assertpy2-2.3.4 → assertpy2-2.3.5}/uv.lock +1 -1
  12. {assertpy2-2.3.4 → assertpy2-2.3.5}/.codecov.yml +0 -0
  13. {assertpy2-2.3.4 → assertpy2-2.3.5}/.github/dependabot.yml +0 -0
  14. {assertpy2-2.3.4 → assertpy2-2.3.5}/.github/workflows/ci.yml +0 -0
  15. {assertpy2-2.3.4 → assertpy2-2.3.5}/.github/workflows/codeql.yml +0 -0
  16. {assertpy2-2.3.4 → assertpy2-2.3.5}/.github/workflows/publish.yml +0 -0
  17. {assertpy2-2.3.4 → assertpy2-2.3.5}/.github/workflows/scorecard.yml +0 -0
  18. {assertpy2-2.3.4 → assertpy2-2.3.5}/.gitignore +0 -0
  19. {assertpy2-2.3.4 → assertpy2-2.3.5}/CONTRIBUTING.md +0 -0
  20. {assertpy2-2.3.4 → assertpy2-2.3.5}/LICENSE +0 -0
  21. {assertpy2-2.3.4 → assertpy2-2.3.5}/SECURITY.md +0 -0
  22. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/__init__.py +0 -0
  23. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/_mixin_base.py +0 -0
  24. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/_typing.py +0 -0
  25. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/async_assertions.py +0 -0
  26. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/base.py +0 -0
  27. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/behave_matchers.py +0 -0
  28. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/contains.py +0 -0
  29. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/date.py +0 -0
  30. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/dict.py +0 -0
  31. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/dynamic.py +0 -0
  32. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/errors.py +0 -0
  33. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/extracting.py +0 -0
  34. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/file.py +0 -0
  35. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/numeric.py +0 -0
  36. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/py.typed +0 -0
  37. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/pytest_plugin.py +0 -0
  38. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/snapshot.py +0 -0
  39. {assertpy2-2.3.4 → assertpy2-2.3.5}/assertpy2/string.py +0 -0
  40. {assertpy2-2.3.4 → assertpy2-2.3.5}/docs/logo-dark.svg +0 -0
  41. {assertpy2-2.3.4 → assertpy2-2.3.5}/docs/logo.svg +0 -0
  42. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_async.py +0 -0
  43. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_behave_matchers.py +0 -0
  44. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_bool.py +0 -0
  45. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_class.py +0 -0
  46. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_collection.py +0 -0
  47. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_core.py +0 -0
  48. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_custom_dict.py +0 -0
  49. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_custom_list.py +0 -0
  50. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_datetime.py +0 -0
  51. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_description.py +0 -0
  52. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_dict.py +0 -0
  53. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_dict_compare.py +0 -0
  54. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_dyn.py +0 -0
  55. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_equals.py +0 -0
  56. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_errors.py +0 -0
  57. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_expected_exception.py +0 -0
  58. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_extensions.py +0 -0
  59. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_extracting.py +0 -0
  60. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_fail.py +0 -0
  61. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_file.py +0 -0
  62. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_in.py +0 -0
  63. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_list.py +0 -0
  64. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_matcher_registry.py +0 -0
  65. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_matchers_phase3.py +0 -0
  66. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_namedtuple.py +0 -0
  67. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_none.py +0 -0
  68. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_numbers.py +0 -0
  69. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_overloads.py +0 -0
  70. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_phase2.py +0 -0
  71. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_pytest_plugin.py +0 -0
  72. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_readme.py +0 -0
  73. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_regex_groups.py +0 -0
  74. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_same_as.py +0 -0
  75. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_snapshots.py +0 -0
  76. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_soft.py +0 -0
  77. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_soft_fail.py +0 -0
  78. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_string.py +0 -0
  79. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_structural.py +0 -0
  80. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_traceback.py +0 -0
  81. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_type.py +0 -0
  82. {assertpy2-2.3.4 → assertpy2-2.3.5}/tests/test_warn.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assertpy2
3
- Version: 2.3.4
3
+ Version: 2.3.5
4
4
  Summary: Fluent assertion library for Python with composable matchers, structural matching, and full type safety
5
5
  Project-URL: Homepage, https://github.com/Solganis/assertpy2
6
6
  Project-URL: Repository, https://github.com/Solganis/assertpy2
@@ -160,7 +160,7 @@ assert_that(items).is_type_of(list).is_length(3).contains("admin")
160
160
 
161
161
  ## Features
162
162
 
163
- - [**Composable matchers**](docs/api.md#composable-matchers): `match.greater_than(5)`, `match.is_uuid()`, combine with `&`, `|`, `~` operators.
163
+ - [**Composable matchers**](docs/api.md#composable-matchers): `match.greater_than(5)`, `match.is_uuid()`, combine with `&`, `|`, `~`. Also work with plain `assert ==`.
164
164
  - [**Structural matching**](docs/api.md#structural-matching): `matches_structure()` for declarative dict/API response validation.
165
165
  - [**Async assertions**](docs/api.md#async-assertions): `eventually()` with polling/retry for async and eventual consistency testing.
166
166
  - [**Structured errors**](docs/api.md#structured-errors): `AssertionFailure` with `.actual`, `.expected`, `.diff` attributes, pytest plugin with rich diff output.
@@ -204,6 +204,15 @@ assert_that("hello").satisfies(~match.equal_to("world"))
204
204
  assert_that(150).satisfies(match.is_negative() | match.greater_than(100))
205
205
  ```
206
206
 
207
+ Matchers also support `==` directly, so you can use them with plain `assert` or mix into dicts and lists:
208
+
209
+ ```py
210
+ from assertpy2 import match
211
+
212
+ assert 42 == match.is_positive()
213
+ assert {"id": 5, "name": "Alice"} == {"id": match.is_positive(), "name": match.is_non_empty_string()}
214
+ ```
215
+
207
216
  Available matchers: `equal_to`, `greater_than`, `greater_than_or_equal_to`, `less_than`, `less_than_or_equal_to`, `between`, `close_to`, `is_none`, `is_not_none`, `is_instance_of`, `has_length`, `is_empty`, `is_not_empty`, `is_positive`, `is_negative`, `is_zero`, `is_even`, `is_odd`, `is_divisible_by`, `is_callable`, `is_in`, `has_property`, `contains_string`, `matches_regex`, `is_uuid`, `is_non_empty_string`, `ignore`, `each_item`, `structure`.
208
217
 
209
218
 
@@ -125,7 +125,7 @@ assert_that(items).is_type_of(list).is_length(3).contains("admin")
125
125
 
126
126
  ## Features
127
127
 
128
- - [**Composable matchers**](docs/api.md#composable-matchers): `match.greater_than(5)`, `match.is_uuid()`, combine with `&`, `|`, `~` operators.
128
+ - [**Composable matchers**](docs/api.md#composable-matchers): `match.greater_than(5)`, `match.is_uuid()`, combine with `&`, `|`, `~`. Also work with plain `assert ==`.
129
129
  - [**Structural matching**](docs/api.md#structural-matching): `matches_structure()` for declarative dict/API response validation.
130
130
  - [**Async assertions**](docs/api.md#async-assertions): `eventually()` with polling/retry for async and eventual consistency testing.
131
131
  - [**Structured errors**](docs/api.md#structured-errors): `AssertionFailure` with `.actual`, `.expected`, `.diff` attributes, pytest plugin with rich diff output.
@@ -169,6 +169,15 @@ assert_that("hello").satisfies(~match.equal_to("world"))
169
169
  assert_that(150).satisfies(match.is_negative() | match.greater_than(100))
170
170
  ```
171
171
 
172
+ Matchers also support `==` directly, so you can use them with plain `assert` or mix into dicts and lists:
173
+
174
+ ```py
175
+ from assertpy2 import match
176
+
177
+ assert 42 == match.is_positive()
178
+ assert {"id": 5, "name": "Alice"} == {"id": match.is_positive(), "name": match.is_non_empty_string()}
179
+ ```
180
+
172
181
  Available matchers: `equal_to`, `greater_than`, `greater_than_or_equal_to`, `less_than`, `less_than_or_equal_to`, `between`, `close_to`, `is_none`, `is_not_none`, `is_instance_of`, `has_length`, `is_empty`, `is_not_empty`, `is_positive`, `is_negative`, `is_zero`, `is_even`, `is_odd`, `is_divisible_by`, `is_callable`, `is_in`, `has_property`, `contains_string`, `matches_regex`, `is_uuid`, `is_non_empty_string`, `ignore`, `each_item`, `structure`.
173
182
 
174
183
 
@@ -73,7 +73,7 @@ from .numeric import NumericMixin
73
73
  from .snapshot import SnapshotMixin
74
74
  from .string import StringMixin
75
75
 
76
- __version__ = "2.3.4"
76
+ __version__ = "2.3.5"
77
77
 
78
78
  __tracebackhide__ = True # clean tracebacks via py.test integration
79
79
  contextlib.__tracebackhide__ = True # ty: ignore[unresolved-attribute] # pytest monkey-patch
@@ -397,7 +397,6 @@ def _builder(val, description="", kind=None, expected=None, logger=None):
397
397
  """Internal helper to build a new :class:`AssertionBuilder` instance and glue on any extension methods."""
398
398
  ab = AssertionBuilder(val, description, kind, expected, logger)
399
399
  if _extensions:
400
- # glue extension method onto new builder instance
401
400
  for name, func in _extensions.items():
402
401
  meth = types.MethodType(func, ab)
403
402
  setattr(ab, name, meth)
@@ -410,13 +409,11 @@ class WarningLoggingAdapter(logging.LoggerAdapter):
410
409
 
411
410
  def process(self, msg, kwargs):
412
411
  def _unwind(frame):
413
- # walk all the frames
414
412
  frames = []
415
413
  while frame:
416
414
  frames.append((frame.f_code.co_filename, frame.f_lineno))
417
415
  frame = frame.f_back
418
416
 
419
- # in reverse, find the first assertpy frame (and return the previous one)
420
417
  prev = None
421
418
  for frame in reversed(
422
419
  frames
@@ -118,7 +118,6 @@ class CollectionMixin(_MixinBase):
118
118
 
119
119
  missing = []
120
120
  if hasattr(self.val, "keys") and callable(self.val.keys) and hasattr(self.val, "__getitem__"):
121
- # flatten superset dicts
122
121
  superdict = {}
123
122
  for idx, j in enumerate(supersets):
124
123
  self._check_dict_like(j, check_values=False, name=f"arg #{idx + 1}")
@@ -136,7 +135,6 @@ class CollectionMixin(_MixinBase):
136
135
  f"but {self._fmt_items(missing)} {'was' if len(missing) == 1 else 'were'} missing."
137
136
  )
138
137
  else:
139
- # flatten supersets
140
138
  superset = set()
141
139
  for j in supersets:
142
140
  try:
@@ -73,7 +73,6 @@ class ExceptionMixin(_MixinBase):
73
73
  if not issubclass(ex, BaseException):
74
74
  raise TypeError("given arg must be exception")
75
75
 
76
- # chain on with ex as the expected exception
77
76
  return self.builder(self.val, self.description, self.kind, ex, self.logger)
78
77
 
79
78
  def when_called_with(self, *some_args, **some_kwargs) -> Self:
@@ -163,7 +163,6 @@ class HelpersMixin(_MixinBase):
163
163
  ignores = self._dict_ignore(ignore)
164
164
  includes = self._dict_include(include)
165
165
 
166
- # guarantee include keys are in val
167
166
  if include:
168
167
  missing = []
169
168
  for i in includes:
@@ -181,7 +180,6 @@ class HelpersMixin(_MixinBase):
181
180
  f" but did not include key{missing_suffix} {missing_fmt}."
182
181
  )
183
182
 
184
- # calc val keys given ignores and includes
185
183
  if ignore and include:
186
184
  k1 = {k for k in val if k not in ignores and k in includes}
187
185
  elif ignore:
@@ -189,7 +187,6 @@ class HelpersMixin(_MixinBase):
189
187
  else: # include
190
188
  k1 = {k for k in val if k in includes}
191
189
 
192
- # calc other keys given ignores and includes
193
190
  if ignore and include:
194
191
  k2 = {k for k in other if k not in ignores and k in includes}
195
192
  elif ignore:
@@ -198,7 +195,6 @@ class HelpersMixin(_MixinBase):
198
195
  k2 = {k for k in other if k in includes}
199
196
 
200
197
  if k1 != k2:
201
- # different set of keys, so not equal
202
198
  return True
203
199
  else:
204
200
  for k in k1:
@@ -214,10 +210,8 @@ class HelpersMixin(_MixinBase):
214
210
  else None,
215
211
  )
216
212
  if subdicts_not_equal:
217
- # fast fail inside the loop since sub-dicts are not equal
218
213
  return True
219
214
  elif val[k] != other[k]:
220
- # fast fail inside the loop since values are not equal
221
215
  return True
222
216
  return False
223
217
  else:
@@ -43,6 +43,12 @@ class BaseMatcher:
43
43
  def __invert__(self) -> NotMatcher:
44
44
  return NotMatcher(self)
45
45
 
46
+ def __eq__(self, other: object) -> bool:
47
+ return self.matches(other)
48
+
49
+ def __hash__(self) -> int:
50
+ return id(self)
51
+
46
52
  def __repr__(self) -> str:
47
53
  return self.describe()
48
54
 
@@ -452,8 +458,6 @@ class EndsWithMatcher(BaseMatcher):
452
458
 
453
459
 
454
460
  class IgnoreMatcher(BaseMatcher):
455
- """Always matches. Used in structure specs to accept any value for a field."""
456
-
457
461
  def matches(self, value: Any) -> bool:
458
462
  return True
459
463
 
@@ -462,8 +466,6 @@ class IgnoreMatcher(BaseMatcher):
462
466
 
463
467
 
464
468
  class IsUuidMatcher(BaseMatcher):
465
- """Matches valid UUID strings."""
466
-
467
469
  def matches(self, value: Any) -> bool:
468
470
  if not isinstance(value, str):
469
471
  return False
@@ -478,8 +480,6 @@ class IsUuidMatcher(BaseMatcher):
478
480
 
479
481
 
480
482
  class IsNonEmptyStringMatcher(BaseMatcher):
481
- """Matches non-empty strings."""
482
-
483
483
  def matches(self, value: Any) -> bool:
484
484
  return isinstance(value, str) and len(value) > 0
485
485
 
@@ -977,6 +977,38 @@ assert_that(50).satisfies(complex_check)
977
977
  assert_that(-1).satisfies(complex_check)
978
978
  ```
979
979
 
980
+ ### Using matchers with `==`
981
+
982
+ Matchers implement `__eq__`, so they work with plain `assert` and pytest introspection. No `assert_that()` wrapper needed:
983
+
984
+ ```py
985
+ from assertpy2 import match
986
+
987
+ # simple value check
988
+ assert 42 == match.is_positive()
989
+ assert "hello" == match.is_non_empty_string()
990
+
991
+ # dict comparison with matchers as expected values
992
+ assert {"id": 5, "name": "Alice"} == {
993
+ "id": match.is_positive(),
994
+ "name": match.is_non_empty_string(),
995
+ }
996
+
997
+ # list comparison
998
+ assert [1, 2, 3] == [match.is_positive(), match.is_positive(), match.is_positive()]
999
+
1000
+ # composition works too
1001
+ assert 42 == (match.is_positive() & match.less_than(100))
1002
+ ```
1003
+
1004
+ On failure, pytest shows the matcher description in the assertion message:
1005
+
1006
+ ```
1007
+ AssertionError: assert -5 == a positive value
1008
+ ```
1009
+
1010
+ This makes matchers a drop-in addition to existing test suites: add one import, use `match.*` in any `==` comparison, no rewrite required.
1011
+
980
1012
  ### Available matchers
981
1013
 
982
1014
  | Matcher | Description |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "assertpy2"
3
- version = "2.3.4"
3
+ version = "2.3.5"
4
4
  description = "Fluent assertion library for Python with composable matchers, structural matching, and full type safety"
5
5
  readme = "README.md"
6
6
  license = "BSD-3-Clause"
@@ -80,4 +80,4 @@ select = ["E", "E301", "F", "I", "UP", "B", "SIM", "RUF"]
80
80
  ignore = ["E501"]
81
81
 
82
82
  [tool.ruff.lint.per-file-ignores]
83
- "tests/*" = ["E741", "SIM102"]
83
+ "tests/*" = ["E741", "SIM102", "SIM300"]
@@ -562,3 +562,70 @@ class TestDescribeCoverage:
562
562
 
563
563
  def test_ends_with_describe(self):
564
564
  assert_that(match.ends_with("bar").describe()).is_equal_to("a string ending with <bar>")
565
+
566
+
567
+ class TestMatcherEqProtocol:
568
+ def test_eq_positive_match(self):
569
+ assert 5 == match.is_positive()
570
+
571
+ def test_eq_negative_match(self):
572
+ assert (-5 == match.is_positive()) is False
573
+
574
+ def test_eq_equal_to(self):
575
+ assert 42 == match.equal_to(42)
576
+
577
+ def test_eq_between(self):
578
+ assert 5 == match.between(1, 10)
579
+
580
+ def test_eq_string_matcher(self):
581
+ assert "hello" == match.is_non_empty_string()
582
+
583
+ def test_eq_not_equal(self):
584
+ assert -5 != match.is_positive()
585
+
586
+ def test_eq_reverse_order(self):
587
+ assert match.is_positive() == 5
588
+
589
+ def test_eq_dict(self):
590
+ assert {"id": 5, "name": "Alice"} == {"id": match.is_positive(), "name": match.is_non_empty_string()}
591
+
592
+ def test_eq_dict_mismatch(self):
593
+ assert {"id": -5} != {"id": match.is_positive()}
594
+
595
+ def test_eq_nested_dict(self):
596
+ data = {"user": {"name": "Alice", "age": 30}}
597
+ assert data == {"user": {"name": match.is_non_empty_string(), "age": match.is_positive()}}
598
+
599
+ def test_eq_list(self):
600
+ assert [1, 2, 3] == [match.is_positive(), match.is_positive(), match.is_positive()]
601
+
602
+ def test_eq_composition_and(self):
603
+ assert 5 == (match.is_positive() & match.less_than(10))
604
+
605
+ def test_eq_composition_or(self):
606
+ assert -1 == (match.is_positive() | match.is_negative())
607
+
608
+ def test_eq_negated_matcher(self):
609
+ assert -5 == ~match.is_positive()
610
+
611
+ def test_hash_unique_instances(self):
612
+ m1 = match.is_positive()
613
+ m2 = match.is_positive()
614
+ s = {m1, m2}
615
+ assert_that(s).is_length(2)
616
+
617
+ def test_hash_same_instance(self):
618
+ m = match.is_positive()
619
+ s = {m, m}
620
+ assert_that(s).is_length(1)
621
+
622
+ def test_repr_unchanged(self):
623
+ assert_that(repr(match.is_positive())).is_equal_to("a positive value")
624
+
625
+ def test_eq_with_pytest_assert_message(self):
626
+ try:
627
+ assert -5 == match.is_positive()
628
+ except AssertionError:
629
+ pass
630
+ else:
631
+ raise AssertionError("Expected AssertionError")
@@ -30,7 +30,7 @@ wheels = [
30
30
 
31
31
  [[package]]
32
32
  name = "assertpy2"
33
- version = "2.3.1"
33
+ version = "2.3.5"
34
34
  source = { editable = "." }
35
35
  dependencies = [
36
36
  { name = "typing-extensions" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes