assertpy2 2.31.0__tar.gz → 2.32.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 (301) hide show
  1. {assertpy2-2.31.0 → assertpy2-2.32.0}/PKG-INFO +1 -1
  2. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_builder_check_typing.py +7 -4
  3. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_capable_typing.py +19 -8
  4. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_check_typing.py +5 -4
  5. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_negated_typing.py +21 -16
  6. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_poll_typing.py +23 -16
  7. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_require.py +17 -0
  8. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_typing.py +5 -4
  9. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_matcher_impls.py +4 -6
  10. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/assertpy.py +1 -1
  11. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/matchers.py +3 -2
  12. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/string.py +32 -34
  13. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/concepts/stability.md +1 -1
  14. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/guides/assertions.md +11 -6
  15. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/guides/matchers.md +1 -1
  16. {assertpy2-2.31.0 → assertpy2-2.32.0}/pyproject.toml +1 -1
  17. {assertpy2-2.31.0 → assertpy2-2.32.0}/scripts/generate_check_protocols.py +1 -0
  18. {assertpy2-2.31.0 → assertpy2-2.32.0}/scripts/generate_poll_protocols.py +2 -0
  19. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/api_snapshot.json +29 -29
  20. assertpy2-2.32.0/tests/test_compiled_patterns.py +209 -0
  21. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_refusal_frames.py +4 -0
  22. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_string.py +11 -2
  23. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing.py +11 -0
  24. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_cases.py +6 -0
  25. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_negative_baseline.py +4 -0
  26. {assertpy2-2.31.0 → assertpy2-2.32.0}/.gitignore +0 -0
  27. {assertpy2-2.31.0 → assertpy2-2.32.0}/CONTRIBUTING.md +0 -0
  28. {assertpy2-2.31.0 → assertpy2-2.32.0}/LICENSE +0 -0
  29. {assertpy2-2.31.0 → assertpy2-2.32.0}/README.md +0 -0
  30. {assertpy2-2.31.0 → assertpy2-2.32.0}/SECURITY.md +0 -0
  31. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/__init__.py +0 -0
  32. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_clustering.py +0 -0
  33. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_dangling.py +0 -0
  34. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/__init__.py +0 -0
  35. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_compare.py +0 -0
  36. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_compat.py +0 -0
  37. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_contract.py +0 -0
  38. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_diff.py +0 -0
  39. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_equality.py +0 -0
  40. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_introspection.py +0 -0
  41. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_membership.py +0 -0
  42. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_mixin_base.py +0 -0
  43. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_operations.py +0 -0
  44. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_ordering.py +0 -0
  45. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_pairing.py +0 -0
  46. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_path.py +0 -0
  47. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_size.py +0 -0
  48. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_engine/_text.py +0 -0
  49. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_hints.py +0 -0
  50. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_inline.py +0 -0
  51. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_satisfies.py +0 -0
  52. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/_snapshot_codec.py +0 -0
  53. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/async_assertions.py +0 -0
  54. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/base.py +0 -0
  55. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/behave_matchers.py +0 -0
  56. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/bytes_mixin.py +0 -0
  57. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/collection.py +0 -0
  58. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/contains.py +0 -0
  59. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/dataframe.py +0 -0
  60. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/date.py +0 -0
  61. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/dict.py +0 -0
  62. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/dynamic.py +0 -0
  63. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/errors.py +0 -0
  64. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/exception.py +0 -0
  65. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/extracting.py +0 -0
  66. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/file.py +0 -0
  67. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/helpers.py +0 -0
  68. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/http_mixin.py +0 -0
  69. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/json_mixin.py +0 -0
  70. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/numeric.py +0 -0
  71. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/outcome.py +0 -0
  72. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/py.typed +0 -0
  73. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/pytest_plugin.py +0 -0
  74. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/snapshot.py +0 -0
  75. {assertpy2-2.31.0 → assertpy2-2.32.0}/assertpy2/warning.py +0 -0
  76. {assertpy2-2.31.0 → assertpy2-2.32.0}/benchmarks/test_perf.py +0 -0
  77. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-equal.png +0 -0
  78. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-equal.svg +0 -0
  79. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-gallery.png +0 -0
  80. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-match.svg +0 -0
  81. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-sequence.svg +0 -0
  82. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-set.svg +0 -0
  83. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/assets/diff-string.svg +0 -0
  84. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/concepts/type-safety.md +0 -0
  85. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/extending/custom-assertions.md +0 -0
  86. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/extending/integrations.md +0 -0
  87. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/getting-started/comparison.md +0 -0
  88. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/getting-started/migration.md +0 -0
  89. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/getting-started/quickstart.md +0 -0
  90. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/guides/data.md +0 -0
  91. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/guides/errors.md +0 -0
  92. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/guides/fluent.md +0 -0
  93. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/guides/testing.md +0 -0
  94. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/index.md +0 -0
  95. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/logo-dark.svg +0 -0
  96. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/logo.svg +0 -0
  97. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/recipes.md +0 -0
  98. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/async.md +0 -0
  99. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/bytes.md +0 -0
  100. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/collections.md +0 -0
  101. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/containment.md +0 -0
  102. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/core.md +0 -0
  103. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/dataframes.md +0 -0
  104. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/dates.md +0 -0
  105. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/dicts.md +0 -0
  106. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/dynamic.md +0 -0
  107. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/entry-points.md +0 -0
  108. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/errors.md +0 -0
  109. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/exceptions.md +0 -0
  110. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/extracting.md +0 -0
  111. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/files.md +0 -0
  112. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/http.md +0 -0
  113. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/json.md +0 -0
  114. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/matchers.md +0 -0
  115. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/numbers.md +0 -0
  116. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/overview.md +0 -0
  117. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/snapshots.md +0 -0
  118. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/strings.md +0 -0
  119. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/reference/warnings.md +0 -0
  120. {assertpy2-2.31.0 → assertpy2-2.32.0}/docs/stylesheets/extra.css +0 -0
  121. {assertpy2-2.31.0 → assertpy2-2.32.0}/mkdocs.yml +0 -0
  122. {assertpy2-2.31.0 → assertpy2-2.32.0}/mkdocs_hooks.py +0 -0
  123. {assertpy2-2.31.0 → assertpy2-2.32.0}/scripts/mutation_report.py +0 -0
  124. {assertpy2-2.31.0 → assertpy2-2.32.0}/scripts/regenerate.py +0 -0
  125. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/api_surface.py +0 -0
  126. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/chain_corpus.py +0 -0
  127. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/chain_model.py +0 -0
  128. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/chain_surfaces.py +0 -0
  129. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/conftest.py +0 -0
  130. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/LICENSE +0 -0
  131. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/date-time.json +0 -0
  132. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/date.json +0 -0
  133. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/duration.json +0 -0
  134. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/email.json +0 -0
  135. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/hostname.json +0 -0
  136. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/multipleOf.json +0 -0
  137. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/time.json +0 -0
  138. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/data/json_schema_test_suite/uri.json +0 -0
  139. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/docs_fixtures.py +0 -0
  140. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/format_corpus.py +0 -0
  141. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/group_compat.py +0 -0
  142. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/poll_parity_baseline.py +0 -0
  143. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/poll_parity_cases.py +0 -0
  144. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/pyright_baseline.py +0 -0
  145. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_api_compatibility.py +0 -0
  146. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_api_vocabulary.py +0 -0
  147. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_architecture_doc.py +0 -0
  148. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_async.py +0 -0
  149. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_async_predicates.py +0 -0
  150. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_attrs_support.py +0 -0
  151. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_behave_matchers.py +0 -0
  152. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_bool.py +0 -0
  153. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_boundary_cases.py +0 -0
  154. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_bytes.py +0 -0
  155. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_call_awaitables.py +0 -0
  156. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_callable.py +0 -0
  157. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_capable_protocol.py +0 -0
  158. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_chain_machine.py +0 -0
  159. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_chaining.py +0 -0
  160. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_check.py +0 -0
  161. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_check_protocols.py +0 -0
  162. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_class.py +0 -0
  163. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_class_in_spec.py +0 -0
  164. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_clustering.py +0 -0
  165. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_collection.py +0 -0
  166. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_complexity.py +0 -0
  167. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_core.py +0 -0
  168. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_custom_dict.py +0 -0
  169. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_custom_list.py +0 -0
  170. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_dangling.py +0 -0
  171. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_dataframe.py +0 -0
  172. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_datetime.py +0 -0
  173. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_declared_floors.py +0 -0
  174. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_deep_nesting.py +0 -0
  175. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_description.py +0 -0
  176. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_dict.py +0 -0
  177. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_dict_compare.py +0 -0
  178. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_diff_laws.py +0 -0
  179. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_difference_places.py +0 -0
  180. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_docs_examples.py +0 -0
  181. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_docs_typing.py +0 -0
  182. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_duality.py +0 -0
  183. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_dynamic.py +0 -0
  184. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_equality_signals.py +0 -0
  185. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_equals.py +0 -0
  186. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_errors.py +0 -0
  187. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_evaluation_core.py +0 -0
  188. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_exact_oracle.py +0 -0
  189. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_exception_context.py +0 -0
  190. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_exception_fields.py +0 -0
  191. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_expected_contract.py +0 -0
  192. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_expected_exception.py +0 -0
  193. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_expected_warning.py +0 -0
  194. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_extensions.py +0 -0
  195. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_extracting.py +0 -0
  196. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_fail.py +0 -0
  197. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_file.py +0 -0
  198. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_fixed_width_integers.py +0 -0
  199. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_grouped_soft.py +0 -0
  200. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_hints.py +0 -0
  201. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_hostile_values.py +0 -0
  202. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_http.py +0 -0
  203. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_import_cost.py +0 -0
  204. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_in.py +0 -0
  205. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_inline_record.py +0 -0
  206. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_inline_snapshot.py +0 -0
  207. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_integer_arguments.py +0 -0
  208. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_iterable_cluster.py +0 -0
  209. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_json.py +0 -0
  210. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_list.py +0 -0
  211. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_match_result.py +0 -0
  212. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_matcher_algebra.py +0 -0
  213. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_matcher_parity.py +0 -0
  214. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_matcher_registry.py +0 -0
  215. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_matchers.py +0 -0
  216. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_membership_failures.py +0 -0
  217. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_membership_family.py +0 -0
  218. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_message_elision.py +0 -0
  219. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_message_values.py +0 -0
  220. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_missing_names.py +0 -0
  221. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_moment_relations.py +0 -0
  222. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_namedtuple.py +0 -0
  223. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_negated_protocols.py +0 -0
  224. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_none.py +0 -0
  225. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_not.py +0 -0
  226. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_number_zoo.py +0 -0
  227. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_numbers.py +0 -0
  228. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_numeric_questions.py +0 -0
  229. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_one_shot_chains.py +0 -0
  230. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_30_keywords.py +0 -0
  231. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_contract.py +0 -0
  232. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_format_suite.py +0 -0
  233. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_formats.py +0 -0
  234. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_multiple_of.py +0 -0
  235. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_oracle.py +0 -0
  236. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_openapi_part_read.py +0 -0
  237. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_operation_contract.py +0 -0
  238. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_optional_integration_contracts.py +0 -0
  239. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_overload_order.py +0 -0
  240. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_overloads.py +0 -0
  241. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_pin_coverage.py +0 -0
  242. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_pipeline.py +0 -0
  243. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_poll_parity.py +0 -0
  244. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_poll_protocols.py +0 -0
  245. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_prerequisites.py +0 -0
  246. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_property_attrs.py +0 -0
  247. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_property_based.py +0 -0
  248. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_protocol_parity.py +0 -0
  249. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_public_surface.py +0 -0
  250. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_pyright_baseline.py +0 -0
  251. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_pytest_plugin.py +0 -0
  252. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_recursive_assertion.py +0 -0
  253. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_recursive_compare.py +0 -0
  254. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_recursive_compare_attrs.py +0 -0
  255. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_recursive_compare_config.py +0 -0
  256. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_recursive_compare_pydantic.py +0 -0
  257. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_refusals.py +0 -0
  258. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_regex_groups.py +0 -0
  259. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_render_laws.py +0 -0
  260. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_requirement.py +0 -0
  261. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_rich_diff.py +0 -0
  262. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_same_as.py +0 -0
  263. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_satisfy.py +0 -0
  264. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_skip_guard.py +0 -0
  265. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_snapshots.py +0 -0
  266. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_soft.py +0 -0
  267. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_soft_fail.py +0 -0
  268. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_soft_summary_blocks.py +0 -0
  269. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_strict_reach.py +0 -0
  270. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_structural.py +0 -0
  271. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_structure_sentence.py +0 -0
  272. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_surface_conformance.py +0 -0
  273. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_sync_eventually.py +0 -0
  274. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_text_relations.py +0 -0
  275. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_traceback.py +0 -0
  276. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_type.py +0 -0
  277. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_type_expression_failures.py +0 -0
  278. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_chain_corpus.py +0 -0
  279. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_claims.py +0 -0
  280. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_completeness.py +0 -0
  281. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_conformance.py +0 -0
  282. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_from_a_wheel.py +0 -0
  283. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_harness.py +0 -0
  284. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_http.py +0 -0
  285. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_integrations.py +0 -0
  286. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_negative.py +0 -0
  287. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_typing_promises.py +0 -0
  288. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_unrenderable_values.py +0 -0
  289. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_vacuity_contract.py +0 -0
  290. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_verdict_corpus.py +0 -0
  291. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_verdicts_held_to_python.py +0 -0
  292. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_warn.py +0 -0
  293. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/test_warn_on_failure.py +0 -0
  294. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_chain_corpus_baseline.json +0 -0
  295. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_harness.py +0 -0
  296. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_http.py +0 -0
  297. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_integrations.py +0 -0
  298. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_integrations_baseline.py +0 -0
  299. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/typing_promises.py +0 -0
  300. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/verdict_corpus.py +0 -0
  301. {assertpy2-2.31.0 → assertpy2-2.32.0}/tests/verdict_golden.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: assertpy2
3
- Version: 2.31.0
3
+ Version: 2.32.0
4
4
  Summary: Fluent, fully typed assertion library for Python: your type checker sees only the assertions that fit the value, and every failure carries a structured diff. Soft assertions, polling, inline snapshots, OpenAPI contracts.
5
5
  Project-URL: Homepage, https://github.com/Solganis/assertpy2
6
6
  Project-URL: Repository, https://github.com/Solganis/assertpy2
@@ -24,6 +24,7 @@ from typing import TYPE_CHECKING
24
24
  if TYPE_CHECKING:
25
25
  import datetime
26
26
  import pathlib
27
+ import re
27
28
  from collections.abc import Callable, Hashable, Iterable, Mapping, Sized
28
29
  from pathlib import Path
29
30
  from typing import Any, Protocol, SupportsFloat, SupportsIndex, TypeVar, overload
@@ -155,9 +156,9 @@ if TYPE_CHECKING:
155
156
 
156
157
  def ends_with_ignoring_case(self: _CheckAnyValue[str], suffix: str) -> AssertionOutcome: ...
157
158
 
158
- def matches(self: _CheckAnyValue[str], pattern: str) -> AssertionOutcome: ...
159
+ def matches(self: _CheckAnyValue[str], pattern: str | re.Pattern[str]) -> AssertionOutcome: ...
159
160
 
160
- def does_not_match(self: _CheckAnyValue[str], pattern: str) -> AssertionOutcome: ...
161
+ def does_not_match(self: _CheckAnyValue[str], pattern: str | re.Pattern[str]) -> AssertionOutcome: ...
161
162
 
162
163
  def is_alpha(self: _CheckAnyValue[str]) -> AssertionOutcome: ...
163
164
 
@@ -571,9 +572,11 @@ if TYPE_CHECKING:
571
572
  allow_empty: bool = ...,
572
573
  ) -> AssertionOutcome: ...
573
574
 
574
- def extracting_group(self: _CheckAnyValue[str], pattern: str, group: int | str = ...) -> AssertionOutcome: ...
575
+ def extracting_group(
576
+ self: _CheckAnyValue[str], pattern: str | re.Pattern[str], group: int | str = ...
577
+ ) -> AssertionOutcome: ...
575
578
 
576
- def matches_with_groups(self: _CheckAnyValue[str], pattern: str) -> AssertionOutcome: ...
579
+ def matches_with_groups(self: _CheckAnyValue[str], pattern: str | re.Pattern[str]) -> AssertionOutcome: ...
577
580
 
578
581
  @overload
579
582
  def exists(self: _CheckAnyValue[str] | _CheckAnyValue[pathlib.Path]) -> AssertionOutcome: ...
@@ -24,6 +24,7 @@ from typing import TYPE_CHECKING
24
24
  if TYPE_CHECKING:
25
25
  import datetime
26
26
  import logging
27
+ import re
27
28
  from collections.abc import Callable, Iterable, Mapping, Sized
28
29
  from pathlib import Path
29
30
  from typing import Any, Protocol, SupportsFloat, SupportsIndex, TypeVar, overload
@@ -297,7 +298,9 @@ if TYPE_CHECKING:
297
298
  ) -> _CapableAssertion[_CapableT_co]: ...
298
299
  def does_not_exist(self: _CapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
299
300
  def does_not_have_json_path(self, path: str) -> Self: ...
300
- def does_not_match(self: _CapableAssertion[str], pattern: str) -> _CapableAssertion[_CapableT_co]: ...
301
+ def does_not_match(
302
+ self: _CapableAssertion[str], pattern: str | re.Pattern[str]
303
+ ) -> _CapableAssertion[_CapableT_co]: ...
301
304
  def each(self, matcher: Matcher[Any] | Callable[..., bool], *, allow_empty: bool = ...) -> Self: ...
302
305
  def ends_with(self, suffix: object) -> Self: ...
303
306
  def ends_with_ignoring_case(self: _CapableAssertion[str], suffix: str) -> _CapableAssertion[_CapableT_co]: ...
@@ -306,7 +309,7 @@ if TYPE_CHECKING:
306
309
  def exists(self: _CapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
307
310
  def extracting(self, *names: object, **kwargs: object) -> _ListAssertion[Any]: ...
308
311
  def extracting_group(
309
- self: _CapableAssertion[str], pattern: str, group: int | str = ...
312
+ self: _CapableAssertion[str], pattern: str | re.Pattern[str], group: int | str = ...
310
313
  ) -> AssertionBuilder[Any]: ...
311
314
  def filtered_on(self, predicate: Matcher[Any] | Callable[[Any], bool]) -> _ListAssertion[Any]: ...
312
315
  def flat_mapped(self, func: Callable[[Any], Iterable[Any]]) -> _ListAssertion[Any]: ...
@@ -427,7 +430,9 @@ if TYPE_CHECKING:
427
430
  def is_whitespace(self: _CapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
428
431
  def is_writable(self: _CapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
429
432
  def is_zero(self) -> Self: ...
430
- def matches(self: _CapableAssertion[str], pattern: str) -> _CapableAssertion[_CapableT_co]: ...
433
+ def matches(
434
+ self: _CapableAssertion[str], pattern: str | re.Pattern[str]
435
+ ) -> _CapableAssertion[_CapableT_co]: ...
431
436
  def matches_contract_snapshot(self, id: str | None = ..., path: str = ...) -> Self: ...
432
437
  def matches_error_tree(self, *expected: type | list[Any]) -> Self: ...
433
438
  def matches_inline(
@@ -443,7 +448,9 @@ if TYPE_CHECKING:
443
448
  def matches_json_schema(self, schema: dict[str, Any]) -> Self: ...
444
449
  def matches_json_schema_from_file(self, path: str | Path) -> Self: ...
445
450
  def matches_structure(self, spec: dict[Any, Any]) -> Self: ...
446
- def matches_with_groups(self: _CapableAssertion[str], pattern: str) -> AssertionBuilder[Any]: ...
451
+ def matches_with_groups(
452
+ self: _CapableAssertion[str], pattern: str | re.Pattern[str]
453
+ ) -> AssertionBuilder[Any]: ...
447
454
  def none_satisfy(self, matcher: Matcher[Any] | Callable[..., bool]) -> Self: ...
448
455
  def raised(self) -> AssertionBuilder[Any]: ...
449
456
  def returned(self) -> AssertionBuilder[Any]: ...
@@ -548,7 +555,9 @@ if TYPE_CHECKING:
548
555
  ) -> _CapableAssertion[_CapableT_co]: ...
549
556
  def does_not_exist(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
550
557
  def does_not_have_json_path(self, path: str) -> _CapableAssertion[_CapableT_co]: ...
551
- def does_not_match(self: _NegatedCapableAssertion[str], pattern: str) -> _CapableAssertion[_CapableT_co]: ...
558
+ def does_not_match(
559
+ self: _NegatedCapableAssertion[str], pattern: str | re.Pattern[str]
560
+ ) -> _CapableAssertion[_CapableT_co]: ...
552
561
  def each(
553
562
  self, matcher: Matcher[Any] | Callable[..., bool], *, allow_empty: bool = ...
554
563
  ) -> _CapableAssertion[_CapableT_co]: ...
@@ -559,7 +568,7 @@ if TYPE_CHECKING:
559
568
  def error_of(self, ex: type) -> _CapableAssertion[_CapableT_co]: ...
560
569
  def exists(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
561
570
  def extracting_group(
562
- self: _NegatedCapableAssertion[str], pattern: str, group: int | str = ...
571
+ self: _NegatedCapableAssertion[str], pattern: str | re.Pattern[str], group: int | str = ...
563
572
  ) -> _CapableAssertion[_CapableT_co]: ...
564
573
  def has_byte_at(
565
574
  self: _NegatedCapableAssertion[bytes | bytearray], index: SupportsIndex, expected: SupportsIndex
@@ -694,7 +703,9 @@ if TYPE_CHECKING:
694
703
  def is_whitespace(self: _NegatedCapableAssertion[str]) -> _CapableAssertion[_CapableT_co]: ...
695
704
  def is_writable(self: _NegatedCapableAssertion[_PathLike]) -> _CapableAssertion[_CapableT_co]: ...
696
705
  def is_zero(self) -> _CapableAssertion[_CapableT_co]: ...
697
- def matches(self: _NegatedCapableAssertion[str], pattern: str) -> _CapableAssertion[_CapableT_co]: ...
706
+ def matches(
707
+ self: _NegatedCapableAssertion[str], pattern: str | re.Pattern[str]
708
+ ) -> _CapableAssertion[_CapableT_co]: ...
698
709
  def matches_contract_snapshot(
699
710
  self, id: str | None = ..., path: str = ...
700
711
  ) -> _CapableAssertion[_CapableT_co]: ...
@@ -713,7 +724,7 @@ if TYPE_CHECKING:
713
724
  def matches_json_schema_from_file(self, path: str | Path) -> _CapableAssertion[_CapableT_co]: ...
714
725
  def matches_structure(self, spec: dict[Any, Any]) -> _CapableAssertion[_CapableT_co]: ...
715
726
  def matches_with_groups(
716
- self: _NegatedCapableAssertion[str], pattern: str
727
+ self: _NegatedCapableAssertion[str], pattern: str | re.Pattern[str]
717
728
  ) -> _CapableAssertion[_CapableT_co]: ...
718
729
  def none_satisfy(self, matcher: Matcher[Any] | Callable[..., bool]) -> _CapableAssertion[_CapableT_co]: ...
719
730
  def satisfies_exactly(
@@ -14,6 +14,7 @@ from typing import TYPE_CHECKING
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  import datetime
17
+ import re
17
18
  from collections.abc import Callable, Hashable, Iterable, Mapping, Sized
18
19
  from pathlib import Path
19
20
  from typing import Any, Protocol, SupportsFloat, SupportsIndex, TypeVar, overload
@@ -401,8 +402,8 @@ if TYPE_CHECKING:
401
402
  def starts_with_ignoring_case(self, prefix: str) -> AssertionOutcome: ...
402
403
  def ends_with(self, suffix: str) -> AssertionOutcome: ...
403
404
  def ends_with_ignoring_case(self, suffix: str) -> AssertionOutcome: ...
404
- def matches(self, pattern: str) -> AssertionOutcome: ...
405
- def does_not_match(self, pattern: str) -> AssertionOutcome: ...
405
+ def matches(self, pattern: str | re.Pattern[str]) -> AssertionOutcome: ...
406
+ def does_not_match(self, pattern: str | re.Pattern[str]) -> AssertionOutcome: ...
406
407
  def is_alpha(self) -> AssertionOutcome: ...
407
408
  def is_digit(self) -> AssertionOutcome: ...
408
409
  def is_lower(self) -> AssertionOutcome: ...
@@ -439,8 +440,8 @@ if TYPE_CHECKING:
439
440
  def zip_satisfies(
440
441
  self, other: Iterable[_Other], predicate: Callable[[str, _Other], object], *, allow_empty: bool = ...
441
442
  ) -> AssertionOutcome: ...
442
- def extracting_group(self, pattern: str, group: int | str = ...) -> AssertionOutcome: ...
443
- def matches_with_groups(self, pattern: str) -> AssertionOutcome: ...
443
+ def extracting_group(self, pattern: str | re.Pattern[str], group: int | str = ...) -> AssertionOutcome: ...
444
+ def matches_with_groups(self, pattern: str | re.Pattern[str]) -> AssertionOutcome: ...
444
445
  @property
445
446
  def not_(self) -> Self: ...
446
447
 
@@ -17,6 +17,7 @@ from typing import TYPE_CHECKING, Protocol
17
17
 
18
18
  if TYPE_CHECKING:
19
19
  import datetime
20
+ import re
20
21
  from collections.abc import Callable, Hashable, Iterable, Mapping, Sized
21
22
  from pathlib import Path
22
23
  from typing import Any, SupportsFloat, SupportsIndex, TypeVar, overload
@@ -88,8 +89,8 @@ if TYPE_CHECKING:
88
89
  def starts_with_ignoring_case(self, prefix: str) -> _StringAssertion: ...
89
90
  def ends_with(self, suffix: str) -> _StringAssertion: ...
90
91
  def ends_with_ignoring_case(self, suffix: str) -> _StringAssertion: ...
91
- def matches(self, pattern: str) -> _StringAssertion: ...
92
- def does_not_match(self, pattern: str) -> _StringAssertion: ...
92
+ def matches(self, pattern: str | re.Pattern[str]) -> _StringAssertion: ...
93
+ def does_not_match(self, pattern: str | re.Pattern[str]) -> _StringAssertion: ...
93
94
  def is_alpha(self) -> _StringAssertion: ...
94
95
  def is_digit(self) -> _StringAssertion: ...
95
96
  def is_lower(self) -> _StringAssertion: ...
@@ -126,8 +127,8 @@ if TYPE_CHECKING:
126
127
  def zip_satisfies(
127
128
  self, other: Iterable[_Other], predicate: Callable[[str, _Other], object], *, allow_empty: bool = ...
128
129
  ) -> _StringAssertion: ...
129
- def extracting_group(self, pattern: str, group: int | str = ...) -> _StringAssertion: ...
130
- def matches_with_groups(self, pattern: str) -> _StringAssertion: ...
130
+ def extracting_group(self, pattern: str | re.Pattern[str], group: int | str = ...) -> _StringAssertion: ...
131
+ def matches_with_groups(self, pattern: str | re.Pattern[str]) -> _StringAssertion: ...
131
132
  def exists(self) -> _StringAssertion: ...
132
133
  def does_not_exist(self) -> _StringAssertion: ...
133
134
  def is_file(self) -> _StringAssertion: ...
@@ -1492,8 +1493,8 @@ if TYPE_CHECKING:
1492
1493
  def starts_with_ignoring_case(self, prefix: str) -> _WarnedAssertion[_P_co]: ...
1493
1494
  def ends_with(self, suffix: str) -> _WarnedAssertion[_P_co]: ...
1494
1495
  def ends_with_ignoring_case(self, suffix: str) -> _WarnedAssertion[_P_co]: ...
1495
- def matches(self, pattern: str) -> _WarnedAssertion[_P_co]: ...
1496
- def does_not_match(self, pattern: str) -> _WarnedAssertion[_P_co]: ...
1496
+ def matches(self, pattern: str | re.Pattern[str]) -> _WarnedAssertion[_P_co]: ...
1497
+ def does_not_match(self, pattern: str | re.Pattern[str]) -> _WarnedAssertion[_P_co]: ...
1497
1498
  def is_alpha(self) -> _WarnedAssertion[_P_co]: ...
1498
1499
  def is_digit(self) -> _WarnedAssertion[_P_co]: ...
1499
1500
  def is_lower(self) -> _WarnedAssertion[_P_co]: ...
@@ -1530,8 +1531,10 @@ if TYPE_CHECKING:
1530
1531
  def zip_satisfies(
1531
1532
  self, other: Iterable[_Other], predicate: Callable[[str, _Other], object], *, allow_empty: bool = ...
1532
1533
  ) -> _WarnedAssertion[_P_co]: ...
1533
- def extracting_group(self, pattern: str, group: int | str = ...) -> _WarnedAssertion[_P_co]: ...
1534
- def matches_with_groups(self, pattern: str) -> _WarnedAssertion[_P_co]: ...
1534
+ def extracting_group(
1535
+ self, pattern: str | re.Pattern[str], group: int | str = ...
1536
+ ) -> _WarnedAssertion[_P_co]: ...
1537
+ def matches_with_groups(self, pattern: str | re.Pattern[str]) -> _WarnedAssertion[_P_co]: ...
1535
1538
  def is_subset_of(self, *supersets: object, allow_empty: bool = ...) -> _WarnedAssertion[_P_co]: ...
1536
1539
  def contains_duplicates(self) -> _WarnedAssertion[_P_co]: ...
1537
1540
  def does_not_contain_duplicates(self) -> _WarnedAssertion[_P_co]: ...
@@ -1724,8 +1727,8 @@ if TYPE_CHECKING:
1724
1727
  def starts_with_ignoring_case(self, prefix: str) -> _TextAssertion: ...
1725
1728
  def ends_with(self, suffix: str) -> _TextAssertion: ...
1726
1729
  def ends_with_ignoring_case(self, suffix: str) -> _TextAssertion: ...
1727
- def matches(self, pattern: str) -> _TextAssertion: ...
1728
- def does_not_match(self, pattern: str) -> _TextAssertion: ...
1730
+ def matches(self, pattern: str | re.Pattern[str]) -> _TextAssertion: ...
1731
+ def does_not_match(self, pattern: str | re.Pattern[str]) -> _TextAssertion: ...
1729
1732
  def is_alpha(self) -> _TextAssertion: ...
1730
1733
  def is_digit(self) -> _TextAssertion: ...
1731
1734
  def is_lower(self) -> _TextAssertion: ...
@@ -1762,8 +1765,8 @@ if TYPE_CHECKING:
1762
1765
  def zip_satisfies(
1763
1766
  self, other: Iterable[_Other], predicate: Callable[[str, _Other], object], *, allow_empty: bool = ...
1764
1767
  ) -> _TextAssertion: ...
1765
- def extracting_group(self, pattern: str, group: int | str = ...) -> _TextAssertion: ...
1766
- def matches_with_groups(self, pattern: str) -> _TextAssertion: ...
1768
+ def extracting_group(self, pattern: str | re.Pattern[str], group: int | str = ...) -> _TextAssertion: ...
1769
+ def matches_with_groups(self, pattern: str | re.Pattern[str]) -> _TextAssertion: ...
1767
1770
  def is_subset_of(self, *supersets: object, allow_empty: bool = ...) -> _TextAssertion: ...
1768
1771
  def contains_duplicates(self) -> _TextAssertion: ...
1769
1772
  def does_not_contain_duplicates(self) -> _TextAssertion: ...
@@ -1981,8 +1984,8 @@ if TYPE_CHECKING:
1981
1984
  def starts_with_ignoring_case(self, prefix: str) -> _InvokedAssertion[_Exc]: ...
1982
1985
  def ends_with(self, suffix: str) -> _InvokedAssertion[_Exc]: ...
1983
1986
  def ends_with_ignoring_case(self, suffix: str) -> _InvokedAssertion[_Exc]: ...
1984
- def matches(self, pattern: str) -> _InvokedAssertion[_Exc]: ...
1985
- def does_not_match(self, pattern: str) -> _InvokedAssertion[_Exc]: ...
1987
+ def matches(self, pattern: str | re.Pattern[str]) -> _InvokedAssertion[_Exc]: ...
1988
+ def does_not_match(self, pattern: str | re.Pattern[str]) -> _InvokedAssertion[_Exc]: ...
1986
1989
  def is_alpha(self) -> _InvokedAssertion[_Exc]: ...
1987
1990
  def is_digit(self) -> _InvokedAssertion[_Exc]: ...
1988
1991
  def is_lower(self) -> _InvokedAssertion[_Exc]: ...
@@ -2019,8 +2022,10 @@ if TYPE_CHECKING:
2019
2022
  def zip_satisfies(
2020
2023
  self, other: Iterable[_Other], predicate: Callable[[str, _Other], object], *, allow_empty: bool = ...
2021
2024
  ) -> _InvokedAssertion[_Exc]: ...
2022
- def extracting_group(self, pattern: str, group: int | str = ...) -> _InvokedAssertion[_Exc]: ...
2023
- def matches_with_groups(self, pattern: str) -> _InvokedAssertion[_Exc]: ...
2025
+ def extracting_group(
2026
+ self, pattern: str | re.Pattern[str], group: int | str = ...
2027
+ ) -> _InvokedAssertion[_Exc]: ...
2028
+ def matches_with_groups(self, pattern: str | re.Pattern[str]) -> _InvokedAssertion[_Exc]: ...
2024
2029
  def is_subset_of(self, *supersets: object, allow_empty: bool = ...) -> _InvokedAssertion[_Exc]: ...
2025
2030
  def contains_duplicates(self) -> _InvokedAssertion[_Exc]: ...
2026
2031
  def does_not_contain_duplicates(self) -> _InvokedAssertion[_Exc]: ...
@@ -31,6 +31,7 @@ from typing import TYPE_CHECKING
31
31
  if TYPE_CHECKING:
32
32
  import datetime
33
33
  import pathlib
34
+ import re
34
35
  from collections.abc import Callable, Generator, Hashable, Iterable, Mapping, Sized
35
36
  from pathlib import Path
36
37
  from typing import Any, Protocol, SupportsFloat, SupportsIndex, TypeVar, overload
@@ -263,9 +264,9 @@ if TYPE_CHECKING:
263
264
 
264
265
  def ends_with_ignoring_case(self: _SyncPoll[str], suffix: str) -> _SyncPoll[_P_co]: ...
265
266
 
266
- def matches(self: _SyncPoll[str], pattern: str) -> _SyncPoll[_P_co]: ...
267
+ def matches(self: _SyncPoll[str], pattern: str | re.Pattern[str]) -> _SyncPoll[_P_co]: ...
267
268
 
268
- def does_not_match(self: _SyncPoll[str], pattern: str) -> _SyncPoll[_P_co]: ...
269
+ def does_not_match(self: _SyncPoll[str], pattern: str | re.Pattern[str]) -> _SyncPoll[_P_co]: ...
269
270
 
270
271
  def is_alpha(self: _SyncPoll[str]) -> _SyncPoll[_P_co]: ...
271
272
 
@@ -687,9 +688,11 @@ if TYPE_CHECKING:
687
688
  @overload
688
689
  def flat_mapped(self: _SyncPoll[_CapableT], func: Callable[[str], Iterable[_R]]) -> _SyncPoll[Any]: ...
689
690
 
690
- def extracting_group(self: _SyncPoll[str], pattern: str, group: int | str = ...) -> _SyncPoll[_P_co]: ...
691
+ def extracting_group(
692
+ self: _SyncPoll[str], pattern: str | re.Pattern[str], group: int | str = ...
693
+ ) -> _SyncPoll[_P_co]: ...
691
694
 
692
- def matches_with_groups(self: _SyncPoll[str], pattern: str) -> _SyncPoll[Any]: ...
695
+ def matches_with_groups(self: _SyncPoll[str], pattern: str | re.Pattern[str]) -> _SyncPoll[Any]: ...
693
696
 
694
697
  @overload
695
698
  def exists(self: _SyncPoll[str] | _SyncPoll[pathlib.Path]) -> _SyncPoll[_P_co]: ...
@@ -1621,9 +1624,9 @@ if TYPE_CHECKING:
1621
1624
 
1622
1625
  def ends_with_ignoring_case(self: _NegatedSyncPoll[str], suffix: str) -> _SyncPoll[_P_co]: ...
1623
1626
 
1624
- def matches(self: _NegatedSyncPoll[str], pattern: str) -> _SyncPoll[_P_co]: ...
1627
+ def matches(self: _NegatedSyncPoll[str], pattern: str | re.Pattern[str]) -> _SyncPoll[_P_co]: ...
1625
1628
 
1626
- def does_not_match(self: _NegatedSyncPoll[str], pattern: str) -> _SyncPoll[_P_co]: ...
1629
+ def does_not_match(self: _NegatedSyncPoll[str], pattern: str | re.Pattern[str]) -> _SyncPoll[_P_co]: ...
1627
1630
 
1628
1631
  def is_alpha(self: _NegatedSyncPoll[str]) -> _SyncPoll[_P_co]: ...
1629
1632
 
@@ -2047,9 +2050,11 @@ if TYPE_CHECKING:
2047
2050
  allow_empty: bool = ...,
2048
2051
  ) -> _SyncPoll[_P_co]: ...
2049
2052
 
2050
- def extracting_group(self: _NegatedSyncPoll[str], pattern: str, group: int | str = ...) -> _SyncPoll[_P_co]: ...
2053
+ def extracting_group(
2054
+ self: _NegatedSyncPoll[str], pattern: str | re.Pattern[str], group: int | str = ...
2055
+ ) -> _SyncPoll[_P_co]: ...
2051
2056
 
2052
- def matches_with_groups(self: _NegatedSyncPoll[str], pattern: str) -> _SyncPoll[_P_co]: ...
2057
+ def matches_with_groups(self: _NegatedSyncPoll[str], pattern: str | re.Pattern[str]) -> _SyncPoll[_P_co]: ...
2053
2058
 
2054
2059
  @overload
2055
2060
  def exists(self: _NegatedSyncPoll[str] | _NegatedSyncPoll[pathlib.Path]) -> _SyncPoll[_P_co]: ...
@@ -2975,9 +2980,9 @@ if TYPE_CHECKING:
2975
2980
 
2976
2981
  def ends_with_ignoring_case(self: _AsyncPoll[str], suffix: str) -> _AsyncPoll[_P_co]: ...
2977
2982
 
2978
- def matches(self: _AsyncPoll[str], pattern: str) -> _AsyncPoll[_P_co]: ...
2983
+ def matches(self: _AsyncPoll[str], pattern: str | re.Pattern[str]) -> _AsyncPoll[_P_co]: ...
2979
2984
 
2980
- def does_not_match(self: _AsyncPoll[str], pattern: str) -> _AsyncPoll[_P_co]: ...
2985
+ def does_not_match(self: _AsyncPoll[str], pattern: str | re.Pattern[str]) -> _AsyncPoll[_P_co]: ...
2981
2986
 
2982
2987
  def is_alpha(self: _AsyncPoll[str]) -> _AsyncPoll[_P_co]: ...
2983
2988
 
@@ -3411,9 +3416,11 @@ if TYPE_CHECKING:
3411
3416
  @overload
3412
3417
  def flat_mapped(self: _AsyncPoll[_CapableT], func: Callable[[str], Iterable[_R]]) -> _AsyncPoll[Any]: ...
3413
3418
 
3414
- def extracting_group(self: _AsyncPoll[str], pattern: str, group: int | str = ...) -> _AsyncPoll[_P_co]: ...
3419
+ def extracting_group(
3420
+ self: _AsyncPoll[str], pattern: str | re.Pattern[str], group: int | str = ...
3421
+ ) -> _AsyncPoll[_P_co]: ...
3415
3422
 
3416
- def matches_with_groups(self: _AsyncPoll[str], pattern: str) -> _AsyncPoll[Any]: ...
3423
+ def matches_with_groups(self: _AsyncPoll[str], pattern: str | re.Pattern[str]) -> _AsyncPoll[Any]: ...
3417
3424
 
3418
3425
  @overload
3419
3426
  def exists(self: _AsyncPoll[str] | _AsyncPoll[pathlib.Path]) -> _AsyncPoll[_P_co]: ...
@@ -4336,9 +4343,9 @@ if TYPE_CHECKING:
4336
4343
 
4337
4344
  def ends_with_ignoring_case(self: _NegatedAsyncPoll[str], suffix: str) -> _AsyncPoll[_P_co]: ...
4338
4345
 
4339
- def matches(self: _NegatedAsyncPoll[str], pattern: str) -> _AsyncPoll[_P_co]: ...
4346
+ def matches(self: _NegatedAsyncPoll[str], pattern: str | re.Pattern[str]) -> _AsyncPoll[_P_co]: ...
4340
4347
 
4341
- def does_not_match(self: _NegatedAsyncPoll[str], pattern: str) -> _AsyncPoll[_P_co]: ...
4348
+ def does_not_match(self: _NegatedAsyncPoll[str], pattern: str | re.Pattern[str]) -> _AsyncPoll[_P_co]: ...
4342
4349
 
4343
4350
  def is_alpha(self: _NegatedAsyncPoll[str]) -> _AsyncPoll[_P_co]: ...
4344
4351
 
@@ -4763,10 +4770,10 @@ if TYPE_CHECKING:
4763
4770
  ) -> _AsyncPoll[_P_co]: ...
4764
4771
 
4765
4772
  def extracting_group(
4766
- self: _NegatedAsyncPoll[str], pattern: str, group: int | str = ...
4773
+ self: _NegatedAsyncPoll[str], pattern: str | re.Pattern[str], group: int | str = ...
4767
4774
  ) -> _AsyncPoll[_P_co]: ...
4768
4775
 
4769
- def matches_with_groups(self: _NegatedAsyncPoll[str], pattern: str) -> _AsyncPoll[_P_co]: ...
4776
+ def matches_with_groups(self: _NegatedAsyncPoll[str], pattern: str | re.Pattern[str]) -> _AsyncPoll[_P_co]: ...
4770
4777
 
4771
4778
  @overload
4772
4779
  def exists(self: _NegatedAsyncPoll[str] | _NegatedAsyncPoll[pathlib.Path]) -> _AsyncPoll[_P_co]: ...
@@ -27,6 +27,7 @@ import decimal
27
27
  import difflib
28
28
  import functools
29
29
  import inspect
30
+ import re
30
31
  import types
31
32
  from typing import Any, Final, NoReturn, TypeVar
32
33
 
@@ -173,6 +174,22 @@ def argument(name: str) -> str:
173
174
  return f"given {name} arg"
174
175
 
175
176
 
177
+ def require_pattern(pattern: object) -> re.Pattern[str]:
178
+ """*pattern* compiled, refused unless it is a string or a pattern compiled from one, and not empty.
179
+
180
+ A pattern compiled from bytes is never found in a string, and an empty one is found in every string. A
181
+ string goes through ``re.compile`` and its cache, as ``re.search`` would take it. A compiled one comes back
182
+ as it is, flags and all.
183
+ """
184
+ text = pattern.pattern if isinstance(pattern, re.Pattern) else pattern
185
+ if not isinstance(text, str):
186
+ refuse(pattern, "a string or a pattern compiled from one", subject=argument("pattern"))
187
+ if len(text) == 0:
188
+ _assertpy2_refusal = True
189
+ raise ValueError("given pattern arg must not be empty")
190
+ return pattern if isinstance(pattern, re.Pattern) else re.compile(text)
191
+
192
+
176
193
  def sized_len(value: object, *, subject: str = "val") -> int:
177
194
  """The length of *value*, refusing it in the shared shape when it has none.
178
195
 
@@ -22,6 +22,7 @@ from typing import TYPE_CHECKING
22
22
 
23
23
  if TYPE_CHECKING:
24
24
  import datetime
25
+ import re
25
26
  from collections.abc import Awaitable, Callable, Hashable, Iterable, Mapping, Sized
26
27
  from pathlib import Path
27
28
  from typing import Any, ClassVar, Protocol, SupportsFloat, SupportsIndex, TypeVar, overload
@@ -579,8 +580,8 @@ if TYPE_CHECKING:
579
580
  def starts_with_ignoring_case(self, prefix: str) -> Self: ...
580
581
  def ends_with(self, suffix: str) -> Self: ...
581
582
  def ends_with_ignoring_case(self, suffix: str) -> Self: ...
582
- def matches(self, pattern: str) -> Self: ...
583
- def does_not_match(self, pattern: str) -> Self: ...
583
+ def matches(self, pattern: str | re.Pattern[str]) -> Self: ...
584
+ def does_not_match(self, pattern: str | re.Pattern[str]) -> Self: ...
584
585
  def is_alpha(self) -> Self: ...
585
586
  def is_digit(self) -> Self: ...
586
587
  def is_lower(self) -> Self: ...
@@ -621,9 +622,9 @@ if TYPE_CHECKING:
621
622
  def last(self) -> _TextAssertion: ...
622
623
  def element(self, index: SupportsIndex) -> _TextAssertion: ...
623
624
  def single(self) -> _TextAssertion: ...
624
- def extracting_group(self, pattern: str, group: int | str = ...) -> Self: ...
625
+ def extracting_group(self, pattern: str | re.Pattern[str], group: int | str = ...) -> Self: ...
625
626
  # which of the two a pattern yields cannot be known statically
626
- def matches_with_groups(self, pattern: str) -> AssertionBuilder[Any]: ...
627
+ def matches_with_groups(self, pattern: str | re.Pattern[str]) -> AssertionBuilder[Any]: ...
627
628
 
628
629
  class _StringAssertion(_TextAssertion, _FilesystemAssertion, Protocol):
629
630
  """Assertions available for ``str`` values.
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import functools
4
- import re
5
4
  import sys
6
5
  import uuid as _uuid_mod
7
6
  from dataclasses import dataclass
@@ -86,6 +85,7 @@ from ._engine._require import (
86
85
  raised_on_purpose,
87
86
  refuse,
88
87
  reject_unknown_kwargs,
88
+ require_pattern,
89
89
  verdict,
90
90
  )
91
91
  from ._engine._size import length_of
@@ -96,6 +96,7 @@ from ._hints import matcher_for_a_class, type_beside_a_class
96
96
  from .errors import _capped, _capped_format, _capped_repr, _safe_repr, _told_apart, _type_expression_name
97
97
 
98
98
  if TYPE_CHECKING:
99
+ import re
99
100
  from collections.abc import Callable
100
101
  from typing import TypeAlias
101
102
 
@@ -1106,13 +1107,10 @@ _TEXTS = (str, bytes, bytearray)
1106
1107
 
1107
1108
 
1108
1109
  class MatchesRegexMatcher(BaseMatcher):
1109
- def __init__(self, pattern: str):
1110
- # asked here: through the helper a build cost 50% more
1111
- if (type(pattern) is str or issubclass(type(pattern), _TEXTS)) and len(pattern) == 0:
1112
- _refuse_empty("pattern")
1110
+ def __init__(self, pattern: str | re.Pattern[str]):
1113
1111
  self.pattern = pattern
1114
1112
  # compiled eagerly so an invalid pattern raises at the call site, not inside `matches()` or a combinator
1115
- self._compiled = re.compile(pattern)
1113
+ self._compiled = require_pattern(pattern)
1116
1114
 
1117
1115
  def matches(self, value: Any) -> bool:
1118
1116
  if not isinstance(value, str):
@@ -111,7 +111,7 @@ from .snapshot import SnapshotMixin
111
111
  from .string import StringMixin
112
112
  from .warning import WarningMixin
113
113
 
114
- __version__ = "2.31.0"
114
+ __version__ = "2.32.0"
115
115
 
116
116
  # the tracked value type of the generic AssertionBuilder fallback (_U appears only in narrowing stubs)
117
117
  _T = TypeVar("_T")
@@ -69,6 +69,7 @@ from ._matcher_impls import (
69
69
  )
70
70
 
71
71
  if TYPE_CHECKING:
72
+ import re
72
73
  from collections.abc import Callable, Iterable
73
74
 
74
75
  # the element a membership matcher judges, so `match.contains("x")` is a matcher for collections of strings
@@ -460,8 +461,8 @@ class _MatchNamespace:
460
461
  return ContainsStringMatcher(substring)
461
462
 
462
463
  @staticmethod
463
- def matches_regex(pattern: str) -> Matcher[str]:
464
- """Matcher for a string in which ``pattern`` is found (``re.search``)."""
464
+ def matches_regex(pattern: str | re.Pattern[str]) -> Matcher[str]:
465
+ """Matcher for a string in which ``pattern`` (a string, or compiled from one) is found (``re.search``)."""
465
466
  return MatchesRegexMatcher(pattern)
466
467
 
467
468
  @staticmethod