crosshair-tool 0.0.99__cp312-cp312-macosx_10_13_x86_64.whl

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 (176) hide show
  1. _crosshair_tracers.cpython-312-darwin.so +0 -0
  2. crosshair/__init__.py +42 -0
  3. crosshair/__main__.py +8 -0
  4. crosshair/_mark_stacks.h +790 -0
  5. crosshair/_preliminaries_test.py +18 -0
  6. crosshair/_tracers.h +94 -0
  7. crosshair/_tracers_pycompat.h +522 -0
  8. crosshair/_tracers_test.py +138 -0
  9. crosshair/abcstring.py +245 -0
  10. crosshair/auditwall.py +190 -0
  11. crosshair/auditwall_test.py +77 -0
  12. crosshair/codeconfig.py +113 -0
  13. crosshair/codeconfig_test.py +117 -0
  14. crosshair/condition_parser.py +1237 -0
  15. crosshair/condition_parser_test.py +497 -0
  16. crosshair/conftest.py +30 -0
  17. crosshair/copyext.py +155 -0
  18. crosshair/copyext_test.py +84 -0
  19. crosshair/core.py +1763 -0
  20. crosshair/core_and_libs.py +149 -0
  21. crosshair/core_regestered_types_test.py +82 -0
  22. crosshair/core_test.py +1316 -0
  23. crosshair/diff_behavior.py +314 -0
  24. crosshair/diff_behavior_test.py +261 -0
  25. crosshair/dynamic_typing.py +346 -0
  26. crosshair/dynamic_typing_test.py +210 -0
  27. crosshair/enforce.py +282 -0
  28. crosshair/enforce_test.py +182 -0
  29. crosshair/examples/PEP316/__init__.py +1 -0
  30. crosshair/examples/PEP316/bugs_detected/__init__.py +0 -0
  31. crosshair/examples/PEP316/bugs_detected/getattr_magic.py +16 -0
  32. crosshair/examples/PEP316/bugs_detected/hash_consistent_with_equals.py +31 -0
  33. crosshair/examples/PEP316/bugs_detected/shopping_cart.py +24 -0
  34. crosshair/examples/PEP316/bugs_detected/showcase.py +39 -0
  35. crosshair/examples/PEP316/correct_code/__init__.py +0 -0
  36. crosshair/examples/PEP316/correct_code/arith.py +60 -0
  37. crosshair/examples/PEP316/correct_code/chess.py +77 -0
  38. crosshair/examples/PEP316/correct_code/nesting_inference.py +17 -0
  39. crosshair/examples/PEP316/correct_code/numpy_examples.py +132 -0
  40. crosshair/examples/PEP316/correct_code/rolling_average.py +35 -0
  41. crosshair/examples/PEP316/correct_code/showcase.py +104 -0
  42. crosshair/examples/__init__.py +0 -0
  43. crosshair/examples/check_examples_test.py +146 -0
  44. crosshair/examples/deal/__init__.py +1 -0
  45. crosshair/examples/icontract/__init__.py +1 -0
  46. crosshair/examples/icontract/bugs_detected/__init__.py +0 -0
  47. crosshair/examples/icontract/bugs_detected/showcase.py +41 -0
  48. crosshair/examples/icontract/bugs_detected/wrong_sign.py +8 -0
  49. crosshair/examples/icontract/correct_code/__init__.py +0 -0
  50. crosshair/examples/icontract/correct_code/arith.py +51 -0
  51. crosshair/examples/icontract/correct_code/showcase.py +94 -0
  52. crosshair/fnutil.py +391 -0
  53. crosshair/fnutil_test.py +75 -0
  54. crosshair/fuzz_core_test.py +516 -0
  55. crosshair/libimpl/__init__.py +0 -0
  56. crosshair/libimpl/arraylib.py +161 -0
  57. crosshair/libimpl/binascii_ch_test.py +30 -0
  58. crosshair/libimpl/binascii_test.py +67 -0
  59. crosshair/libimpl/binasciilib.py +150 -0
  60. crosshair/libimpl/bisectlib_test.py +23 -0
  61. crosshair/libimpl/builtinslib.py +5228 -0
  62. crosshair/libimpl/builtinslib_ch_test.py +1191 -0
  63. crosshair/libimpl/builtinslib_test.py +3735 -0
  64. crosshair/libimpl/codecslib.py +86 -0
  65. crosshair/libimpl/codecslib_test.py +86 -0
  66. crosshair/libimpl/collectionslib.py +264 -0
  67. crosshair/libimpl/collectionslib_ch_test.py +252 -0
  68. crosshair/libimpl/collectionslib_test.py +332 -0
  69. crosshair/libimpl/copylib.py +23 -0
  70. crosshair/libimpl/copylib_test.py +18 -0
  71. crosshair/libimpl/datetimelib.py +2559 -0
  72. crosshair/libimpl/datetimelib_ch_test.py +354 -0
  73. crosshair/libimpl/datetimelib_test.py +112 -0
  74. crosshair/libimpl/decimallib.py +5257 -0
  75. crosshair/libimpl/decimallib_ch_test.py +78 -0
  76. crosshair/libimpl/decimallib_test.py +76 -0
  77. crosshair/libimpl/encodings/__init__.py +23 -0
  78. crosshair/libimpl/encodings/_encutil.py +187 -0
  79. crosshair/libimpl/encodings/ascii.py +44 -0
  80. crosshair/libimpl/encodings/latin_1.py +40 -0
  81. crosshair/libimpl/encodings/utf_8.py +93 -0
  82. crosshair/libimpl/encodings_ch_test.py +83 -0
  83. crosshair/libimpl/fractionlib.py +16 -0
  84. crosshair/libimpl/fractionlib_test.py +80 -0
  85. crosshair/libimpl/functoolslib.py +34 -0
  86. crosshair/libimpl/functoolslib_test.py +56 -0
  87. crosshair/libimpl/hashliblib.py +30 -0
  88. crosshair/libimpl/hashliblib_test.py +18 -0
  89. crosshair/libimpl/heapqlib.py +47 -0
  90. crosshair/libimpl/heapqlib_test.py +21 -0
  91. crosshair/libimpl/importliblib.py +18 -0
  92. crosshair/libimpl/importliblib_test.py +38 -0
  93. crosshair/libimpl/iolib.py +216 -0
  94. crosshair/libimpl/iolib_ch_test.py +128 -0
  95. crosshair/libimpl/iolib_test.py +19 -0
  96. crosshair/libimpl/ipaddresslib.py +8 -0
  97. crosshair/libimpl/itertoolslib.py +44 -0
  98. crosshair/libimpl/itertoolslib_test.py +44 -0
  99. crosshair/libimpl/jsonlib.py +984 -0
  100. crosshair/libimpl/jsonlib_ch_test.py +42 -0
  101. crosshair/libimpl/jsonlib_test.py +51 -0
  102. crosshair/libimpl/mathlib.py +179 -0
  103. crosshair/libimpl/mathlib_ch_test.py +44 -0
  104. crosshair/libimpl/mathlib_test.py +67 -0
  105. crosshair/libimpl/oslib.py +7 -0
  106. crosshair/libimpl/pathliblib_test.py +10 -0
  107. crosshair/libimpl/randomlib.py +178 -0
  108. crosshair/libimpl/randomlib_test.py +120 -0
  109. crosshair/libimpl/relib.py +846 -0
  110. crosshair/libimpl/relib_ch_test.py +169 -0
  111. crosshair/libimpl/relib_test.py +493 -0
  112. crosshair/libimpl/timelib.py +72 -0
  113. crosshair/libimpl/timelib_test.py +82 -0
  114. crosshair/libimpl/typeslib.py +15 -0
  115. crosshair/libimpl/typeslib_test.py +36 -0
  116. crosshair/libimpl/unicodedatalib.py +75 -0
  117. crosshair/libimpl/unicodedatalib_test.py +42 -0
  118. crosshair/libimpl/urlliblib.py +23 -0
  119. crosshair/libimpl/urlliblib_test.py +19 -0
  120. crosshair/libimpl/weakreflib.py +13 -0
  121. crosshair/libimpl/weakreflib_test.py +69 -0
  122. crosshair/libimpl/zliblib.py +15 -0
  123. crosshair/libimpl/zliblib_test.py +13 -0
  124. crosshair/lsp_server.py +261 -0
  125. crosshair/lsp_server_test.py +30 -0
  126. crosshair/main.py +973 -0
  127. crosshair/main_test.py +543 -0
  128. crosshair/objectproxy.py +376 -0
  129. crosshair/objectproxy_test.py +41 -0
  130. crosshair/opcode_intercept.py +601 -0
  131. crosshair/opcode_intercept_test.py +304 -0
  132. crosshair/options.py +218 -0
  133. crosshair/options_test.py +10 -0
  134. crosshair/patch_equivalence_test.py +75 -0
  135. crosshair/path_cover.py +209 -0
  136. crosshair/path_cover_test.py +138 -0
  137. crosshair/path_search.py +161 -0
  138. crosshair/path_search_test.py +52 -0
  139. crosshair/pathing_oracle.py +271 -0
  140. crosshair/pathing_oracle_test.py +21 -0
  141. crosshair/pure_importer.py +27 -0
  142. crosshair/pure_importer_test.py +16 -0
  143. crosshair/py.typed +0 -0
  144. crosshair/register_contract.py +273 -0
  145. crosshair/register_contract_test.py +190 -0
  146. crosshair/simplestructs.py +1165 -0
  147. crosshair/simplestructs_test.py +283 -0
  148. crosshair/smtlib.py +24 -0
  149. crosshair/smtlib_test.py +14 -0
  150. crosshair/statespace.py +1199 -0
  151. crosshair/statespace_test.py +108 -0
  152. crosshair/stubs_parser.py +352 -0
  153. crosshair/stubs_parser_test.py +43 -0
  154. crosshair/test_util.py +329 -0
  155. crosshair/test_util_test.py +26 -0
  156. crosshair/tools/__init__.py +0 -0
  157. crosshair/tools/check_help_in_doc.py +264 -0
  158. crosshair/tools/check_init_and_setup_coincide.py +119 -0
  159. crosshair/tools/generate_demo_table.py +127 -0
  160. crosshair/tracers.py +544 -0
  161. crosshair/tracers_test.py +154 -0
  162. crosshair/type_repo.py +151 -0
  163. crosshair/unicode_categories.py +589 -0
  164. crosshair/unicode_categories_test.py +27 -0
  165. crosshair/util.py +741 -0
  166. crosshair/util_test.py +173 -0
  167. crosshair/watcher.py +307 -0
  168. crosshair/watcher_test.py +107 -0
  169. crosshair/z3util.py +76 -0
  170. crosshair/z3util_test.py +11 -0
  171. crosshair_tool-0.0.99.dist-info/METADATA +144 -0
  172. crosshair_tool-0.0.99.dist-info/RECORD +176 -0
  173. crosshair_tool-0.0.99.dist-info/WHEEL +6 -0
  174. crosshair_tool-0.0.99.dist-info/entry_points.txt +3 -0
  175. crosshair_tool-0.0.99.dist-info/licenses/LICENSE +93 -0
  176. crosshair_tool-0.0.99.dist-info/top_level.txt +2 -0
@@ -0,0 +1,1191 @@
1
+ import operator
2
+ import sys
3
+ from math import isnan
4
+ from numbers import Integral
5
+ from typing import (
6
+ Any,
7
+ Callable,
8
+ Dict,
9
+ FrozenSet,
10
+ List,
11
+ Mapping,
12
+ Optional,
13
+ Sequence,
14
+ Set,
15
+ Tuple,
16
+ Union,
17
+ )
18
+
19
+ import pytest # type: ignore
20
+
21
+ from crosshair.core import realize
22
+ from crosshair.core_and_libs import MessageType, analyze_function, run_checkables
23
+ from crosshair.test_util import ResultComparison, compare_results, compare_returns
24
+
25
+ _TRICKY_UNICODE = (
26
+ "A\u01f2", # upper followed by title cased character
27
+ "\ua770", # Lm, lower (superscript "9")
28
+ "\u01f2", # Lt, title-cased but not upper (compound "Dz" like char)
29
+ "\u2165", # Nl (roman numeral "VI")
30
+ )
31
+
32
+
33
+ def check_abs(x: Union[int, bool, float]) -> ResultComparison:
34
+ """post: _"""
35
+ return compare_returns(abs, x)
36
+
37
+
38
+ def check_ascii(x: object) -> ResultComparison:
39
+ """post: _"""
40
+ return compare_results(ascii, x)
41
+
42
+
43
+ def check_bin(x: Integral) -> ResultComparison:
44
+ """post: _"""
45
+ return compare_results(bin, x)
46
+
47
+
48
+ def check_callable(x: object) -> ResultComparison:
49
+ """post: _"""
50
+ return compare_results(callable, x)
51
+
52
+
53
+ def check_chr(x: int) -> ResultComparison:
54
+ """post: _"""
55
+ return compare_results(chr, x)
56
+
57
+
58
+ # NOTE: dir() is not expected to be compatible.
59
+
60
+ _NAN_SENTINAL: Tuple = tuple()
61
+ # (anything that is copyable and compares equal with itself)
62
+
63
+
64
+ def check_divmod(
65
+ numerator: Union[int, float], denominator: Union[int, float]
66
+ ) -> ResultComparison:
67
+ """post: _"""
68
+ if numerator == 0 or denominator == 0:
69
+ pass
70
+ return compare_returns(
71
+ lambda n, d: [_NAN_SENTINAL if isnan(x) else x for x in divmod(n, d)],
72
+ numerator,
73
+ denominator,
74
+ )
75
+
76
+
77
+ def check_eval(expr: str):
78
+ """
79
+ pre: len(expr) == 1
80
+ post: _
81
+ """
82
+ return compare_results(lambda e: eval(e, {}, {}), expr)
83
+
84
+
85
+ # NOTE: not patching exit()
86
+
87
+ # TODO: this fails; symbolic callables do not have correct behavior for
88
+ # inputs outside their expected domain.
89
+ # def check_filter(f: Callable[[int], bool], l: List[str]):
90
+ # ''' post: _ '''
91
+ # return compare_results(filter, f, l)
92
+
93
+
94
+ def check_float(o: Union[str, int, float]) -> ResultComparison:
95
+ """post: _"""
96
+ # TODO this isn't hitting most of the branches we care about right now.
97
+ return compare_returns(float, o)
98
+
99
+
100
+ def check_float_sub(float_a: float, float_b: float) -> ResultComparison:
101
+ """post: _"""
102
+ return compare_returns(lambda a, b: a - b, float_a, float_b)
103
+
104
+
105
+ def check_format(x: object, f: str) -> ResultComparison:
106
+ """post: _"""
107
+ return compare_results(format, x, f)
108
+
109
+
110
+ # TODO: Add str and other types to check here
111
+ def check_format_dunder(obj: Union[int, float], fmt: str) -> ResultComparison:
112
+ """post: _"""
113
+ if fmt == "03d":
114
+ pass
115
+ elif fmt == "+.3f":
116
+ pass
117
+ # TODO: do not realize `fmt` here- instead we should intercept the native
118
+ # __format__ calls to check for a symbolic format string.
119
+ return compare_returns(lambda o, f: o.__format__(f), obj, realize(fmt))
120
+
121
+
122
+ # CrossHair proxies don't have the same attributes as native:
123
+ # def check_getattr(o: object, n: str, d: object) -> ResultComparison:
124
+
125
+ # NOTE: not patching globals()
126
+
127
+ # CrossHair proxies don't have the same attributes as native:
128
+ # def check_hasattr(o: str, n: str) -> ResultComparison:
129
+
130
+
131
+ def check_hash(o: Union[int, str, bytes, tuple]) -> ResultComparison:
132
+ """post: _"""
133
+ return compare_results(hash, o)
134
+
135
+
136
+ # We test frozenset explicitly because it's trickier:
137
+ def check_frozenset_hash(o: frozenset) -> ResultComparison:
138
+ """post: _"""
139
+ return compare_results(hash, o)
140
+
141
+
142
+ # NOTE: not patching help()
143
+
144
+
145
+ def check_hex(o: int) -> ResultComparison:
146
+ """post: _"""
147
+ return compare_results(hex, o)
148
+
149
+
150
+ # NOTE: not testing id()
151
+ # NOTE: not testing input()
152
+
153
+
154
+ def check_int(o: Union[str, int, float]) -> ResultComparison:
155
+ """post: _"""
156
+ return compare_returns(int, o)
157
+
158
+
159
+ def check_int_with_base(o: str, b: int) -> ResultComparison:
160
+ """post: _"""
161
+ return compare_results(int, o, b)
162
+
163
+
164
+ def check_isinstance(o: object, t: type) -> ResultComparison:
165
+ """post: _"""
166
+ return compare_results(isinstance, o, t)
167
+
168
+
169
+ def check_issubclass(o: object, t: type) -> ResultComparison:
170
+ """post: _"""
171
+ return compare_results(issubclass, o, t)
172
+
173
+
174
+ def check_iter(obj: Union[str, List[int], Dict[int, int]]) -> ResultComparison:
175
+ """post: _"""
176
+ # Note that we don't check Set[int] because of unstable ordering.
177
+ return compare_results(lambda o: list(iter(o)), obj)
178
+
179
+
180
+ def check_len(
181
+ s: Union[Dict[int, int], Tuple[int, ...], str, List[int], Set[int]],
182
+ ) -> ResultComparison:
183
+ """post: _"""
184
+ return compare_results(len, s)
185
+
186
+
187
+ # NOTE: not testing license()
188
+ # NOTE: not testing locals()
189
+
190
+ # TODO: this fails; right now because symbolic callables have a bug that
191
+ # let's them realize inconsistently.
192
+ # def check_map(f: Callable[[int], str], l: List[int]):
193
+ # ''' post: _ '''
194
+ # return compare_results(map, f, l)
195
+
196
+
197
+ def check_max(
198
+ x: Sequence, k: Optional[Callable[[Any], Any]], d: object
199
+ ) -> ResultComparison:
200
+ """post: _"""
201
+ kw = {"default": d}
202
+ if k is not None:
203
+ kw["key"] = k
204
+ return compare_results(max, x, **kw)
205
+
206
+
207
+ def check_min(x: Sequence) -> ResultComparison:
208
+ """post: _"""
209
+ return compare_results(min, x)
210
+
211
+
212
+ # NOTE: not testing next()
213
+
214
+
215
+ def check_oct(x: int) -> ResultComparison:
216
+ """post: _"""
217
+ return compare_results(oct, x)
218
+
219
+
220
+ # NOTE: not testing open()
221
+
222
+
223
+ def check_ord(x: str) -> ResultComparison:
224
+ """post: _"""
225
+ return compare_results(ord, x)
226
+
227
+
228
+ def check_print(o: object) -> ResultComparison:
229
+ """post: _"""
230
+ return compare_results(print, o)
231
+
232
+
233
+ def check_pow_function(
234
+ b: Union[int, float], e: Union[int, float], m: Optional[int]
235
+ ) -> ResultComparison:
236
+ """post: _"""
237
+ # crosshair: max_uninteresting_iterations=150
238
+ # (running this a little longer for various float representations)
239
+ return compare_returns(pow, b, e, m)
240
+
241
+
242
+ def check_pow_operator(b: Union[int, float], e: Union[int, float]) -> ResultComparison:
243
+ """post: _"""
244
+ # crosshair: max_uninteresting_iterations=150
245
+ # (running this a little longer for various float representations)
246
+ return compare_returns(operator.pow, b, e)
247
+
248
+
249
+ # NOTE: not testing quit()
250
+
251
+
252
+ def check_range_len(start: int, stop: int, step: int) -> ResultComparison:
253
+ """post: _"""
254
+ return compare_results(lambda a, o, e: len(range(a, o, e)), start, stop, step)
255
+
256
+
257
+ def check_range_reversed(start: int, stop: int, step: int) -> ResultComparison:
258
+ """post: _"""
259
+ return compare_results(
260
+ lambda a, o, e: list(reversed(range(a, o, e))), start, stop, step
261
+ )
262
+
263
+
264
+ def check_reversed(obj: Union[List[int], Tuple[int]]) -> ResultComparison:
265
+ """post: _"""
266
+ return compare_results(lambda o: list(reversed(o)), obj)
267
+
268
+
269
+ def check_repr(o: object) -> ResultComparison:
270
+ """post: _"""
271
+ return compare_results(repr, o)
272
+
273
+
274
+ def check_round_float(o: float, d: Optional[int]) -> ResultComparison:
275
+ """post: _"""
276
+ return compare_returns(round, o, d)
277
+
278
+
279
+ def check_round_int(o: int, d: Optional[int]) -> ResultComparison:
280
+ """post: _"""
281
+ return compare_results(round, o, d)
282
+
283
+
284
+ # CrossHair proxies don't have the same attributes as native:
285
+ # def check_setattr(o: object, n: str, v: object) -> ResultComparison:
286
+
287
+
288
+ def check_sorted(s: Sequence) -> ResultComparison:
289
+ """post: _"""
290
+ return compare_results(sorted, s)
291
+
292
+
293
+ def check_sum(
294
+ s: Union[Sequence[int], Sequence[float]],
295
+ # i: Union[None, int, float]
296
+ ) -> ResultComparison:
297
+ """post: _"""
298
+ return compare_returns(sum, s)
299
+
300
+
301
+ # NOTE: not testing vars()
302
+
303
+
304
+ def check_zip(s: Sequence[Sequence[int]]) -> ResultComparison:
305
+ """post: _"""
306
+ return compare_results(lambda args: zip(*args), s)
307
+
308
+
309
+ # Check list methods
310
+
311
+
312
+ def check_list_index(
313
+ lst: List[int], item: int, start: int, stop: int
314
+ ) -> ResultComparison:
315
+ """post: _"""
316
+ return compare_results(lambda ln, *a: ln.index(*a), lst, item, start, stop)
317
+
318
+
319
+ def check_list_extend_and_slice(container: Union[List[int], bytearray]):
320
+ """
321
+ pre: len(container) <= 4
322
+ post: _
323
+ """
324
+
325
+ def f(c):
326
+ addition = [1, 2] if isinstance(container, list) else bytearray([1, 2])
327
+ c += addition
328
+ c = c[:3]
329
+ del addition[0] # This mutation hopefully doesn't change the result!
330
+ return (c, type(c))
331
+
332
+ return compare_results(f, container)
333
+
334
+
335
+ def check_list_setitem_slice(container: List[int], key: slice, replacement: List[int]):
336
+ """
337
+ pre: len(container) <= 3 and len(replacement) <= 3
338
+ post: _
339
+ """
340
+ # crosshair: max_iterations=100
341
+
342
+ def f(c, k, r):
343
+ c[k] = r
344
+ r.append(42)
345
+ return c
346
+
347
+ return compare_results(f, container, key, replacement)
348
+
349
+
350
+ # Check dict methods
351
+
352
+
353
+ def check_dict___init__(
354
+ pos_args: List[Tuple[int, int]], kw_args: Dict[str, int]
355
+ ) -> ResultComparison:
356
+ """post: _"""
357
+ return compare_results(lambda a, kw: dict(*a, **kw), pos_args, kw_args)
358
+
359
+
360
+ def check_dict_get(dictionary: Dict[int, int], key: int) -> ResultComparison:
361
+ """post: _"""
362
+ return compare_results(lambda d, k: d.get(k), dictionary, key)
363
+
364
+
365
+ def check_dict_iter(dictionary: Dict[int, int]) -> ResultComparison:
366
+ """post: _"""
367
+ return compare_results(lambda d: list(d), dictionary)
368
+
369
+
370
+ def check_dict_clear(dictionary: Dict[int, int]) -> ResultComparison:
371
+ """post: _"""
372
+
373
+ def checker(d):
374
+ d.clear()
375
+ return d
376
+
377
+ return compare_results(checker, dictionary)
378
+
379
+
380
+ def check_dict_pop(dictionary: Dict[int, int], key: int) -> ResultComparison:
381
+ """post: _"""
382
+
383
+ def checker(d, k):
384
+ x = d.pop(k)
385
+ return (x, d)
386
+
387
+ return compare_results(checker, dictionary, key)
388
+
389
+
390
+ def check_dict_popitem(dictionary: Dict[int, int]) -> ResultComparison:
391
+ """post: _"""
392
+
393
+ def checker(d):
394
+ x = d.popitem()
395
+ return (x, d)
396
+
397
+ return compare_results(checker, dictionary)
398
+
399
+
400
+ def check_dict_update(left: Dict[int, int], right: Dict[int, int]) -> ResultComparison:
401
+ """post: _"""
402
+
403
+ def checker(d1, d2):
404
+ d1.update(d2)
405
+ return d1
406
+
407
+ return compare_results(checker, left, right)
408
+
409
+
410
+ def check_dict_values(dictionary: Dict[int, int]) -> ResultComparison:
411
+ """post: _"""
412
+ # TODO: value views compare false even with new views from the same dict.
413
+ # Ensure we match this behavior.
414
+ return compare_results(lambda d: list(d.values()), dictionary)
415
+
416
+
417
+ # check set/frozenset methods
418
+
419
+
420
+ def check_set_eq(setobj: Set[int]) -> ResultComparison:
421
+ """post: _"""
422
+ return compare_results(lambda s: s, setobj)
423
+
424
+
425
+ def check_set_clear(setobj: Set[int]) -> ResultComparison:
426
+ """post: _"""
427
+
428
+ def checker(s):
429
+ s.clear()
430
+ return s
431
+
432
+ return compare_results(checker, setobj)
433
+
434
+
435
+ def check_set_remove(setobj: Set[int], item: int) -> ResultComparison:
436
+ """post: _"""
437
+
438
+ def checker(s, i):
439
+ s.remove(i)
440
+ return realize(s)
441
+
442
+ return compare_results(checker, setobj, item)
443
+
444
+
445
+ def check_set_add(setobj: Set[int], item: int) -> ResultComparison:
446
+ """post: _"""
447
+
448
+ def checker(s, i):
449
+ s.add(i)
450
+ return realize(s)
451
+
452
+ return compare_results(checker, setobj, item)
453
+
454
+
455
+ def check_set_symmetric_difference_update(
456
+ left: Set[int], right: Set[int]
457
+ ) -> ResultComparison:
458
+ """post: _"""
459
+
460
+ def checker(left, right):
461
+ left ^= right
462
+ return sorted(left)
463
+
464
+ return compare_results(checker, left, right)
465
+
466
+
467
+ def check_set_union_sorted(
468
+ left: Union[Set[int], FrozenSet[int]], right: Union[Set[int], FrozenSet[int]]
469
+ ) -> ResultComparison:
470
+ """post: _"""
471
+ # We check union-sorted, because realizing the set contents would suppress duplicates
472
+ return compare_results(lambda lt, r: sorted(lt | r), left, right)
473
+
474
+
475
+ def check_set_difference(
476
+ left: Union[Set[int], FrozenSet[int]], right: Union[Set[int], FrozenSet[int]]
477
+ ) -> ResultComparison:
478
+ """post: _"""
479
+ return compare_results(lambda lt, r: lt - r, left, right)
480
+
481
+
482
+ def check_set_intersection(
483
+ left: Union[Set[int], FrozenSet[int]],
484
+ # unlike operators, named methods (set.intersection) can take iterables:
485
+ right: List[int],
486
+ ) -> ResultComparison:
487
+ """post: _"""
488
+ return compare_results(lambda lt, r: lt.intersection(r), left, right)
489
+
490
+
491
+ def check_set_compare(
492
+ left: Union[Set[int], FrozenSet[int]], right: Union[Set[int], FrozenSet[int]]
493
+ ) -> ResultComparison:
494
+ """
495
+ pre: len(left) + len(right) <= 4
496
+ post: _
497
+ """
498
+ # crosshair: max_uninteresting_iterations=75
499
+ # (running this a little longer - it's been able to detect deepcopy memo
500
+ # keepalive issues in the past)
501
+ return compare_results(lambda lt, r: lt <= r, left, right)
502
+
503
+
504
+ def check_set_bool(setobj: Union[Set[int], FrozenSet[int]]) -> ResultComparison:
505
+ """post: _"""
506
+ return compare_results(lambda s: s, bool(setobj))
507
+
508
+
509
+ def check_seq_concat_and_slice(seq1: List[int], seq2: List[int], slc: slice):
510
+ """post: _"""
511
+ return compare_results(lambda s1, s2, c: (s1 + s2)[c], seq1, seq2, slc)
512
+
513
+
514
+ # Check int methods
515
+
516
+
517
+ if sys.version_info >= (3, 10):
518
+
519
+ def check_int_bit_count(val: int):
520
+ """post: _"""
521
+ realize(val in range(-3, 3))
522
+ return compare_results(lambda v: v.bit_count(), val)
523
+
524
+
525
+ def check_int_bit_length(val: int):
526
+ """post: _"""
527
+ realize(val in range(-3, 3))
528
+ return compare_results(lambda v: v.bit_length(), val)
529
+
530
+
531
+ def check_int_to_bytes(val: int, big: bool, signed: bool):
532
+ """post: _"""
533
+ realize(val == 2**16)
534
+ return compare_results(
535
+ lambda v, b, s: v.to_bytes(2, "big" if b else "little", signed=s),
536
+ val,
537
+ big,
538
+ signed,
539
+ )
540
+
541
+
542
+ # Check string methods
543
+
544
+
545
+ def check_str_getitem_index(string: str, idx: int) -> ResultComparison:
546
+ """post: _"""
547
+ return compare_results(lambda s: s[idx], string)
548
+
549
+
550
+ def check_str_getitem_slice(string: str, start: int, end: int) -> ResultComparison:
551
+ """post: _"""
552
+ return compare_results(lambda s: s[start:end], string)
553
+
554
+
555
+ def check_str_capitalize(string: str) -> ResultComparison:
556
+ """post: _"""
557
+ if string in _TRICKY_UNICODE:
558
+ pass
559
+ return compare_results(lambda s: s.capitalize(), string)
560
+
561
+
562
+ def check_str_casefold(string: str) -> ResultComparison:
563
+ """
564
+ pre: len(string) <= 2
565
+ post: _
566
+ """
567
+ return compare_results(lambda s: s.casefold(), string)
568
+
569
+
570
+ def check_str_center(string: str, size: int, fill: str) -> ResultComparison:
571
+ """post: _"""
572
+ if not string:
573
+ pass
574
+ if len(string) % 2 == 0:
575
+ pass
576
+ if size % 2 == 0:
577
+ pass
578
+ if fill == " ":
579
+ pass
580
+ return compare_results(lambda s, *a: s.center(*a), string, size, fill)
581
+
582
+
583
+ def check_str_contains(needle: str, haystack: str) -> ResultComparison:
584
+ """post: _"""
585
+ return compare_results(lambda n, h: n in h, needle, haystack)
586
+
587
+
588
+ def check_str_contains_against_literal(needle: str) -> ResultComparison:
589
+ """post: _"""
590
+ return compare_results(lambda n: n in "abc", needle)
591
+
592
+
593
+ def check_str_count(
594
+ string: str, sub: str, start: Optional[int], end: Optional[int]
595
+ ) -> ResultComparison:
596
+ """post: _"""
597
+ return compare_results(lambda s, *a: s.count(*a), string, sub, start, end)
598
+
599
+
600
+ def check_str_encode_wild(string: str, encoding: str, errors: str) -> ResultComparison:
601
+ """post: _"""
602
+ return compare_results(lambda s, *a: s.encode(*a), string, encoding, errors)
603
+
604
+
605
+ def check_str_endswith(
606
+ string: str, suffix: str, start: Optional[int], end: Optional[int]
607
+ ) -> ResultComparison:
608
+ """post: _"""
609
+ # crosshair: max_uninteresting_iterations=100
610
+
611
+ for i in (len(string), len(suffix), start, end):
612
+ if i is not None and abs(i) >= 1:
613
+ pass
614
+
615
+ return compare_results(
616
+ lambda s, *a, **kw: s.endswith(*a, **kw), string, suffix, start, end
617
+ )
618
+
619
+
620
+ def check_str_expandtabs(string: str, tabsize: int) -> ResultComparison:
621
+ """post: _"""
622
+ return compare_results(lambda s, *a: s.expandtabs(*a), string, tabsize)
623
+
624
+
625
+ def check_str_find(
626
+ big: str, little: str, start: Optional[int], end: Optional[int]
627
+ ) -> ResultComparison:
628
+ """post: _"""
629
+ return compare_results(lambda s, *a: s.find(*a), big, little, start, end)
630
+
631
+
632
+ def check_str_find_empty(big: str, start: int, end: int):
633
+ """post: _"""
634
+ # Lots of tricky edge cases when searching for an empty string.
635
+ # Target these cases more narrowly.
636
+ if big != "":
637
+ return True
638
+ return compare_results(lambda s, *a: s.find("", *a), big, start, end)
639
+
640
+
641
+ def check_str_fstring(string: str, num: int, lst: List[int]) -> ResultComparison:
642
+ """post: _"""
643
+ return compare_results(lambda s, n, ls: f"{n:02d}{s}{ls!r}", string, num, lst)
644
+
645
+
646
+ def check_str_format(string: str, *args: object, **kwargs: object) -> ResultComparison:
647
+ """post: _"""
648
+ return compare_results(
649
+ lambda s, *a, **kw: s.format(*a, **kw), string, *args, **kwargs
650
+ )
651
+
652
+
653
+ def check_str_format_map(string: str, mapping: Mapping) -> ResultComparison:
654
+ """post: _"""
655
+ return compare_results(lambda s, *a: s.format_map(*a), string, mapping)
656
+
657
+
658
+ def check_str_index(
659
+ string: str, sub: str, start: Optional[int], end: Optional[int]
660
+ ) -> ResultComparison:
661
+ """post: _"""
662
+ return compare_results(lambda s, *a: s.index(*a), string, sub, start, end)
663
+
664
+
665
+ def check_str_isalpha(s: str) -> ResultComparison:
666
+ """post: _"""
667
+ return compare_results(lambda s: s.isalpha(), s)
668
+
669
+
670
+ def check_str_isalnum(string: str) -> ResultComparison:
671
+ """post: _"""
672
+ return compare_results(lambda s: s.isalnum(), string)
673
+
674
+
675
+ def check_str_isascii(string: str) -> ResultComparison:
676
+ """post: _"""
677
+ return compare_results(lambda s: s.isascii(), string)
678
+
679
+
680
+ def check_str_isdecimal(string: str) -> ResultComparison:
681
+ """post: _"""
682
+ return compare_results(lambda s: s.isdecimal(), string)
683
+
684
+
685
+ def check_str_isdigit(string: str) -> ResultComparison:
686
+ """post: _"""
687
+ return compare_results(lambda s: s.isdigit(), string)
688
+
689
+
690
+ def check_str_isidentifier(string: str) -> ResultComparison:
691
+ """post: _"""
692
+ return compare_results(lambda s: s.isidentifier(), string)
693
+
694
+
695
+ def check_str_islower(string: str) -> ResultComparison:
696
+ """post: _"""
697
+ if string in _TRICKY_UNICODE:
698
+ pass
699
+ return compare_results(lambda s: s.islower(), string)
700
+
701
+
702
+ def check_str_isnumeric(string: str) -> ResultComparison:
703
+ """post: _"""
704
+ return compare_results(lambda s: s.isnumeric(), string)
705
+
706
+
707
+ def check_str_isprintable(string: str) -> ResultComparison:
708
+ """post: _"""
709
+ if string in (" ", "\n", "\x01"):
710
+ pass
711
+ return compare_results(lambda s: s.isprintable(), string)
712
+
713
+
714
+ def check_str_isspace(string: str) -> ResultComparison:
715
+ """post: _"""
716
+ return compare_results(lambda s: s.isspace(), string)
717
+
718
+
719
+ def check_str_istitle(string: str) -> ResultComparison:
720
+ """
721
+ pre: len(string) <= 3
722
+ post: _
723
+ """
724
+ if string in _TRICKY_UNICODE:
725
+ pass
726
+ return compare_results(lambda s: s.istitle(), string)
727
+
728
+
729
+ def check_str_isupper(string: str) -> ResultComparison:
730
+ """post: _"""
731
+ if string in _TRICKY_UNICODE:
732
+ pass
733
+ return compare_results(lambda s: s.isupper(), string)
734
+
735
+
736
+ def check_str_join(string: str, seq: Sequence[str]) -> ResultComparison:
737
+ """post: _"""
738
+ return compare_results(lambda s, *a: s.join(*a), string, seq)
739
+
740
+
741
+ def check_str_ljust(string: str, width: int, fill: str) -> ResultComparison:
742
+ """post: _"""
743
+ return compare_results(lambda s, *a: s.ljust(*a), string, width, fill)
744
+
745
+
746
+ def check_str_lower(string: str) -> ResultComparison:
747
+ """
748
+ pre: len(string) <= 2
749
+ post: _
750
+ """
751
+ return compare_results(lambda s, *a: s.lower(*a), string)
752
+
753
+
754
+ def check_str_lstrip(string: str, chars: str) -> ResultComparison:
755
+ """post: _"""
756
+ return compare_results(lambda s, *a: s.lstrip(*a), string, chars)
757
+
758
+
759
+ def check_str_partition(string: str, sep: str) -> ResultComparison:
760
+ """post: _"""
761
+ return compare_results(lambda s, *a: s.partition(*a), string, sep)
762
+
763
+
764
+ def check_str_replace(
765
+ string: str, old: str, new: str, maxsplit: int
766
+ ) -> ResultComparison:
767
+ """post: _"""
768
+ return compare_results(lambda s, *a: s.replace(*a), string, old, new, maxsplit)
769
+
770
+
771
+ def check_str_rfind(
772
+ string: str, substr: str, start: Optional[int], end: Optional[int]
773
+ ) -> ResultComparison:
774
+ """post: _"""
775
+ return compare_results(lambda s, *a: s.rfind(*a), string, substr, start, end)
776
+
777
+
778
+ def check_str_rfind_empty(big: str, start: int, end: int):
779
+ """post: _"""
780
+ # Lots of tricky edge cases when searching for an empty string.
781
+ # Target these cases more narrowly.
782
+ if big != "":
783
+ return True
784
+ return compare_results(lambda s, *a: s.rfind("", *a), big, start, end)
785
+
786
+
787
+ def check_str_rindex(
788
+ string: str, sub: str, start: Optional[int], end: Optional[int]
789
+ ) -> ResultComparison:
790
+ """post: _"""
791
+ return compare_results(lambda s, *a: s.rindex(*a), string, sub, start, end)
792
+
793
+
794
+ def check_str_rjust(string: str, width: int, fill: str) -> ResultComparison:
795
+ """post: _"""
796
+ return compare_results(lambda s, *a: s.rjust(*a), string, width, fill)
797
+
798
+
799
+ def check_str_rpartition(string: str, sep: str) -> ResultComparison:
800
+ """post: _"""
801
+ return compare_results(lambda s, *a: s.rpartition(*a), string, sep)
802
+
803
+
804
+ def check_str_rsplit(string: str, sep: str, maxsplit: int) -> ResultComparison:
805
+ """post: _"""
806
+ return compare_results(lambda s, *a: s.rsplit(*a), string, sep, maxsplit)
807
+
808
+
809
+ def check_str_rstrip(string: str, chars: str) -> ResultComparison:
810
+ """post: _"""
811
+ return compare_results(lambda s, *a: s.rstrip(*a), string, chars)
812
+
813
+
814
+ def check_str_split(string: str, sep: str, maxsplit: int) -> ResultComparison:
815
+ """post: _"""
816
+ return compare_results(lambda s, *a: s.split(*a), string, sep, maxsplit)
817
+
818
+
819
+ def check_str_splitlines(string: str, keepends: bool) -> ResultComparison:
820
+ """post: _"""
821
+ if "\r" in string:
822
+ pass
823
+ return compare_results(lambda s, *a: s.splitlines(*a), string, keepends)
824
+
825
+
826
+ def check_str_startswith(
827
+ string: str,
828
+ prefix: Union[str, Tuple[str, ...]],
829
+ start: Optional[int],
830
+ end: Optional[int],
831
+ ) -> ResultComparison:
832
+ """post: _"""
833
+ # crosshair: max_uninteresting_iterations=100
834
+
835
+ for i in (len(string), len(prefix), start, end):
836
+ if i is not None and abs(i) >= 1:
837
+ pass
838
+ return compare_results(
839
+ lambda s, *a, **kw: s.startswith(*a, **kw), string, prefix, start, end
840
+ )
841
+
842
+
843
+ def check_str_strip(string: str, chars: str) -> ResultComparison:
844
+ """post: _"""
845
+ return compare_results(lambda s, *a: s.strip(*a), string, chars)
846
+
847
+
848
+ def check_str_swapcase(string: str):
849
+ """post: _"""
850
+ if string not in ("Ab", "\u01f2"):
851
+ return True
852
+ return compare_results(lambda s: s.swapcase(), string)
853
+
854
+
855
+ def check_str_title(string: str):
856
+ """post: _"""
857
+ if string not in ("A\u01f2", "aA"):
858
+ return True
859
+ return compare_results(lambda s: s.title(), string)
860
+
861
+
862
+ def check_str_translate(
863
+ string: str, tbl: Union[Mapping[int, int], List[str]]
864
+ ) -> ResultComparison:
865
+ """post: _"""
866
+ return compare_results(lambda s, *a: s.translate(*a), string, tbl)
867
+
868
+
869
+ def check_str_upper(string: str) -> ResultComparison:
870
+ """
871
+ pre: len(string) <= 2
872
+ post: _
873
+ """
874
+ return compare_results(lambda s: s.upper(), string)
875
+
876
+
877
+ def check_str_zfill(string: str, width: int) -> ResultComparison:
878
+ """post: _"""
879
+ return compare_results(lambda s, *a: s.zfill(*a), string, width)
880
+
881
+
882
+ if sys.version_info >= (3, 9):
883
+
884
+ def check_str_removeprefix(s: str, prefix: str):
885
+ """post: _"""
886
+ return compare_results(lambda s, *a: s.removeprefix(*a), s, prefix)
887
+
888
+ def check_str_removesuffix(s: str, suffix: str):
889
+ """post: _"""
890
+ return compare_results(lambda s, *a: s.removesuffix(*a), s, suffix)
891
+
892
+
893
+ # Check bytes, bytearray, memoryview methods
894
+
895
+
896
+ def check_buffer_getitem_return_type(container: Union[bytes, bytearray, memoryview]):
897
+ """post: _"""
898
+ return compare_results(lambda c: type(c[:1]), container)
899
+
900
+
901
+ def check_buffer_hex_noargs(container: Union[bytes, bytearray, memoryview]):
902
+ """post: _"""
903
+ return compare_results(lambda c: c.hex(), container)
904
+
905
+
906
+ def check_buffer_hex(
907
+ container: Union[bytes, bytearray, memoryview], sep: str, bytes_per_sep: int
908
+ ):
909
+ """post: _"""
910
+ return compare_results(lambda c, s, b: c.hex(s, b), container, sep, bytes_per_sep)
911
+
912
+
913
+ def check_buffer_fromhex(hexstr: str):
914
+ """post: _"""
915
+ return compare_results(lambda s: bytes.fromhex(s), hexstr)
916
+
917
+
918
+ def check_buffer_setitem_splice(container: bytearray):
919
+ """post: _"""
920
+
921
+ def setter(c):
922
+ c[0:0] = [42]
923
+ return c
924
+
925
+ return compare_results(setter, container)
926
+
927
+
928
+ def check_buffer_setitem_add_self(container: memoryview):
929
+ """post: _"""
930
+
931
+ def setter(c):
932
+ c[0:0] = c
933
+ return c
934
+
935
+ return compare_results(setter, container)
936
+
937
+
938
+ def check_buffer_setitem_replace(
939
+ container: Union[memoryview, bytearray],
940
+ replacement: Union[memoryview, bytearray, bytes],
941
+ realize_at: int,
942
+ ):
943
+ """post: _"""
944
+
945
+ def setter(c, r):
946
+ if r == 0:
947
+ c = realize(c)
948
+ elif r == 1:
949
+ r = realize(r)
950
+ c[0:1] = r
951
+ return c
952
+
953
+ return compare_results(setter, container, replacement)
954
+
955
+
956
+ def check_buffer_crosstype_addition(
957
+ buffer1: Union[bytes, bytearray, memoryview],
958
+ buffer2: Union[bytes, bytearray, memoryview],
959
+ realize_at: int,
960
+ ):
961
+ """post: _"""
962
+
963
+ def adder(b1, b2, r):
964
+ if r == 0:
965
+ b1 = realize(b1)
966
+ elif r == 1:
967
+ b2 = realize(b2)
968
+ return b1 + b2
969
+
970
+ return compare_results(adder, buffer1, buffer2, realize_at)
971
+
972
+
973
+ def check_buffer_add_return_type(container: Union[bytearray, memoryview]):
974
+ """post: _"""
975
+ return compare_results(lambda c: type(c + b"abc"), container)
976
+
977
+
978
+ def check_bytes___init__(source: Union[int, List[int], bytes, bytearray, memoryview]):
979
+ """
980
+ post: _
981
+ raises: KeyError
982
+ """
983
+ return compare_results(lambda c, s: c(s), bytes, source)
984
+
985
+
986
+ def check_bytearray___init__(
987
+ source: Union[int, List[int], bytes, bytearray, memoryview],
988
+ ):
989
+ """
990
+ post: _
991
+ raises: KeyError
992
+ """
993
+ return compare_results(lambda c, s: c(s), bytearray, source)
994
+
995
+
996
+ def check_memoryview___init__(
997
+ source: Union[int, List[int], bytes, bytearray, memoryview],
998
+ ):
999
+ """
1000
+ post: _
1001
+ raises: KeyError
1002
+ """
1003
+ return compare_results(lambda c, s: c(s), memoryview, source)
1004
+
1005
+
1006
+ def check_buffer_iter(container: Union[bytes, bytearray, memoryview]):
1007
+ """post: _"""
1008
+ return compare_results(list, container)
1009
+
1010
+
1011
+ def check_buffer_equal(
1012
+ buffer1: Union[bytes, bytearray, memoryview],
1013
+ buffer2: Union[bytes, bytearray, memoryview],
1014
+ realize_at: int,
1015
+ ):
1016
+ """post: _"""
1017
+
1018
+ def compare(b1, b2, r):
1019
+ if r == 0:
1020
+ b1 = realize(b1)
1021
+ elif r == 1:
1022
+ b2 = realize(b2)
1023
+ return b1 == b2
1024
+
1025
+ return compare_results(compare, buffer1, buffer2, realize_at)
1026
+
1027
+
1028
+ def check_buffer_compare(
1029
+ buffer1: Union[bytes, bytearray, memoryview],
1030
+ buffer2: Union[bytes, bytearray, memoryview],
1031
+ realize_at: int,
1032
+ ):
1033
+ """post: _"""
1034
+
1035
+ def compare(b1, b2, r):
1036
+ if r == 0:
1037
+ b1 = realize(b1)
1038
+ elif r == 1:
1039
+ b2 = realize(b2)
1040
+ # A lot of esotric Python behaviors in (<); see comments in BytesLike._cmp_op.
1041
+ return b1 < b2
1042
+
1043
+ return compare_results(compare, buffer1, buffer2, realize_at)
1044
+
1045
+
1046
+ def check_buffer_percent_format(buffer: Union[bytes, bytearray, memoryview]):
1047
+ """post: _"""
1048
+ return compare_results(lambda b: b"%04b" % b, buffer)
1049
+
1050
+
1051
+ def check_memoryview_conversions(view: memoryview):
1052
+ """post: _"""
1053
+ if len(view) == 1:
1054
+ pass
1055
+ return compare_results(
1056
+ lambda mv: (mv.tobytes(), mv.tolist(), mv.hex(), mv.cast("b")), view
1057
+ )
1058
+
1059
+
1060
+ # Check operators
1061
+
1062
+
1063
+ def check_add_seqs(seq: Union[str, bytes, bytearray, List[int], Tuple[int, ...]]):
1064
+ """
1065
+ pre: len(seq) == 1
1066
+ post: _
1067
+ """
1068
+
1069
+ def f(s):
1070
+ combined = s + s
1071
+ return (combined, type(combined))
1072
+
1073
+ return compare_results(f, seq)
1074
+
1075
+
1076
+ def check_and(left: int):
1077
+ """post: _"""
1078
+ return compare_results(lambda lt: (lt & 3, 4 & lt), left)
1079
+
1080
+
1081
+ def check_xor(left: Union[int, bool], right: Union[int, bool]):
1082
+ """post: _"""
1083
+ return compare_results(operator.xor, left, right)
1084
+
1085
+
1086
+ def check_truediv(left: Union[int, float], right: Union[int, float]):
1087
+ """post: _"""
1088
+ return compare_returns(operator.truediv, left, right)
1089
+
1090
+
1091
+ def check_lt_strings(left: str, right: str):
1092
+ """post: _"""
1093
+ return compare_results(operator.lt, left, right)
1094
+
1095
+
1096
+ def check_ge_numeric(
1097
+ left: Union[int, bool, float, complex], right: Union[int, bool, float, complex]
1098
+ ):
1099
+ """post: _"""
1100
+ return compare_returns(operator.ge, left, right)
1101
+
1102
+
1103
+ def check_mod(
1104
+ left: Union[int, bool, float, complex], right: Union[int, bool, float, complex]
1105
+ ):
1106
+ """post: _"""
1107
+ if left == 0 or right == 0:
1108
+ pass
1109
+ return compare_returns(operator.mod, left, right)
1110
+
1111
+
1112
+ def check_floordiv(x: Union[int, float], y: Union[int, float]) -> ResultComparison:
1113
+ """post: _"""
1114
+ if y == 0 or x == 0:
1115
+ pass
1116
+ return compare_returns(operator.floordiv, x, y)
1117
+
1118
+
1119
+ def check_getitem(
1120
+ container: Union[Dict[int, int], List[int], Tuple[int, ...]], key: int
1121
+ ):
1122
+ """post: _"""
1123
+ return compare_results(lambda d, k: d[k], container, key)
1124
+
1125
+
1126
+ def check_getitem_slice(
1127
+ container: Union[List[int], Tuple[int, ...], str, bytes, bytearray], key: slice
1128
+ ):
1129
+ """post: _"""
1130
+
1131
+ def f(d, s):
1132
+ ret = d[s]
1133
+ return (ret, type(ret))
1134
+
1135
+ return compare_results(f, container, key)
1136
+
1137
+
1138
+ def check_delitem_int(container: Union[Dict[int, int], List[int]], key: int):
1139
+ """post: _"""
1140
+
1141
+ def checker(d, k):
1142
+ del d[k]
1143
+ return d
1144
+
1145
+ return compare_results(checker, container, key)
1146
+
1147
+
1148
+ def check_delitem_slice(container: List[int], key: slice):
1149
+ """post: _"""
1150
+
1151
+ def checker(d, k):
1152
+ del d[k]
1153
+ return d
1154
+
1155
+ return compare_results(checker, container, key)
1156
+
1157
+
1158
+ def check_inplace_mutation(container: Union[bytearray, List[int], Dict[int, int]]):
1159
+ """post: _"""
1160
+
1161
+ def setter(c):
1162
+ if c:
1163
+ c[0] &= 42
1164
+ return c
1165
+
1166
+ return compare_results(setter, container)
1167
+
1168
+
1169
+ def check_eq_atomic(
1170
+ left: Union[bool, int, float, str], right: Union[bool, int, float, str]
1171
+ ):
1172
+ """post: _"""
1173
+ return compare_returns(lambda a, b: a == b, left, right)
1174
+
1175
+
1176
+ def check_trunc(num: Union[bool, int, float]):
1177
+ """post: _"""
1178
+ if num >= 0:
1179
+ pass
1180
+ return compare_returns(lambda n: n.__trunc__(), num)
1181
+
1182
+
1183
+ # This is the only real test definition.
1184
+ # It runs crosshair on each of the "check" functions defined above.
1185
+ @pytest.mark.parametrize("fn_name", [fn for fn in dir() if fn.startswith("check_")])
1186
+ def test_builtin(fn_name: str) -> None:
1187
+ this_module = sys.modules[__name__]
1188
+ fn = getattr(this_module, fn_name)
1189
+ messages = run_checkables(analyze_function(fn))
1190
+ errors = [m for m in messages if m.state > MessageType.PRE_UNSAT]
1191
+ assert errors == []