assertpy2 2.25.0__tar.gz → 2.26.0__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 (243) hide show
  1. {assertpy2-2.25.0 → assertpy2-2.26.0}/CONTRIBUTING.md +10 -7
  2. {assertpy2-2.25.0 → assertpy2-2.26.0}/PKG-INFO +1 -1
  3. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/__init__.py +2 -1
  4. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_builder_check_typing.py +71 -57
  5. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_capable_typing.py +301 -5
  6. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_mixin_base.py +3 -1
  7. assertpy2-2.26.0/assertpy2/_engine/_negated_typing.py +1688 -0
  8. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_poll_typing.py +133 -133
  9. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_typing.py +83 -12
  10. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_matcher_impls.py +9 -10
  11. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/assertpy.py +260 -14
  12. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/async_assertions.py +4 -0
  13. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/dynamic.py +21 -2
  14. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/errors.py +47 -21
  15. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/file.py +3 -3
  16. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/helpers.py +97 -42
  17. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/json_mixin.py +6 -6
  18. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/numeric.py +17 -5
  19. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/outcome.py +46 -1
  20. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/pytest_plugin.py +132 -44
  21. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/snapshot.py +12 -1
  22. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/concepts/stability.md +18 -8
  23. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/extending/integrations.md +22 -8
  24. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/getting-started/migration.md +3 -3
  25. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/guides/assertions.md +1 -1
  26. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/guides/errors.md +57 -9
  27. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/guides/fluent.md +6 -2
  28. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/entry-points.md +6 -0
  29. {assertpy2-2.25.0 → assertpy2-2.26.0}/pyproject.toml +27 -12
  30. {assertpy2-2.25.0 → assertpy2-2.26.0}/scripts/generate_check_protocols.py +1 -0
  31. {assertpy2-2.25.0 → assertpy2-2.26.0}/scripts/generate_poll_protocols.py +330 -20
  32. {assertpy2-2.25.0 → assertpy2-2.26.0}/scripts/regenerate.py +5 -1
  33. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/api_snapshot.json +349 -21
  34. assertpy2-2.26.0/tests/poll_parity_baseline.py +921 -0
  35. assertpy2-2.26.0/tests/poll_parity_cases.py +3331 -0
  36. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/pyright_baseline.py +2 -2
  37. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_architecture_doc.py +4 -9
  38. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_capable_protocol.py +32 -5
  39. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_complexity.py +5 -3
  40. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_dict_compare.py +8 -5
  41. assertpy2-2.26.0/tests/test_docs_examples.py +334 -0
  42. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_equals.py +5 -5
  43. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_extensions.py +91 -0
  44. assertpy2-2.26.0/tests/test_message_elision.py +267 -0
  45. assertpy2-2.26.0/tests/test_negated_protocols.py +406 -0
  46. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_numbers.py +26 -0
  47. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_openapi_contract.py +23 -0
  48. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_pin_coverage.py +20 -0
  49. assertpy2-2.26.0/tests/test_poll_parity.py +378 -0
  50. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_property_based.py +75 -1
  51. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_public_surface.py +10 -2
  52. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_pyright_baseline.py +10 -4
  53. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_pytest_plugin.py +563 -62
  54. assertpy2-2.26.0/tests/test_requirement.py +673 -0
  55. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_rich_diff.py +4 -4
  56. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_snapshots.py +74 -0
  57. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing.py +33 -1
  58. assertpy2-2.26.0/tests/test_typing_promises.py +67 -0
  59. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/typing_cases.py +22 -2
  60. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/typing_harness.py +17 -8
  61. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/typing_negative_baseline.py +31 -12
  62. assertpy2-2.26.0/tests/typing_promises.py +199 -0
  63. assertpy2-2.25.0/tests/test_docs_examples.py +0 -123
  64. assertpy2-2.25.0/tests/test_message_elision.py +0 -117
  65. {assertpy2-2.25.0 → assertpy2-2.26.0}/.gitignore +0 -0
  66. {assertpy2-2.25.0 → assertpy2-2.26.0}/LICENSE +0 -0
  67. {assertpy2-2.25.0 → assertpy2-2.26.0}/README.md +0 -0
  68. {assertpy2-2.25.0 → assertpy2-2.26.0}/SECURITY.md +0 -0
  69. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_clustering.py +0 -0
  70. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_dangling.py +0 -0
  71. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/__init__.py +0 -0
  72. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_check_typing.py +0 -0
  73. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_compare.py +0 -0
  74. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_compat.py +0 -0
  75. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_contract.py +0 -0
  76. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_diff.py +0 -0
  77. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_equality.py +0 -0
  78. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_introspection.py +0 -0
  79. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_membership.py +0 -0
  80. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_operations.py +0 -0
  81. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_ordering.py +0 -0
  82. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_path.py +0 -0
  83. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_require.py +0 -0
  84. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_size.py +0 -0
  85. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_engine/_text.py +0 -0
  86. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_hints.py +0 -0
  87. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_inline.py +0 -0
  88. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_satisfies.py +0 -0
  89. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/_snapshot_codec.py +0 -0
  90. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/base.py +0 -0
  91. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/behave_matchers.py +0 -0
  92. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/bytes_mixin.py +0 -0
  93. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/collection.py +0 -0
  94. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/contains.py +0 -0
  95. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/dataframe.py +0 -0
  96. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/date.py +0 -0
  97. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/dict.py +0 -0
  98. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/exception.py +0 -0
  99. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/extracting.py +0 -0
  100. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/http_mixin.py +0 -0
  101. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/matchers.py +0 -0
  102. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/py.typed +0 -0
  103. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/string.py +0 -0
  104. {assertpy2-2.25.0 → assertpy2-2.26.0}/assertpy2/warning.py +0 -0
  105. {assertpy2-2.25.0 → assertpy2-2.26.0}/benchmarks/test_perf.py +0 -0
  106. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-equal.png +0 -0
  107. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-equal.svg +0 -0
  108. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-gallery.png +0 -0
  109. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-match.svg +0 -0
  110. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-sequence.svg +0 -0
  111. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-set.svg +0 -0
  112. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/assets/diff-string.svg +0 -0
  113. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/concepts/type-safety.md +0 -0
  114. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/extending/custom-assertions.md +0 -0
  115. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/getting-started/comparison.md +0 -0
  116. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/getting-started/quickstart.md +0 -0
  117. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/guides/data.md +0 -0
  118. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/guides/matchers.md +0 -0
  119. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/guides/testing.md +0 -0
  120. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/index.md +0 -0
  121. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/logo-dark.svg +0 -0
  122. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/logo.svg +0 -0
  123. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/recipes.md +0 -0
  124. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/async.md +0 -0
  125. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/bytes.md +0 -0
  126. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/collections.md +0 -0
  127. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/containment.md +0 -0
  128. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/core.md +0 -0
  129. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/dataframes.md +0 -0
  130. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/dates.md +0 -0
  131. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/dicts.md +0 -0
  132. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/dynamic.md +0 -0
  133. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/errors.md +0 -0
  134. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/exceptions.md +0 -0
  135. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/extracting.md +0 -0
  136. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/files.md +0 -0
  137. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/http.md +0 -0
  138. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/json.md +0 -0
  139. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/matchers.md +0 -0
  140. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/numbers.md +0 -0
  141. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/overview.md +0 -0
  142. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/snapshots.md +0 -0
  143. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/strings.md +0 -0
  144. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/reference/warnings.md +0 -0
  145. {assertpy2-2.25.0 → assertpy2-2.26.0}/docs/stylesheets/extra.css +0 -0
  146. {assertpy2-2.25.0 → assertpy2-2.26.0}/mkdocs.yml +0 -0
  147. {assertpy2-2.25.0 → assertpy2-2.26.0}/mkdocs_hooks.py +0 -0
  148. {assertpy2-2.25.0 → assertpy2-2.26.0}/scripts/mutation_report.py +0 -0
  149. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/api_surface.py +0 -0
  150. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/conftest.py +0 -0
  151. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/docs_fixtures.py +0 -0
  152. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/group_compat.py +0 -0
  153. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_api_compatibility.py +0 -0
  154. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_api_vocabulary.py +0 -0
  155. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_async.py +0 -0
  156. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_async_predicates.py +0 -0
  157. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_attrs_support.py +0 -0
  158. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_behave_matchers.py +0 -0
  159. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_bool.py +0 -0
  160. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_boundary_cases.py +0 -0
  161. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_bytes.py +0 -0
  162. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_callable.py +0 -0
  163. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_chaining.py +0 -0
  164. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_check.py +0 -0
  165. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_check_protocols.py +0 -0
  166. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_class.py +0 -0
  167. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_clustering.py +0 -0
  168. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_collection.py +0 -0
  169. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_core.py +0 -0
  170. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_custom_dict.py +0 -0
  171. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_custom_list.py +0 -0
  172. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_dangling.py +0 -0
  173. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_dataframe.py +0 -0
  174. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_datetime.py +0 -0
  175. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_declared_floors.py +0 -0
  176. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_description.py +0 -0
  177. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_dict.py +0 -0
  178. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_docs_typing.py +0 -0
  179. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_dynamic.py +0 -0
  180. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_errors.py +0 -0
  181. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_evaluation_core.py +0 -0
  182. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_exception_context.py +0 -0
  183. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_expected_contract.py +0 -0
  184. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_expected_exception.py +0 -0
  185. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_expected_warning.py +0 -0
  186. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_extracting.py +0 -0
  187. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_fail.py +0 -0
  188. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_file.py +0 -0
  189. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_grouped_soft.py +0 -0
  190. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_hints.py +0 -0
  191. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_http.py +0 -0
  192. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_in.py +0 -0
  193. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_inline_record.py +0 -0
  194. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_inline_snapshot.py +0 -0
  195. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_iterable_cluster.py +0 -0
  196. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_json.py +0 -0
  197. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_list.py +0 -0
  198. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_match_result.py +0 -0
  199. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_matcher_parity.py +0 -0
  200. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_matcher_registry.py +0 -0
  201. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_matchers.py +0 -0
  202. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_namedtuple.py +0 -0
  203. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_none.py +0 -0
  204. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_not.py +0 -0
  205. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_operation_contract.py +0 -0
  206. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_optional_integration_contracts.py +0 -0
  207. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_overload_order.py +0 -0
  208. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_overloads.py +0 -0
  209. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_pipeline.py +0 -0
  210. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_poll_protocols.py +0 -0
  211. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_property_attrs.py +0 -0
  212. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_protocol_parity.py +0 -0
  213. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_recursive_assertion.py +0 -0
  214. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_recursive_compare.py +0 -0
  215. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_recursive_compare_attrs.py +0 -0
  216. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_recursive_compare_config.py +0 -0
  217. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_recursive_compare_pydantic.py +0 -0
  218. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_refusals.py +0 -0
  219. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_regex_groups.py +0 -0
  220. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_same_as.py +0 -0
  221. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_satisfy.py +0 -0
  222. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_skip_guard.py +0 -0
  223. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_soft.py +0 -0
  224. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_soft_fail.py +0 -0
  225. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_string.py +0 -0
  226. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_structural.py +0 -0
  227. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_surface_conformance.py +0 -0
  228. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_sync_eventually.py +0 -0
  229. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_traceback.py +0 -0
  230. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_type.py +0 -0
  231. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_type_expression_failures.py +0 -0
  232. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_claims.py +0 -0
  233. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_completeness.py +0 -0
  234. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_conformance.py +0 -0
  235. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_from_a_wheel.py +0 -0
  236. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_http.py +0 -0
  237. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_integrations.py +0 -0
  238. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_typing_negative.py +0 -0
  239. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_vacuity_contract.py +0 -0
  240. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/test_warn.py +0 -0
  241. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/typing_http.py +0 -0
  242. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/typing_integrations.py +0 -0
  243. {assertpy2-2.25.0 → assertpy2-2.26.0}/tests/typing_integrations_baseline.py +0 -0
@@ -25,7 +25,7 @@ Read more about how pulls work on GitHub's [About pull requests](https://help.gi
25
25
 
26
26
  ## Before you change a public signature
27
27
 
28
- Read [ARCHITECTURE.md](ARCHITECTURE.md). Four files under `assertpy2/_engine/` are generated, the public
28
+ Read [ARCHITECTURE.md](ARCHITECTURE.md). Five files under `assertpy2/_engine/` are generated, the public
29
29
  surface is pinned by a recorded snapshot, and neither is discoverable from the files themselves.
30
30
 
31
31
  ## Verification pipeline
@@ -86,15 +86,16 @@ Run these after the main gate, not before. `uv run --group typecheck` adds the c
86
86
 
87
87
  ```bash
88
88
  uv run --group typecheck mypy --strict --follow-imports=silent tests/test_typing.py
89
- PYRIGHT_PYTHON_FORCE_VERSION=1.1.413 uv run --group typecheck pyright --pythonversion 3.14 tests/test_typing.py
89
+ PYRIGHT_PYTHON_FORCE_VERSION=1.1.414 uv run --group typecheck pyright --pythonversion 3.14 tests/test_typing.py
90
90
  uv run --group typecheck pyrefly check tests/test_typing.py
91
91
  uv run --group typecheck pytest tests/test_pyright_baseline.py
92
92
  ```
93
93
 
94
94
  `PYRIGHT_PYTHON_FORCE_VERSION` picks the engine rather than the launcher. The `pyright` distribution on
95
- PyPI stopped at 1.1.411 on 25 June while npm has shipped 1.1.412 and 1.1.413 since, so the launcher and
96
- the engine move apart. The baseline is recorded against one engine, and `tests/typing_harness.py` pins
97
- the same build, so only this direct invocation needs the variable.
95
+ PyPI is released separately from the npm engine it launches, and the two have drifted apart before: PyPI
96
+ stayed at 1.1.411 from June to September while npm shipped two builds. The baseline is recorded against
97
+ one engine, and `tests/typing_harness.py` pins the same build, so only this direct invocation needs the
98
+ variable.
98
99
 
99
100
  `--pythonversion 3.14` is not decoration. Pyright reports against the interpreter it finds unless
100
101
  told otherwise, and the count moves with it: 174 diagnostics for this package on 3.10 against 169 on
@@ -123,9 +124,11 @@ Write tests for every new feature or bug fix. Use `assertpy2` assertions in test
123
124
 
124
125
  ## Documentation examples
125
126
 
126
- Guide code blocks are executed and type-checked in CI, so an example you add has to run. A block that
127
+ Guide code blocks are type-checked in CI, and every page that can run in the suite is executed, with what
128
+ each block prints compared with the comment beside it, so an example you add has to run. A block that
127
129
  cannot (pseudo-context, a deliberate failure, a rejected counter-example) is marked with an HTML comment
128
- above the fence: `tests/test_docs_examples.py` lists the markers and what each one exempts.
130
+ above the fence. `tests/test_docs_examples.py` lists the markers and what each one exempts, and it and
131
+ `tests/test_docs_typing.py` each name the pages they leave out, with the reason.
129
132
 
130
133
  Setup a page assumes (a domain class, a repository, an HTTP response) goes in
131
134
  `tests/docs_fixtures.py`, not into an extra block on the page.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: assertpy2
3
- Version: 2.25.0
3
+ Version: 2.26.0
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
@@ -35,7 +35,7 @@ from .matchers import (
35
35
  register_matcher,
36
36
  unregister_matcher,
37
37
  )
38
- from .outcome import AssertionOutcome
38
+ from .outcome import AssertionOutcome, Requirement
39
39
  from .snapshot import (
40
40
  SnapshotCreatedWarning,
41
41
  SnapshotKeyReusedWarning,
@@ -57,6 +57,7 @@ __all__ = [
57
57
  "NegatedBuilder",
58
58
  "PollSample",
59
59
  "PollTrace",
60
+ "Requirement",
60
61
  "SnapshotCreatedWarning",
61
62
  "SnapshotKeyReusedWarning",
62
63
  "SnapshotUpdatedWarning",
@@ -26,7 +26,15 @@ if TYPE_CHECKING:
26
26
  from .._matcher_impls import ClassInfo
27
27
  from ..matchers import Matcher
28
28
  from ..outcome import AssertionOutcome
29
- from ._capable_typing import _Callable, _Keyed, _KeyedWithItems, _KeyedWithValues, _Orderable, _PathLike
29
+ from ._capable_typing import (
30
+ _Callable,
31
+ _Indexed,
32
+ _Keyed,
33
+ _KeyedWithItems,
34
+ _KeyedWithValues,
35
+ _Orderable,
36
+ _PathLike,
37
+ )
30
38
  from ._introspection import MappingLike
31
39
  from ._typing import (
32
40
  _U,
@@ -551,6 +559,53 @@ if TYPE_CHECKING:
551
559
 
552
560
  def matches_with_groups(self: _CheckAnyValue[str], pattern: str) -> AssertionOutcome: ...
553
561
 
562
+ @overload
563
+ def exists(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
564
+ @overload
565
+ def exists(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
566
+
567
+ @overload
568
+ def does_not_exist(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
569
+ @overload
570
+ def does_not_exist(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
571
+
572
+ @overload
573
+ def is_file(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
574
+ @overload
575
+ def is_file(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
576
+
577
+ @overload
578
+ def is_directory(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
579
+ @overload
580
+ def is_directory(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
581
+
582
+ @overload
583
+ def is_named(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path], filename: str) -> AssertionOutcome: ...
584
+ @overload
585
+ def is_named(self: _CheckAnyValue[_PathLike], filename: str) -> AssertionOutcome: ...
586
+
587
+ @overload
588
+ def is_child_of(
589
+ self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path], parent: object
590
+ ) -> AssertionOutcome: ...
591
+ @overload
592
+ def is_child_of(self: _CheckAnyValue[_PathLike], parent: object) -> AssertionOutcome: ...
593
+
594
+ @overload
595
+ def is_readable(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
596
+ @overload
597
+ def is_readable(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
598
+
599
+ @overload
600
+ def is_writable(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
601
+ @overload
602
+ def is_writable(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
603
+
604
+ @overload
605
+ def is_executable(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
606
+ @overload
607
+ def is_executable(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
608
+
554
609
  @overload
555
610
  def is_subset_of(
556
611
  self: _CheckAnyValue[str]
@@ -574,10 +629,11 @@ if TYPE_CHECKING:
574
629
  self: _CheckAnyValue[_CapableT], *supersets: object, allow_empty: bool = ...
575
630
  ) -> AssertionOutcome: ...
576
631
 
632
+ @overload
633
+ def contains_duplicates(self: _CheckAnyValue[str]) -> AssertionOutcome: ...
577
634
  @overload
578
635
  def contains_duplicates(
579
- self: _CheckAnyValue[str]
580
- | _CheckAnyValue[list[_E]]
636
+ self: _CheckAnyValue[list[_E]]
581
637
  | _CheckAnyValue[tuple[_E, ...]]
582
638
  | _CheckAnyValue[set[_E]]
583
639
  | _CheckAnyValue[frozenset[_E]],
@@ -585,10 +641,11 @@ if TYPE_CHECKING:
585
641
  @overload
586
642
  def contains_duplicates(self: _CheckAnyValue[_CapableT]) -> AssertionOutcome: ...
587
643
 
644
+ @overload
645
+ def does_not_contain_duplicates(self: _CheckAnyValue[str]) -> AssertionOutcome: ...
588
646
  @overload
589
647
  def does_not_contain_duplicates(
590
- self: _CheckAnyValue[str]
591
- | _CheckAnyValue[list[_E]]
648
+ self: _CheckAnyValue[list[_E]]
592
649
  | _CheckAnyValue[tuple[_E, ...]]
593
650
  | _CheckAnyValue[set[_E]]
594
651
  | _CheckAnyValue[frozenset[_E]],
@@ -596,10 +653,11 @@ if TYPE_CHECKING:
596
653
  @overload
597
654
  def does_not_contain_duplicates(self: _CheckAnyValue[_CapableT]) -> AssertionOutcome: ...
598
655
 
656
+ @overload
657
+ def contains_only_once(self: _CheckAnyValue[str], *items: object) -> AssertionOutcome: ...
599
658
  @overload
600
659
  def contains_only_once(
601
- self: _CheckAnyValue[str]
602
- | _CheckAnyValue[list[_E]]
660
+ self: _CheckAnyValue[list[_E]]
603
661
  | _CheckAnyValue[tuple[_E, ...]]
604
662
  | _CheckAnyValue[set[_E]]
605
663
  | _CheckAnyValue[frozenset[_E]],
@@ -608,17 +666,20 @@ if TYPE_CHECKING:
608
666
  @overload
609
667
  def contains_only_once(self: _CheckAnyValue[_CapableT], *items: object) -> AssertionOutcome: ...
610
668
 
669
+ @overload
670
+ def contains_in_order(self: _CheckAnyValue[str], *items: str | Matcher[str]) -> AssertionOutcome: ...
611
671
  @overload
612
672
  def contains_in_order(
613
- self: _CheckAnyValue[str]
614
- | _CheckAnyValue[list[_E]]
673
+ self: _CheckAnyValue[list[_E]]
615
674
  | _CheckAnyValue[tuple[_E, ...]]
616
675
  | _CheckAnyValue[set[_E]]
617
676
  | _CheckAnyValue[frozenset[_E]],
618
677
  *items: _E | Matcher[_E],
619
678
  ) -> AssertionOutcome: ...
620
679
  @overload
621
- def contains_in_order(self: _CheckAnyValue[_CapableT], *items: _E | Matcher[_E]) -> AssertionOutcome: ...
680
+ def contains_in_order(
681
+ self: _CheckAnyValue[Iterable[_E] | _Indexed[_E]], *items: _E | Matcher[_E]
682
+ ) -> AssertionOutcome: ...
622
683
 
623
684
  @overload
624
685
  def has_same_size_as(
@@ -721,53 +782,6 @@ if TYPE_CHECKING:
721
782
  @overload
722
783
  def is_not_empty(self: _CheckAnyValue[_CapableT]) -> AssertionOutcome: ...
723
784
 
724
- @overload
725
- def exists(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
726
- @overload
727
- def exists(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
728
-
729
- @overload
730
- def does_not_exist(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
731
- @overload
732
- def does_not_exist(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
733
-
734
- @overload
735
- def is_file(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
736
- @overload
737
- def is_file(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
738
-
739
- @overload
740
- def is_directory(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
741
- @overload
742
- def is_directory(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
743
-
744
- @overload
745
- def is_named(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path], filename: str) -> AssertionOutcome: ...
746
- @overload
747
- def is_named(self: _CheckAnyValue[_PathLike], filename: str) -> AssertionOutcome: ...
748
-
749
- @overload
750
- def is_child_of(
751
- self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path], parent: object
752
- ) -> AssertionOutcome: ...
753
- @overload
754
- def is_child_of(self: _CheckAnyValue[_PathLike], parent: object) -> AssertionOutcome: ...
755
-
756
- @overload
757
- def is_readable(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
758
- @overload
759
- def is_readable(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
760
-
761
- @overload
762
- def is_writable(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
763
- @overload
764
- def is_writable(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
765
-
766
- @overload
767
- def is_executable(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
768
- @overload
769
- def is_executable(self: _CheckAnyValue[_PathLike]) -> AssertionOutcome: ...
770
-
771
785
  @overload
772
786
  def is_positive(
773
787
  self: _CheckAnyValue[bool] | _CheckAnyValue[int] | _CheckAnyValue[float],
@@ -24,7 +24,7 @@ from typing import TYPE_CHECKING
24
24
  if TYPE_CHECKING:
25
25
  import datetime
26
26
  import logging
27
- from collections.abc import Callable, Collection, Iterable, Mapping, Sized
27
+ from collections.abc import Callable, Iterable, Mapping, Sized
28
28
  from pathlib import Path
29
29
  from typing import Any, Protocol, SupportsFloat, SupportsIndex, TypeVar, overload
30
30
 
@@ -49,6 +49,21 @@ if TYPE_CHECKING:
49
49
 
50
50
  def __lt__(self, other: Any, /) -> Any: ...
51
51
 
52
+ class _Indexed(Protocol[_E_co]):
53
+ """The older way to be a sequence: integer lookup that stops with `IndexError`, and no `__iter__`.
54
+
55
+ `list(value)` accepts it, so `contains_in_order()` runs on it, and asking only for `Iterable`
56
+ refused a value that works.
57
+
58
+ One shape gets through that the runtime refuses, and it cannot be spelled out of: a class with
59
+ this lookup and ``__iter__ = None`` disables the fallback, so `list(value)` raises while this
60
+ still matches. Structural typing has no way to ask for the absence of a member, and the
61
+ direction is the safe one: the call is accepted here and refused with "val must be iterable"
62
+ when it runs, which is what every other umbrella rung already does.
63
+ """
64
+
65
+ def __getitem__(self, index: int, /) -> _E_co: ...
66
+
52
67
  class _Keyed(Protocol):
53
68
  """`keys()`, which the dict gate reads before anything else.
54
69
 
@@ -82,10 +97,14 @@ if TYPE_CHECKING:
82
97
  def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
83
98
 
84
99
  class _ElementSource(Protocol[_E_co]):
85
- """Anything whose value is a collection of `_E_co`, spelled the way the builder spells it."""
100
+ """Anything whose value can be walked for `_E_co`, spelled the way the builder spells it.
101
+
102
+ `Iterable` and not `Collection`: a value with only `__iter__` fell through to the `Self` overload,
103
+ so `first()` kept the container's type after the value had become an element.
104
+ """
86
105
 
87
106
  @property
88
- def value(self) -> Collection[_E_co]: ...
107
+ def value(self) -> Iterable[_E_co]: ...
89
108
 
90
109
  class _CapableAssertion(Protocol[_CapableT_co]):
91
110
  """What a value the umbrella claims can be asked."""
@@ -100,7 +119,7 @@ if TYPE_CHECKING:
100
119
  @property
101
120
  def value(self) -> _CapableT_co: ...
102
121
  @property
103
- def not_(self) -> Self: ...
122
+ def not_(self) -> _NegatedCapableAssertion[_CapableT_co]: ...
104
123
  def __getattr__(self, name: str) -> Callable[..., Self]: ...
105
124
 
106
125
  # the builder's ladders, carried across: a narrowing lost here is lost for every value the umbrella claims
@@ -225,7 +244,9 @@ if TYPE_CHECKING:
225
244
  def contains_exactly(self, *items: object) -> Self: ...
226
245
  def contains_exactly_in_any_order(self, *items: object) -> Self: ...
227
246
  def contains_ignoring_case(self, *items: str) -> Self: ...
228
- def contains_in_order(self, *items: object) -> Self: ...
247
+ def contains_in_order(
248
+ self: _CapableAssertion[Iterable[_E] | _Indexed[_E]], *items: object
249
+ ) -> _CapableAssertion[_CapableT_co]: ...
229
250
  def contains_key(self: _CapableAssertion[_Keyed], *keys: object) -> _CapableAssertion[_CapableT_co]: ...
230
251
  def contains_none_of(self, *items: str) -> Self: ...
231
252
  def contains_only(self, *items: object) -> Self: ...
@@ -431,3 +452,278 @@ if TYPE_CHECKING:
431
452
  def zip_satisfies(
432
453
  self, other: Iterable[object], predicate: Callable[..., bool], *, allow_empty: bool = ...
433
454
  ) -> Self: ...
455
+
456
+ class _NegatedCapableAssertion(Protocol[_CapableT_co]):
457
+ """The negation twin of the capability facade: one step, then it back."""
458
+
459
+ def is_not_none(self) -> _CapableAssertion[_CapableT_co]: ...
460
+ @overload
461
+ def is_instance_of(self, some_class: tuple[type[_U], type[_U2]]) -> _CapableAssertion[_CapableT_co]: ...
462
+ @overload
463
+ def is_instance_of(
464
+ self, some_class: tuple[type[_U], type[_U2], type[_U3]]
465
+ ) -> _CapableAssertion[_CapableT_co]: ...
466
+ @overload
467
+ def is_instance_of(self, some_class: type[_U]) -> _CapableAssertion[_CapableT_co]: ...
468
+ @overload
469
+ def is_instance_of(self, some_class: ClassInfo) -> _CapableAssertion[_CapableT_co]: ...
470
+ @overload
471
+ def is_instance_of_any(self, first: type[_U], second: type[_U2], /) -> _CapableAssertion[_CapableT_co]: ...
472
+ @overload
473
+ def is_instance_of_any(
474
+ self, first: type[_U], second: type[_U2], third: type[_U3], /
475
+ ) -> _CapableAssertion[_CapableT_co]: ...
476
+ @overload
477
+ def is_instance_of_any(self, *some_classes: ClassInfo) -> _CapableAssertion[_CapableT_co]: ...
478
+ def satisfies(self, matcher: Matcher[Any] | Callable[..., bool]) -> _CapableAssertion[_CapableT_co]: ...
479
+ def all_fields_satisfy(
480
+ self, matcher: Matcher[Any] | Callable[..., bool], *, allow_empty: bool = ...
481
+ ) -> _CapableAssertion[_CapableT_co]: ...
482
+ def all_satisfy(
483
+ self, matcher: Matcher[Any] | Callable[..., bool], *, allow_empty: bool = ...
484
+ ) -> _CapableAssertion[_CapableT_co]: ...
485
+ def any_satisfy(self, matcher: Matcher[Any] | Callable[..., bool]) -> _CapableAssertion[_CapableT_co]: ...
486
+ def caused_by(self, ex: type) -> _CapableAssertion[_CapableT_co]: ...
487
+ def conforms_to_openapi(
488
+ self,
489
+ spec: dict[str, Any],
490
+ path: str,
491
+ method: str,
492
+ *,
493
+ status: str | int | None = ...,
494
+ content_type: str = ...,
495
+ ) -> _CapableAssertion[_CapableT_co]: ...
496
+ def contains(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
497
+ def contains_any_of(self, *items: str) -> _CapableAssertion[_CapableT_co]: ...
498
+ def contains_bytes(
499
+ self: _NegatedCapableAssertion[bytes | bytearray], sub: bytes | bytearray
500
+ ) -> _CapableAssertion[_CapableT_co]: ...
501
+ def contains_duplicates(self) -> _CapableAssertion[_CapableT_co]: ...
502
+ def contains_entry(
503
+ self: _NegatedCapableAssertion[_KeyedWithItems], *args: object, **kwargs: object
504
+ ) -> _CapableAssertion[_CapableT_co]: ...
505
+ def contains_error(self, *ex_types: type) -> _CapableAssertion[_CapableT_co]: ...
506
+ def contains_exactly(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
507
+ def contains_exactly_in_any_order(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
508
+ def contains_ignoring_case(self, *items: str) -> _CapableAssertion[_CapableT_co]: ...
509
+ def contains_in_order(
510
+ self: _NegatedCapableAssertion[Iterable[_E] | _Indexed[_E]], *items: object
511
+ ) -> _CapableAssertion[_CapableT_co]: ...
512
+ def contains_key(self: _NegatedCapableAssertion[_Keyed], *keys: object) -> _CapableAssertion[_CapableT_co]: ...
513
+ def contains_none_of(self, *items: str) -> _CapableAssertion[_CapableT_co]: ...
514
+ def contains_only(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
515
+ def contains_only_once(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
516
+ def contains_sequence(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
517
+ def contains_value(
518
+ self: _NegatedCapableAssertion[_KeyedWithValues], *values: object
519
+ ) -> _CapableAssertion[_CapableT_co]: ...
520
+ def does_not_contain(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
521
+ def does_not_contain_duplicates(self) -> _CapableAssertion[_CapableT_co]: ...
522
+ def does_not_contain_entry(
523
+ self: _NegatedCapableAssertion[_KeyedWithItems], *args: object, **kwargs: object
524
+ ) -> _CapableAssertion[_CapableT_co]: ...
525
+ def does_not_contain_error(self, *ex_types: type) -> _CapableAssertion[_CapableT_co]: ...
526
+ def does_not_contain_key(
527
+ self: _NegatedCapableAssertion[_Keyed], *keys: object
528
+ ) -> _CapableAssertion[_CapableT_co]: ...
529
+ def does_not_contain_value(
530
+ self: _NegatedCapableAssertion[_KeyedWithValues], *values: object
531
+ ) -> _CapableAssertion[_CapableT_co]: ...
532
+ def does_not_exist(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
533
+ def does_not_have_json_path(self, path: str) -> _CapableAssertion[_CapableT_co]: ...
534
+ def does_not_match(self: _NegatedCapableAssertion[str], pattern: str) -> _CapableAssertion[_CapableT_co]: ...
535
+ def each(
536
+ self, matcher: Matcher[Any] | Callable[..., bool], *, allow_empty: bool = ...
537
+ ) -> _CapableAssertion[_CapableT_co]: ...
538
+ def ends_with(self, suffix: object) -> _CapableAssertion[_CapableT_co]: ...
539
+ def ends_with_ignoring_case(
540
+ self: _NegatedCapableAssertion[str], suffix: str
541
+ ) -> _CapableAssertion[_CapableT_co]: ...
542
+ def error_of(self, ex: type) -> _CapableAssertion[_CapableT_co]: ...
543
+ def exists(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
544
+ def extracting_group(
545
+ self: _NegatedCapableAssertion[str], pattern: str, group: int | str = ...
546
+ ) -> _CapableAssertion[_CapableT_co]: ...
547
+ def has_byte_at(
548
+ self: _NegatedCapableAssertion[bytes | bytearray], index: int, expected: int
549
+ ) -> _CapableAssertion[_CapableT_co]: ...
550
+ def has_json_path(self, path: str) -> _CapableAssertion[_CapableT_co]: ...
551
+ def has_no_none_fields(self, *, allow_empty: bool = ...) -> _CapableAssertion[_CapableT_co]: ...
552
+ def has_root_cause(self, ex: type) -> _CapableAssertion[_CapableT_co]: ...
553
+ def has_same_size_as(self, other: Sized) -> _CapableAssertion[_CapableT_co]: ...
554
+ def has_size_between(self, low: int, high: int) -> _CapableAssertion[_CapableT_co]: ...
555
+ def has_size_greater_than(self, size: int) -> _CapableAssertion[_CapableT_co]: ...
556
+ def has_size_less_than(self, size: int) -> _CapableAssertion[_CapableT_co]: ...
557
+ def is_after(
558
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
559
+ ) -> _CapableAssertion[_CapableT_co]: ...
560
+ def is_after_or_equal_to(
561
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
562
+ ) -> _CapableAssertion[_CapableT_co]: ...
563
+ def is_alpha(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
564
+ def is_alphanumeric(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
565
+ def is_array_close_to(
566
+ self, expected: object, *, rtol: float = ..., atol: float = ..., equal_nan: bool = ..., **options: Any
567
+ ) -> _CapableAssertion[_CapableT_co]: ...
568
+ def is_array_equal(self, expected: object, **options: Any) -> _CapableAssertion[_CapableT_co]: ...
569
+ def is_before(
570
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
571
+ ) -> _CapableAssertion[_CapableT_co]: ...
572
+ def is_before_or_equal_to(
573
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
574
+ ) -> _CapableAssertion[_CapableT_co]: ...
575
+ def is_between(self, low: object, high: object) -> _CapableAssertion[_CapableT_co]: ...
576
+ def is_callable(self) -> _CapableAssertion[_CapableT_co]: ...
577
+ def is_child_of(
578
+ self: _NegatedCapableAssertion[_PathLike], parent: object
579
+ ) -> _CapableAssertion[_CapableT_co]: ...
580
+ def is_close_to(
581
+ self: _NegatedCapableAssertion[SupportsFloat | SupportsIndex],
582
+ other: SupportsFloat | SupportsIndex | datetime.datetime,
583
+ tolerance: SupportsFloat | SupportsIndex | datetime.timedelta,
584
+ ) -> _CapableAssertion[_CapableT_co]: ...
585
+ def is_digit(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
586
+ def is_directory(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
587
+ def is_divisible_by(self: _NegatedCapableAssertion[int], divisor: int) -> _CapableAssertion[_CapableT_co]: ...
588
+ def is_empty(self) -> _CapableAssertion[_CapableT_co]: ...
589
+ def is_equal_to(self, other: object, **kwargs: object) -> _CapableAssertion[_CapableT_co]: ...
590
+ def is_equal_to_ignoring_case(
591
+ self: _NegatedCapableAssertion[str], other: str
592
+ ) -> _CapableAssertion[_CapableT_co]: ...
593
+ def is_equal_to_ignoring_milliseconds(
594
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
595
+ ) -> _CapableAssertion[_CapableT_co]: ...
596
+ def is_equal_to_ignoring_seconds(
597
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
598
+ ) -> _CapableAssertion[_CapableT_co]: ...
599
+ def is_equal_to_ignoring_time(
600
+ self: _NegatedCapableAssertion[datetime.datetime], other: datetime.datetime
601
+ ) -> _CapableAssertion[_CapableT_co]: ...
602
+ def is_equal_to_ignoring_whitespace(
603
+ self: _NegatedCapableAssertion[str], other: str
604
+ ) -> _CapableAssertion[_CapableT_co]: ...
605
+ def is_even(self: _NegatedCapableAssertion[int]) -> _CapableAssertion[_CapableT_co]: ...
606
+ def is_executable(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
607
+ def is_false(self) -> _CapableAssertion[_CapableT_co]: ...
608
+ def is_file(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
609
+ def is_frame_equal(self, expected: object, **options: Any) -> _CapableAssertion[_CapableT_co]: ...
610
+ def is_greater_than(
611
+ self: _NegatedCapableAssertion[_Orderable], other: object
612
+ ) -> _CapableAssertion[_CapableT_co]: ...
613
+ def is_greater_than_or_equal_to(
614
+ self: _NegatedCapableAssertion[_Orderable], other: object
615
+ ) -> _CapableAssertion[_CapableT_co]: ...
616
+ def is_hex_equal_to(
617
+ self: _NegatedCapableAssertion[bytes | bytearray], expected_hex: str
618
+ ) -> _CapableAssertion[_CapableT_co]: ...
619
+ def is_in(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
620
+ def is_inf(
621
+ self: _NegatedCapableAssertion[SupportsFloat | SupportsIndex],
622
+ ) -> _CapableAssertion[_CapableT_co]: ...
623
+ def is_iterable(self) -> _CapableAssertion[_CapableT_co]: ...
624
+ def is_length(self, length: int) -> _CapableAssertion[_CapableT_co]: ...
625
+ def is_length_between(self, low: int, high: int) -> _CapableAssertion[_CapableT_co]: ...
626
+ def is_less_than(
627
+ self: _NegatedCapableAssertion[_Orderable], other: object
628
+ ) -> _CapableAssertion[_CapableT_co]: ...
629
+ def is_less_than_or_equal_to(
630
+ self: _NegatedCapableAssertion[_Orderable], other: object
631
+ ) -> _CapableAssertion[_CapableT_co]: ...
632
+ def is_lower(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
633
+ def is_named(self: _NegatedCapableAssertion[_PathLike], filename: str) -> _CapableAssertion[_CapableT_co]: ...
634
+ def is_nan(
635
+ self: _NegatedCapableAssertion[SupportsFloat | SupportsIndex],
636
+ ) -> _CapableAssertion[_CapableT_co]: ...
637
+ def is_negative(self: _NegatedCapableAssertion[_Orderable]) -> _CapableAssertion[_CapableT_co]: ...
638
+ def is_none(self) -> _CapableAssertion[_CapableT_co]: ...
639
+ def is_not_between(self, low: object, high: object) -> _CapableAssertion[_CapableT_co]: ...
640
+ def is_not_callable(self) -> _CapableAssertion[_CapableT_co]: ...
641
+ def is_not_close_to(
642
+ self,
643
+ other: SupportsFloat | SupportsIndex | datetime.datetime,
644
+ tolerance: SupportsFloat | SupportsIndex | datetime.timedelta,
645
+ ) -> _CapableAssertion[_CapableT_co]: ...
646
+ def is_not_empty(self) -> _CapableAssertion[_CapableT_co]: ...
647
+ def is_not_equal_to(self, other: object) -> _CapableAssertion[_CapableT_co]: ...
648
+ def is_not_in(self, *items: object) -> _CapableAssertion[_CapableT_co]: ...
649
+ def is_not_inf(
650
+ self: _NegatedCapableAssertion[SupportsFloat | SupportsIndex],
651
+ ) -> _CapableAssertion[_CapableT_co]: ...
652
+ def is_not_iterable(self) -> _CapableAssertion[_CapableT_co]: ...
653
+ def is_not_nan(
654
+ self: _NegatedCapableAssertion[SupportsFloat | SupportsIndex],
655
+ ) -> _CapableAssertion[_CapableT_co]: ...
656
+ def is_not_same_as(self, other: object) -> _CapableAssertion[_CapableT_co]: ...
657
+ def is_not_zero(self) -> _CapableAssertion[_CapableT_co]: ...
658
+ def is_odd(self: _NegatedCapableAssertion[int]) -> _CapableAssertion[_CapableT_co]: ...
659
+ def is_positive(self: _NegatedCapableAssertion[_Orderable]) -> _CapableAssertion[_CapableT_co]: ...
660
+ def is_readable(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
661
+ def is_same_as(self, other: object) -> _CapableAssertion[_CapableT_co]: ...
662
+ def is_sorted(
663
+ self, key: Callable[[Any], Any] = ..., reverse: bool = ..., *, allow_empty: bool = ...
664
+ ) -> _CapableAssertion[_CapableT_co]: ...
665
+ def is_subclass_of(self, some_class: type) -> _CapableAssertion[_CapableT_co]: ...
666
+ def is_subset_of(self, *supersets: object, allow_empty: bool = ...) -> _CapableAssertion[_CapableT_co]: ...
667
+ def is_true(self) -> _CapableAssertion[_CapableT_co]: ...
668
+ def is_type_of(self, some_type: type) -> _CapableAssertion[_CapableT_co]: ...
669
+ def is_unicode(self) -> _CapableAssertion[_CapableT_co]: ...
670
+ def is_upper(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
671
+ def is_valid_encoding(
672
+ self: _NegatedCapableAssertion[bytes | bytearray], encoding: str
673
+ ) -> _CapableAssertion[_CapableT_co]: ...
674
+ def is_valid_utf8(self: _NegatedCapableAssertion[bytes | bytearray]) -> _CapableAssertion[_CapableT_co]: ...
675
+ def is_whitespace(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
676
+ def is_writable(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
677
+ def is_zero(self) -> _CapableAssertion[_CapableT_co]: ...
678
+ def matches(self: _NegatedCapableAssertion[str], pattern: str) -> _CapableAssertion[_CapableT_co]: ...
679
+ def matches_contract_snapshot(
680
+ self, id: str | None = ..., path: str = ...
681
+ ) -> _CapableAssertion[_CapableT_co]: ...
682
+ def matches_error_tree(self, *expected: type | list[Any]) -> _CapableAssertion[_CapableT_co]: ...
683
+ def matches_inline(
684
+ self,
685
+ expected: object = ...,
686
+ *,
687
+ ignore: object = ...,
688
+ include: object = ...,
689
+ tolerance: float | None = ...,
690
+ comparators: dict[Any, Callable[[Any, Any], Any]] | None = ...,
691
+ placeholders: Mapping[Any, Matcher[Any] | Callable[[Any], object]] | None = ...,
692
+ ) -> _CapableAssertion[_CapableT_co]: ...
693
+ def matches_json_schema(self, schema: dict[str, Any]) -> _CapableAssertion[_CapableT_co]: ...
694
+ def matches_json_schema_from_file(self, path: str | Path) -> _CapableAssertion[_CapableT_co]: ...
695
+ def matches_structure(self, spec: dict[Any, Any]) -> _CapableAssertion[_CapableT_co]: ...
696
+ def matches_with_groups(
697
+ self: _NegatedCapableAssertion[str], pattern: str
698
+ ) -> _CapableAssertion[_CapableT_co]: ...
699
+ def none_satisfy(self, matcher: Matcher[Any] | Callable[..., bool]) -> _CapableAssertion[_CapableT_co]: ...
700
+ def satisfies_exactly(
701
+ self, *matchers: Matcher[Any] | Callable[..., bool]
702
+ ) -> _CapableAssertion[_CapableT_co]: ...
703
+ def satisfies_exactly_in_any_order(
704
+ self, *matchers: Matcher[Any] | Callable[..., bool]
705
+ ) -> _CapableAssertion[_CapableT_co]: ...
706
+ def snapshot(
707
+ self,
708
+ id: str | None = ...,
709
+ path: str = ...,
710
+ *,
711
+ ignore: object = ...,
712
+ include: object = ...,
713
+ tolerance: float | None = ...,
714
+ comparators: dict[Any, Callable[[Any, Any], Any]] | None = ...,
715
+ placeholders: Mapping[Any, Matcher[Any] | Callable[[Any], object]] | None = ...,
716
+ ) -> _CapableAssertion[_CapableT_co]: ...
717
+ def starts_with(self, prefix: object) -> _CapableAssertion[_CapableT_co]: ...
718
+ def starts_with_bytes(
719
+ self: _NegatedCapableAssertion[bytes | bytearray], prefix: bytes | bytearray
720
+ ) -> _CapableAssertion[_CapableT_co]: ...
721
+ def starts_with_ignoring_case(
722
+ self: _NegatedCapableAssertion[str], prefix: str
723
+ ) -> _CapableAssertion[_CapableT_co]: ...
724
+ def when_called_with(
725
+ self: _NegatedCapableAssertion[_Callable], *some_args: object, **some_kwargs: object
726
+ ) -> _CapableAssertion[_CapableT_co]: ...
727
+ def zip_satisfies(
728
+ self, other: Iterable[object], predicate: Callable[..., bool], *, allow_empty: bool = ...
729
+ ) -> _CapableAssertion[_CapableT_co]: ...
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any
5
5
  if TYPE_CHECKING:
6
6
  from ..errors import AssertionFailure, DiffResult, PollTrace
7
7
  from ..http_mixin import _Response
8
- from ..outcome import AssertionOutcome
8
+ from ..outcome import AssertionOutcome, Requirement
9
9
  from ._compare import _CompareConfig
10
10
  from ._compat import Self
11
11
  from ._introspection import WarningLogger
@@ -45,6 +45,7 @@ class _MixinBase:
45
45
  actual: object = ...,
46
46
  expected: object = ...,
47
47
  diff: DiffResult | None = ...,
48
+ requirement: Requirement | None = ...,
48
49
  suppress_context: bool = ...,
49
50
  ) -> Self: ...
50
51
 
@@ -56,6 +57,7 @@ class _MixinBase:
56
57
  expected: object,
57
58
  diff: DiffResult | None,
58
59
  trace: PollTrace | None,
60
+ requirement: Requirement | None = ...,
59
61
  ) -> AssertionOutcome: ...
60
62
 
61
63
  @staticmethod