crosshair-tool 0.0.56__cp39-cp39-macosx_11_0_arm64.whl → 0.0.100__cp39-cp39-macosx_11_0_arm64.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 (123) hide show
  1. _crosshair_tracers.cpython-39-darwin.so +0 -0
  2. crosshair/__init__.py +1 -1
  3. crosshair/_mark_stacks.h +51 -24
  4. crosshair/_tracers.h +9 -5
  5. crosshair/_tracers_test.py +19 -9
  6. crosshair/auditwall.py +9 -8
  7. crosshair/auditwall_test.py +31 -19
  8. crosshair/codeconfig.py +3 -2
  9. crosshair/condition_parser.py +17 -133
  10. crosshair/condition_parser_test.py +54 -96
  11. crosshair/conftest.py +1 -1
  12. crosshair/copyext.py +91 -22
  13. crosshair/copyext_test.py +33 -0
  14. crosshair/core.py +259 -203
  15. crosshair/core_and_libs.py +20 -0
  16. crosshair/core_regestered_types_test.py +82 -0
  17. crosshair/core_test.py +693 -664
  18. crosshair/diff_behavior.py +76 -21
  19. crosshair/diff_behavior_test.py +132 -23
  20. crosshair/dynamic_typing.py +128 -18
  21. crosshair/dynamic_typing_test.py +91 -4
  22. crosshair/enforce.py +1 -6
  23. crosshair/enforce_test.py +15 -23
  24. crosshair/examples/check_examples_test.py +2 -1
  25. crosshair/fnutil.py +2 -3
  26. crosshair/fnutil_test.py +0 -7
  27. crosshair/fuzz_core_test.py +70 -83
  28. crosshair/libimpl/arraylib.py +10 -7
  29. crosshair/libimpl/binascii_ch_test.py +30 -0
  30. crosshair/libimpl/binascii_test.py +67 -0
  31. crosshair/libimpl/binasciilib.py +150 -0
  32. crosshair/libimpl/bisectlib_test.py +5 -5
  33. crosshair/libimpl/builtinslib.py +1002 -682
  34. crosshair/libimpl/builtinslib_ch_test.py +108 -30
  35. crosshair/libimpl/builtinslib_test.py +431 -143
  36. crosshair/libimpl/codecslib.py +22 -2
  37. crosshair/libimpl/codecslib_test.py +41 -9
  38. crosshair/libimpl/collectionslib.py +44 -8
  39. crosshair/libimpl/collectionslib_test.py +108 -20
  40. crosshair/libimpl/copylib.py +1 -1
  41. crosshair/libimpl/copylib_test.py +18 -0
  42. crosshair/libimpl/datetimelib.py +84 -67
  43. crosshair/libimpl/datetimelib_ch_test.py +12 -7
  44. crosshair/libimpl/datetimelib_test.py +5 -6
  45. crosshair/libimpl/decimallib.py +5257 -0
  46. crosshair/libimpl/decimallib_ch_test.py +78 -0
  47. crosshair/libimpl/decimallib_test.py +76 -0
  48. crosshair/libimpl/encodings/_encutil.py +21 -11
  49. crosshair/libimpl/fractionlib.py +16 -0
  50. crosshair/libimpl/fractionlib_test.py +80 -0
  51. crosshair/libimpl/functoolslib.py +19 -7
  52. crosshair/libimpl/functoolslib_test.py +22 -6
  53. crosshair/libimpl/hashliblib.py +30 -0
  54. crosshair/libimpl/hashliblib_test.py +18 -0
  55. crosshair/libimpl/heapqlib.py +32 -5
  56. crosshair/libimpl/heapqlib_test.py +15 -12
  57. crosshair/libimpl/iolib.py +7 -4
  58. crosshair/libimpl/ipaddresslib.py +8 -0
  59. crosshair/libimpl/itertoolslib_test.py +1 -1
  60. crosshair/libimpl/mathlib.py +165 -2
  61. crosshair/libimpl/mathlib_ch_test.py +44 -0
  62. crosshair/libimpl/mathlib_test.py +59 -16
  63. crosshair/libimpl/oslib.py +7 -0
  64. crosshair/libimpl/pathliblib_test.py +10 -0
  65. crosshair/libimpl/randomlib.py +1 -0
  66. crosshair/libimpl/randomlib_test.py +6 -4
  67. crosshair/libimpl/relib.py +180 -59
  68. crosshair/libimpl/relib_ch_test.py +26 -2
  69. crosshair/libimpl/relib_test.py +77 -14
  70. crosshair/libimpl/timelib.py +35 -13
  71. crosshair/libimpl/timelib_test.py +13 -3
  72. crosshair/libimpl/typeslib.py +15 -0
  73. crosshair/libimpl/typeslib_test.py +36 -0
  74. crosshair/libimpl/unicodedatalib_test.py +3 -3
  75. crosshair/libimpl/weakreflib.py +13 -0
  76. crosshair/libimpl/weakreflib_test.py +69 -0
  77. crosshair/libimpl/zliblib.py +15 -0
  78. crosshair/libimpl/zliblib_test.py +13 -0
  79. crosshair/lsp_server.py +21 -10
  80. crosshair/main.py +48 -28
  81. crosshair/main_test.py +59 -14
  82. crosshair/objectproxy.py +39 -14
  83. crosshair/objectproxy_test.py +27 -13
  84. crosshair/opcode_intercept.py +212 -24
  85. crosshair/opcode_intercept_test.py +172 -18
  86. crosshair/options.py +0 -1
  87. crosshair/patch_equivalence_test.py +5 -21
  88. crosshair/path_cover.py +7 -5
  89. crosshair/path_search.py +6 -4
  90. crosshair/path_search_test.py +1 -2
  91. crosshair/pathing_oracle.py +53 -10
  92. crosshair/pathing_oracle_test.py +21 -0
  93. crosshair/pure_importer_test.py +5 -21
  94. crosshair/register_contract.py +16 -6
  95. crosshair/register_contract_test.py +2 -14
  96. crosshair/simplestructs.py +154 -85
  97. crosshair/simplestructs_test.py +16 -2
  98. crosshair/smtlib.py +24 -0
  99. crosshair/smtlib_test.py +14 -0
  100. crosshair/statespace.py +319 -196
  101. crosshair/statespace_test.py +45 -0
  102. crosshair/stubs_parser.py +0 -2
  103. crosshair/test_util.py +87 -25
  104. crosshair/test_util_test.py +26 -0
  105. crosshair/tools/check_init_and_setup_coincide.py +0 -3
  106. crosshair/tools/generate_demo_table.py +2 -2
  107. crosshair/tracers.py +141 -49
  108. crosshair/type_repo.py +11 -4
  109. crosshair/unicode_categories.py +1 -0
  110. crosshair/util.py +158 -76
  111. crosshair/util_test.py +13 -20
  112. crosshair/watcher.py +4 -4
  113. crosshair/z3util.py +1 -1
  114. {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/METADATA +45 -36
  115. crosshair_tool-0.0.100.dist-info/RECORD +176 -0
  116. {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/WHEEL +2 -1
  117. crosshair/examples/hypothesis/__init__.py +0 -2
  118. crosshair/examples/hypothesis/bugs_detected/simple_strategies.py +0 -74
  119. crosshair_tool-0.0.56.dist-info/RECORD +0 -152
  120. /crosshair/{examples/hypothesis/bugs_detected/__init__.py → py.typed} +0 -0
  121. {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/entry_points.txt +0 -0
  122. {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info/licenses}/LICENSE +0 -0
  123. {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  import operator
2
2
  import sys
3
+ from math import isnan
3
4
  from numbers import Integral
4
5
  from typing import (
5
6
  Any,
@@ -19,7 +20,7 @@ import pytest # type: ignore
19
20
 
20
21
  from crosshair.core import realize
21
22
  from crosshair.core_and_libs import MessageType, analyze_function, run_checkables
22
- from crosshair.test_util import ResultComparison, compare_results
23
+ from crosshair.test_util import ResultComparison, compare_results, compare_returns
23
24
 
24
25
  _TRICKY_UNICODE = (
25
26
  "A\u01f2", # upper followed by title cased character
@@ -29,9 +30,9 @@ _TRICKY_UNICODE = (
29
30
  )
30
31
 
31
32
 
32
- def check_abs(x: float) -> ResultComparison:
33
+ def check_abs(x: Union[int, bool, float]) -> ResultComparison:
33
34
  """post: _"""
34
- return compare_results(abs, x)
35
+ return compare_returns(abs, x)
35
36
 
36
37
 
37
38
  def check_ascii(x: object) -> ResultComparison:
@@ -56,12 +57,21 @@ def check_chr(x: int) -> ResultComparison:
56
57
 
57
58
  # NOTE: dir() is not expected to be compatible.
58
59
 
60
+ _NAN_SENTINAL: Tuple = tuple()
61
+ # (anything that is copyable and compares equal with itself)
59
62
 
60
- def check_divmod(x: Union[int, float], y: Union[int, float]) -> ResultComparison:
63
+
64
+ def check_divmod(
65
+ numerator: Union[int, float], denominator: Union[int, float]
66
+ ) -> ResultComparison:
61
67
  """post: _"""
62
- if y == 0 or x == 0:
68
+ if numerator == 0 or denominator == 0:
63
69
  pass
64
- return compare_results(divmod, x, y)
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
+ )
65
75
 
66
76
 
67
77
  def check_eval(expr: str):
@@ -84,7 +94,12 @@ def check_eval(expr: str):
84
94
  def check_float(o: Union[str, int, float]) -> ResultComparison:
85
95
  """post: _"""
86
96
  # TODO this isn't hitting most of the branches we care about right now.
87
- return compare_results(float, o)
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)
88
103
 
89
104
 
90
105
  def check_format(x: object, f: str) -> ResultComparison:
@@ -101,7 +116,7 @@ def check_format_dunder(obj: Union[int, float], fmt: str) -> ResultComparison:
101
116
  pass
102
117
  # TODO: do not realize `fmt` here- instead we should intercept the native
103
118
  # __format__ calls to check for a symbolic format string.
104
- return compare_results(lambda o, f: o.__format__(f), obj, realize(fmt))
119
+ return compare_returns(lambda o, f: o.__format__(f), obj, realize(fmt))
105
120
 
106
121
 
107
122
  # CrossHair proxies don't have the same attributes as native:
@@ -113,7 +128,13 @@ def check_format_dunder(obj: Union[int, float], fmt: str) -> ResultComparison:
113
128
  # def check_hasattr(o: str, n: str) -> ResultComparison:
114
129
 
115
130
 
116
- def check_hash(o: Union[int, str]) -> ResultComparison:
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:
117
138
  """post: _"""
118
139
  return compare_results(hash, o)
119
140
 
@@ -132,7 +153,7 @@ def check_hex(o: int) -> ResultComparison:
132
153
 
133
154
  def check_int(o: Union[str, int, float]) -> ResultComparison:
134
155
  """post: _"""
135
- return compare_results(int, o)
156
+ return compare_returns(int, o)
136
157
 
137
158
 
138
159
  def check_int_with_base(o: str, b: int) -> ResultComparison:
@@ -157,7 +178,7 @@ def check_iter(obj: Union[str, List[int], Dict[int, int]]) -> ResultComparison:
157
178
 
158
179
 
159
180
  def check_len(
160
- s: Union[Dict[int, int], Tuple[int, ...], str, List[int], Set[int]]
181
+ s: Union[Dict[int, int], Tuple[int, ...], str, List[int], Set[int]],
161
182
  ) -> ResultComparison:
162
183
  """post: _"""
163
184
  return compare_results(len, s)
@@ -209,11 +230,20 @@ def check_print(o: object) -> ResultComparison:
209
230
  return compare_results(print, o)
210
231
 
211
232
 
212
- def check_pow(
233
+ def check_pow_function(
213
234
  b: Union[int, float], e: Union[int, float], m: Optional[int]
214
235
  ) -> ResultComparison:
215
236
  """post: _"""
216
- return compare_results(pow, b, e, m)
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)
217
247
 
218
248
 
219
249
  # NOTE: not testing quit()
@@ -243,7 +273,7 @@ def check_repr(o: object) -> ResultComparison:
243
273
 
244
274
  def check_round_float(o: float, d: Optional[int]) -> ResultComparison:
245
275
  """post: _"""
246
- return compare_results(round, o, d)
276
+ return compare_returns(round, o, d)
247
277
 
248
278
 
249
279
  def check_round_int(o: int, d: Optional[int]) -> ResultComparison:
@@ -265,7 +295,7 @@ def check_sum(
265
295
  # i: Union[None, int, float]
266
296
  ) -> ResultComparison:
267
297
  """post: _"""
268
- return compare_results(sum, s)
298
+ return compare_returns(sum, s)
269
299
 
270
300
 
271
301
  # NOTE: not testing vars()
@@ -320,6 +350,13 @@ def check_list_setitem_slice(container: List[int], key: slice, replacement: List
320
350
  # Check dict methods
321
351
 
322
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
+
323
360
  def check_dict_get(dictionary: Dict[int, int], key: int) -> ResultComparison:
324
361
  """post: _"""
325
362
  return compare_results(lambda d, k: d.get(k), dictionary, key)
@@ -454,7 +491,13 @@ def check_set_intersection(
454
491
  def check_set_compare(
455
492
  left: Union[Set[int], FrozenSet[int]], right: Union[Set[int], FrozenSet[int]]
456
493
  ) -> ResultComparison:
457
- """post: _"""
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)
458
501
  return compare_results(lambda lt, r: lt <= r, left, right)
459
502
 
460
503
 
@@ -463,6 +506,11 @@ def check_set_bool(setobj: Union[Set[int], FrozenSet[int]]) -> ResultComparison:
463
506
  return compare_results(lambda s: s, bool(setobj))
464
507
 
465
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
+
466
514
  # Check int methods
467
515
 
468
516
 
@@ -558,9 +606,14 @@ def check_str_endswith(
558
606
  string: str, suffix: str, start: Optional[int], end: Optional[int]
559
607
  ) -> ResultComparison:
560
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
+
561
615
  return compare_results(
562
- lambda s, *a: s.endswith(*a),
563
- string,
616
+ lambda s, *a, **kw: s.endswith(*a, **kw), string, suffix, start, end
564
617
  )
565
618
 
566
619
 
@@ -777,6 +830,11 @@ def check_str_startswith(
777
830
  end: Optional[int],
778
831
  ) -> ResultComparison:
779
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
780
838
  return compare_results(
781
839
  lambda s, *a, **kw: s.startswith(*a, **kw), string, prefix, start, end
782
840
  )
@@ -917,17 +975,32 @@ def check_buffer_add_return_type(container: Union[bytearray, memoryview]):
917
975
  return compare_results(lambda c: type(c + b"abc"), container)
918
976
 
919
977
 
920
- def check_buffer_constructions(
921
- constructor_name: str, source: Union[int, List[int], bytes, bytearray, memoryview]
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],
922
988
  ):
923
989
  """
924
990
  post: _
925
991
  raises: KeyError
926
992
  """
927
- constructor = {"bytes": bytes, "bytearray": bytearray, "memoryview": memoryview}[
928
- constructor_name
929
- ]
930
- return compare_results(lambda c, s: c(s), constructor, source)
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)
931
1004
 
932
1005
 
933
1006
  def check_buffer_iter(container: Union[bytes, bytearray, memoryview]):
@@ -1005,9 +1078,14 @@ def check_and(left: int):
1005
1078
  return compare_results(lambda lt: (lt & 3, 4 & lt), left)
1006
1079
 
1007
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
+
1008
1086
  def check_truediv(left: Union[int, float], right: Union[int, float]):
1009
1087
  """post: _"""
1010
- return compare_results(operator.truediv, left, right)
1088
+ return compare_returns(operator.truediv, left, right)
1011
1089
 
1012
1090
 
1013
1091
  def check_lt_strings(left: str, right: str):
@@ -1019,7 +1097,7 @@ def check_ge_numeric(
1019
1097
  left: Union[int, bool, float, complex], right: Union[int, bool, float, complex]
1020
1098
  ):
1021
1099
  """post: _"""
1022
- return compare_results(operator.ge, left, right)
1100
+ return compare_returns(operator.ge, left, right)
1023
1101
 
1024
1102
 
1025
1103
  def check_mod(
@@ -1028,14 +1106,14 @@ def check_mod(
1028
1106
  """post: _"""
1029
1107
  if left == 0 or right == 0:
1030
1108
  pass
1031
- return compare_results(operator.mod, left, right)
1109
+ return compare_returns(operator.mod, left, right)
1032
1110
 
1033
1111
 
1034
1112
  def check_floordiv(x: Union[int, float], y: Union[int, float]) -> ResultComparison:
1035
1113
  """post: _"""
1036
1114
  if y == 0 or x == 0:
1037
1115
  pass
1038
- return compare_results(operator.floordiv, x, y)
1116
+ return compare_returns(operator.floordiv, x, y)
1039
1117
 
1040
1118
 
1041
1119
  def check_getitem(
@@ -1092,14 +1170,14 @@ def check_eq_atomic(
1092
1170
  left: Union[bool, int, float, str], right: Union[bool, int, float, str]
1093
1171
  ):
1094
1172
  """post: _"""
1095
- return compare_results(lambda a, b: a == b, left, right)
1173
+ return compare_returns(lambda a, b: a == b, left, right)
1096
1174
 
1097
1175
 
1098
1176
  def check_trunc(num: Union[bool, int, float]):
1099
1177
  """post: _"""
1100
1178
  if num >= 0:
1101
1179
  pass
1102
- return compare_results(lambda n: n.__trunc__(), num)
1180
+ return compare_returns(lambda n: n.__trunc__(), num)
1103
1181
 
1104
1182
 
1105
1183
  # This is the only real test definition.