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.
- _crosshair_tracers.cpython-39-darwin.so +0 -0
- crosshair/__init__.py +1 -1
- crosshair/_mark_stacks.h +51 -24
- crosshair/_tracers.h +9 -5
- crosshair/_tracers_test.py +19 -9
- crosshair/auditwall.py +9 -8
- crosshair/auditwall_test.py +31 -19
- crosshair/codeconfig.py +3 -2
- crosshair/condition_parser.py +17 -133
- crosshair/condition_parser_test.py +54 -96
- crosshair/conftest.py +1 -1
- crosshair/copyext.py +91 -22
- crosshair/copyext_test.py +33 -0
- crosshair/core.py +259 -203
- crosshair/core_and_libs.py +20 -0
- crosshair/core_regestered_types_test.py +82 -0
- crosshair/core_test.py +693 -664
- crosshair/diff_behavior.py +76 -21
- crosshair/diff_behavior_test.py +132 -23
- crosshair/dynamic_typing.py +128 -18
- crosshair/dynamic_typing_test.py +91 -4
- crosshair/enforce.py +1 -6
- crosshair/enforce_test.py +15 -23
- crosshair/examples/check_examples_test.py +2 -1
- crosshair/fnutil.py +2 -3
- crosshair/fnutil_test.py +0 -7
- crosshair/fuzz_core_test.py +70 -83
- crosshair/libimpl/arraylib.py +10 -7
- crosshair/libimpl/binascii_ch_test.py +30 -0
- crosshair/libimpl/binascii_test.py +67 -0
- crosshair/libimpl/binasciilib.py +150 -0
- crosshair/libimpl/bisectlib_test.py +5 -5
- crosshair/libimpl/builtinslib.py +1002 -682
- crosshair/libimpl/builtinslib_ch_test.py +108 -30
- crosshair/libimpl/builtinslib_test.py +431 -143
- crosshair/libimpl/codecslib.py +22 -2
- crosshair/libimpl/codecslib_test.py +41 -9
- crosshair/libimpl/collectionslib.py +44 -8
- crosshair/libimpl/collectionslib_test.py +108 -20
- crosshair/libimpl/copylib.py +1 -1
- crosshair/libimpl/copylib_test.py +18 -0
- crosshair/libimpl/datetimelib.py +84 -67
- crosshair/libimpl/datetimelib_ch_test.py +12 -7
- crosshair/libimpl/datetimelib_test.py +5 -6
- crosshair/libimpl/decimallib.py +5257 -0
- crosshair/libimpl/decimallib_ch_test.py +78 -0
- crosshair/libimpl/decimallib_test.py +76 -0
- crosshair/libimpl/encodings/_encutil.py +21 -11
- crosshair/libimpl/fractionlib.py +16 -0
- crosshair/libimpl/fractionlib_test.py +80 -0
- crosshair/libimpl/functoolslib.py +19 -7
- crosshair/libimpl/functoolslib_test.py +22 -6
- crosshair/libimpl/hashliblib.py +30 -0
- crosshair/libimpl/hashliblib_test.py +18 -0
- crosshair/libimpl/heapqlib.py +32 -5
- crosshair/libimpl/heapqlib_test.py +15 -12
- crosshair/libimpl/iolib.py +7 -4
- crosshair/libimpl/ipaddresslib.py +8 -0
- crosshair/libimpl/itertoolslib_test.py +1 -1
- crosshair/libimpl/mathlib.py +165 -2
- crosshair/libimpl/mathlib_ch_test.py +44 -0
- crosshair/libimpl/mathlib_test.py +59 -16
- crosshair/libimpl/oslib.py +7 -0
- crosshair/libimpl/pathliblib_test.py +10 -0
- crosshair/libimpl/randomlib.py +1 -0
- crosshair/libimpl/randomlib_test.py +6 -4
- crosshair/libimpl/relib.py +180 -59
- crosshair/libimpl/relib_ch_test.py +26 -2
- crosshair/libimpl/relib_test.py +77 -14
- crosshair/libimpl/timelib.py +35 -13
- crosshair/libimpl/timelib_test.py +13 -3
- crosshair/libimpl/typeslib.py +15 -0
- crosshair/libimpl/typeslib_test.py +36 -0
- crosshair/libimpl/unicodedatalib_test.py +3 -3
- crosshair/libimpl/weakreflib.py +13 -0
- crosshair/libimpl/weakreflib_test.py +69 -0
- crosshair/libimpl/zliblib.py +15 -0
- crosshair/libimpl/zliblib_test.py +13 -0
- crosshair/lsp_server.py +21 -10
- crosshair/main.py +48 -28
- crosshair/main_test.py +59 -14
- crosshair/objectproxy.py +39 -14
- crosshair/objectproxy_test.py +27 -13
- crosshair/opcode_intercept.py +212 -24
- crosshair/opcode_intercept_test.py +172 -18
- crosshair/options.py +0 -1
- crosshair/patch_equivalence_test.py +5 -21
- crosshair/path_cover.py +7 -5
- crosshair/path_search.py +6 -4
- crosshair/path_search_test.py +1 -2
- crosshair/pathing_oracle.py +53 -10
- crosshair/pathing_oracle_test.py +21 -0
- crosshair/pure_importer_test.py +5 -21
- crosshair/register_contract.py +16 -6
- crosshair/register_contract_test.py +2 -14
- crosshair/simplestructs.py +154 -85
- crosshair/simplestructs_test.py +16 -2
- crosshair/smtlib.py +24 -0
- crosshair/smtlib_test.py +14 -0
- crosshair/statespace.py +319 -196
- crosshair/statespace_test.py +45 -0
- crosshair/stubs_parser.py +0 -2
- crosshair/test_util.py +87 -25
- crosshair/test_util_test.py +26 -0
- crosshair/tools/check_init_and_setup_coincide.py +0 -3
- crosshair/tools/generate_demo_table.py +2 -2
- crosshair/tracers.py +141 -49
- crosshair/type_repo.py +11 -4
- crosshair/unicode_categories.py +1 -0
- crosshair/util.py +158 -76
- crosshair/util_test.py +13 -20
- crosshair/watcher.py +4 -4
- crosshair/z3util.py +1 -1
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/METADATA +45 -36
- crosshair_tool-0.0.100.dist-info/RECORD +176 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/WHEEL +2 -1
- crosshair/examples/hypothesis/__init__.py +0 -2
- crosshair/examples/hypothesis/bugs_detected/simple_strategies.py +0 -74
- crosshair_tool-0.0.56.dist-info/RECORD +0 -152
- /crosshair/{examples/hypothesis/bugs_detected/__init__.py → py.typed} +0 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info}/entry_points.txt +0 -0
- {crosshair_tool-0.0.56.dist-info → crosshair_tool-0.0.100.dist-info/licenses}/LICENSE +0 -0
- {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
|
|
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
|
-
|
|
63
|
+
|
|
64
|
+
def check_divmod(
|
|
65
|
+
numerator: Union[int, float], denominator: Union[int, float]
|
|
66
|
+
) -> ResultComparison:
|
|
61
67
|
"""post: _"""
|
|
62
|
-
if
|
|
68
|
+
if numerator == 0 or denominator == 0:
|
|
63
69
|
pass
|
|
64
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
"""
|
|
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
|
|
921
|
-
|
|
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
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1180
|
+
return compare_returns(lambda n: n.__trunc__(), num)
|
|
1103
1181
|
|
|
1104
1182
|
|
|
1105
1183
|
# This is the only real test definition.
|